perf: lazy-load globe/map and update changelog

Globe and DottedMap now only render when the Locations section enters
the viewport via IntersectionObserver. Added changelog entries for
rate limit fallback, buffer improvements, and lazy loading.
This commit is contained in:
Usman Baig
2026-03-10 20:57:55 +01:00
parent f10b903a80
commit 502f4952fc
2 changed files with 27 additions and 4 deletions

View File

@@ -1,6 +1,6 @@
'use client'
import { useState, useEffect } from 'react'
import { useState, useEffect, useRef } from 'react'
import dynamic from 'next/dynamic'
import { motion } from 'framer-motion'
import { logger } from '@/lib/utils/logger'
@@ -43,6 +43,20 @@ export default function Locations({ countries, cities, regions, geoDataLevel = '
const [fullData, setFullData] = useState<LocationItem[]>([])
const [isLoadingFull, setIsLoadingFull] = useState(false)
const containerRef = useRef<HTMLDivElement>(null)
const [inView, setInView] = useState(false)
useEffect(() => {
const el = containerRef.current
if (!el) return
const observer = new IntersectionObserver(
([entry]) => { if (entry.isIntersecting) setInView(true) },
{ rootMargin: '200px' }
)
observer.observe(el)
return () => observer.disconnect()
}, [])
useEffect(() => {
if (isModalOpen) {
const fetchData = async () => {
@@ -202,7 +216,7 @@ export default function Locations({ countries, cities, regions, geoDataLevel = '
return (
<>
<div className="bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl p-6 h-full flex flex-col">
<div ref={containerRef} className="bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl p-6 h-full flex flex-col">
<div className="flex items-center justify-between mb-6">
<div className="flex items-center gap-2">
<h3 className="text-lg font-semibold text-neutral-900 dark:text-white">
@@ -252,8 +266,8 @@ export default function Locations({ countries, cities, regions, geoDataLevel = '
) : isVisualTab ? (
hasData ? (
activeTab === 'globe'
? <Globe data={filterUnknown(countries) as { country: string; pageviews: number }[]} />
: <DottedMap data={filterUnknown(countries) as { country: string; pageviews: number }[]} />
? (inView ? <Globe data={filterUnknown(countries) as { country: string; pageviews: number }[]} /> : null)
: (inView ? <DottedMap data={filterUnknown(countries) as { country: string; pageviews: number }[]} /> : null)
) : (
<div className="h-full flex flex-col items-center justify-center text-center px-6 py-8 gap-3">
<div className="rounded-full bg-neutral-100 dark:bg-neutral-800 p-4">