Fix dashboard and map tab lag with memoization and code splitting
Memoize createMap() in DottedMap (was regenerating 8000 SVG dots every render) and convert 11 heavy dashboard components to next/dynamic imports so the page shell renders instantly instead of blocking on one massive render pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -22,20 +22,22 @@ import { getDateRange, formatDate } from '@ciphera-net/ui'
|
|||||||
import { toast } from '@ciphera-net/ui'
|
import { toast } from '@ciphera-net/ui'
|
||||||
import { Button } from '@ciphera-net/ui'
|
import { Button } from '@ciphera-net/ui'
|
||||||
import { Select, DatePicker, DownloadIcon } from '@ciphera-net/ui'
|
import { Select, DatePicker, DownloadIcon } from '@ciphera-net/ui'
|
||||||
|
import dynamic from 'next/dynamic'
|
||||||
import { DashboardSkeleton, useMinimumLoading } from '@/components/skeletons'
|
import { DashboardSkeleton, useMinimumLoading } from '@/components/skeletons'
|
||||||
import ExportModal from '@/components/dashboard/ExportModal'
|
|
||||||
import ContentStats from '@/components/dashboard/ContentStats'
|
|
||||||
import TopReferrers from '@/components/dashboard/TopReferrers'
|
|
||||||
import Locations from '@/components/dashboard/Locations'
|
|
||||||
import TechSpecs from '@/components/dashboard/TechSpecs'
|
|
||||||
import Chart from '@/components/dashboard/Chart'
|
|
||||||
import PerformanceStats from '@/components/dashboard/PerformanceStats'
|
|
||||||
import GoalStats from '@/components/dashboard/GoalStats'
|
|
||||||
import ScrollDepth from '@/components/dashboard/ScrollDepth'
|
|
||||||
import Campaigns from '@/components/dashboard/Campaigns'
|
|
||||||
import FilterBar from '@/components/dashboard/FilterBar'
|
import FilterBar from '@/components/dashboard/FilterBar'
|
||||||
import AddFilterDropdown, { type FilterSuggestion, type FilterSuggestions } from '@/components/dashboard/AddFilterDropdown'
|
import AddFilterDropdown, { type FilterSuggestion, type FilterSuggestions } from '@/components/dashboard/AddFilterDropdown'
|
||||||
import EventProperties from '@/components/dashboard/EventProperties'
|
|
||||||
|
const Chart = dynamic(() => import('@/components/dashboard/Chart'))
|
||||||
|
const ContentStats = dynamic(() => import('@/components/dashboard/ContentStats'))
|
||||||
|
const TopReferrers = dynamic(() => import('@/components/dashboard/TopReferrers'))
|
||||||
|
const Locations = dynamic(() => import('@/components/dashboard/Locations'))
|
||||||
|
const TechSpecs = dynamic(() => import('@/components/dashboard/TechSpecs'))
|
||||||
|
const PerformanceStats = dynamic(() => import('@/components/dashboard/PerformanceStats'))
|
||||||
|
const GoalStats = dynamic(() => import('@/components/dashboard/GoalStats'))
|
||||||
|
const ScrollDepth = dynamic(() => import('@/components/dashboard/ScrollDepth'))
|
||||||
|
const Campaigns = dynamic(() => import('@/components/dashboard/Campaigns'))
|
||||||
|
const EventProperties = dynamic(() => import('@/components/dashboard/EventProperties'))
|
||||||
|
const ExportModal = dynamic(() => import('@/components/dashboard/ExportModal'))
|
||||||
import { type DimensionFilter, serializeFilters, parseFiltersFromURL } from '@/lib/filters'
|
import { type DimensionFilter, serializeFilters, parseFiltersFromURL } from '@/lib/filters'
|
||||||
import {
|
import {
|
||||||
useDashboardOverview,
|
useDashboardOverview,
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ export default function DottedMap({ data, className }: DottedMapProps) {
|
|||||||
const dotRadius = 0.25
|
const dotRadius = 0.25
|
||||||
const [tooltip, setTooltip] = useState<{ x: number; y: number; country: string; pageviews: number } | null>(null)
|
const [tooltip, setTooltip] = useState<{ x: number; y: number; country: string; pageviews: number } | null>(null)
|
||||||
|
|
||||||
const { points, addMarkers } = createMap({ width, height, mapSamples: 8000 })
|
const { points, addMarkers } = useMemo(
|
||||||
|
() => createMap({ width, height, mapSamples: 8000 }),
|
||||||
|
[width, height],
|
||||||
|
)
|
||||||
|
|
||||||
const markerData = useMemo(() => {
|
const markerData = useMemo(() => {
|
||||||
if (!data.length) return []
|
if (!data.length) return []
|
||||||
@@ -48,7 +51,7 @@ export default function DottedMap({ data, className }: DottedMapProps) {
|
|||||||
() => markerData.map((d) => ({ lat: d.lat, lng: d.lng, size: d.size })),
|
() => markerData.map((d) => ({ lat: d.lat, lng: d.lng, size: d.size })),
|
||||||
[markerData],
|
[markerData],
|
||||||
)
|
)
|
||||||
const processedMarkers = addMarkers(markerInputs)
|
const processedMarkers = useMemo(() => addMarkers(markerInputs), [addMarkers, markerInputs])
|
||||||
|
|
||||||
// Compute stagger helpers
|
// Compute stagger helpers
|
||||||
const { xStep, yToRowIndex } = useMemo(() => {
|
const { xStep, yToRowIndex } = useMemo(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user