perf(lists): lazy-mount cards on the Skaters, Lab, Crews and Events grids
Extends LazyMount beyond the marketplace so these long card grids no longer mount every card (and its hooks/DOM) up front. Cards keep equal height via h-full wrappers. Gate: 101 tests, 0 errors/warnings, boot smoke green.
This commit is contained in:
parent
662a14bcd2
commit
2e29f12a84
4 changed files with 34 additions and 19 deletions
|
|
@ -2,6 +2,7 @@ import { useState, useMemo } from 'react';
|
|||
import { useSeoMeta } from '@unhead/react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Layout } from '@/components/Layout';
|
||||
import { LazyMount } from '@/components/LazyMount';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Skeleton } from '@/components/ui/skeleton';
|
||||
|
|
@ -334,12 +335,13 @@ export default function CrewsPage() {
|
|||
) : (
|
||||
<div className="grid grid-cols-1 gap-3 lg:grid-cols-2">
|
||||
{filtered.map((crew) => (
|
||||
<CrewCard
|
||||
key={`${crew.pubkey}:${crew.identifier}`}
|
||||
crew={crew}
|
||||
activity={activityMap?.get(crewCoordinate(crew))}
|
||||
distanceKm={nearMe && userLoc ? crewDistanceKm(crew, userLoc) : null}
|
||||
/>
|
||||
<LazyMount key={`${crew.pubkey}:${crew.identifier}`} className="h-full">
|
||||
<CrewCard
|
||||
crew={crew}
|
||||
activity={activityMap?.get(crewCoordinate(crew))}
|
||||
distanceKm={nearMe && userLoc ? crewDistanceKm(crew, userLoc) : null}
|
||||
/>
|
||||
</LazyMount>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useState, useMemo, useRef, useEffect, useCallback } from 'react';
|
|||
import { useSeoMeta } from '@unhead/react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { Layout } from '@/components/Layout';
|
||||
import { LazyMount } from '@/components/LazyMount';
|
||||
import { EventCard, EventCardSkeleton } from '@/components/EventCard';
|
||||
import { TourCard, TourCardSkeleton } from '@/components/TourCard';
|
||||
import { HostingDashboard } from '@/components/HostingDashboard';
|
||||
|
|
@ -1221,11 +1222,12 @@ export default function EventsPage() {
|
|||
filteredEvents.upcoming.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 stagger-children">
|
||||
{filteredEvents.upcoming.map((event) => (
|
||||
<EventCard
|
||||
key={event.id}
|
||||
event={event}
|
||||
goingCount={batchRsvps.get(eventCoord(event))?.goingCount ?? 0}
|
||||
/>
|
||||
<LazyMount key={event.id} className="h-full">
|
||||
<EventCard
|
||||
event={event}
|
||||
goingCount={batchRsvps.get(eventCoord(event))?.goingCount ?? 0}
|
||||
/>
|
||||
</LazyMount>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
|
|
@ -1244,11 +1246,12 @@ export default function EventsPage() {
|
|||
filteredEvents.past.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 stagger-children">
|
||||
{filteredEvents.past.map((event) => (
|
||||
<EventCard
|
||||
key={event.id}
|
||||
event={event}
|
||||
goingCount={batchRsvps.get(eventCoord(event))?.goingCount ?? 0}
|
||||
/>
|
||||
<LazyMount key={event.id} className="h-full">
|
||||
<EventCard
|
||||
event={event}
|
||||
goingCount={batchRsvps.get(eventCoord(event))?.goingCount ?? 0}
|
||||
/>
|
||||
</LazyMount>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
|
|
@ -1270,7 +1273,9 @@ export default function EventsPage() {
|
|||
) : filteredTours.length > 0 ? (
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 stagger-children">
|
||||
{filteredTours.map((tour) => (
|
||||
<TourCard key={tour.id} tour={tour} />
|
||||
<LazyMount key={tour.id} className="h-full">
|
||||
<TourCard tour={tour} />
|
||||
</LazyMount>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { useState, useMemo, useRef, useEffect, useCallback } from 'react';
|
|||
import { useSeoMeta } from '@unhead/react';
|
||||
import { Link, useSearchParams } from 'react-router-dom';
|
||||
import { Layout } from '@/components/Layout';
|
||||
import { LazyMount } from '@/components/LazyMount';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet';
|
||||
import { type TrustFilterLevel, filterByTrustLevel } from '@/components/TrustFilter';
|
||||
|
|
@ -1355,7 +1356,9 @@ export default function LabPage() {
|
|||
) : filteredProfiles.length > 0 ? (
|
||||
<div className="grid sm:grid-cols-2 gap-3">
|
||||
{filteredProfiles.map((profile) => (
|
||||
<ProfileCard key={profile.id} profile={profile} />
|
||||
<LazyMount key={profile.id} className="h-full">
|
||||
<ProfileCard profile={profile} />
|
||||
</LazyMount>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { useSeoMeta } from '@unhead/react';
|
|||
import { Link } from 'react-router-dom';
|
||||
import { nip19 } from 'nostr-tools';
|
||||
import { Layout } from '@/components/Layout';
|
||||
import { LazyMount } from '@/components/LazyMount';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
|
|
@ -346,7 +347,11 @@ export default function SkatersPage() {
|
|||
</Card>
|
||||
) : (
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
{shown.map((s) => <SkaterCard key={s.pubkey} skater={s} verified={verifiedSet?.has(s.pubkey)} />)}
|
||||
{shown.map((s) => (
|
||||
<LazyMount key={s.pubkey} className="h-full">
|
||||
<SkaterCard skater={s} verified={verifiedSet?.has(s.pubkey)} />
|
||||
</LazyMount>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
})()}
|
||||
|
|
|
|||
Loading…
Reference in a new issue