perf: lazy-load xlsx/recharts, split estimate tabs, memoize nav
- xlsx dynamically imported via cached singleton in excel.ts and skillMatrixParser.ts (removes ~100 kB from 4 routes) - recharts extracted into lazy-loaded SkillDistributionChart and PeakTimesChart components (removes ~60 kB from 3 routes) - EstimateWorkspaceClient: 7 tab components + 2 editors loaded via next/dynamic (reduces /estimates/[id] from 323 kB to 138 kB) - ImportModal lazy-loaded in ResourcesClient (deferred until open) - NavItem memoized with React.memo, top 5 routes get prefetch=true - Raw <img> replaced with next/image in ProjectsClient, CoverArtSection - tRPC QueryClient: refetchOnWindowFocus/Reconnect disabled globally Heaviest routes reduced 39-66% First Load JS: /analytics/skills: 383→132 kB (-66%) /estimates/[id]: 323→138 kB (-57%) /resources/[id]: 458→210 kB (-54%) /estimates: 310→170 kB (-45%) /resources: 363→222 kB (-39%) Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useRef } from "react";
|
||||
import NextImage from "next/image";
|
||||
import { trpc } from "~/lib/trpc/client.js";
|
||||
|
||||
interface CoverArtSectionProps {
|
||||
@@ -149,14 +150,18 @@ export function CoverArtSection({ projectId, coverImageUrl, coverFocusY = 50, pr
|
||||
{/* Cover image or placeholder */}
|
||||
{imageUrl ? (
|
||||
<div className="relative">
|
||||
<img
|
||||
<NextImage
|
||||
src={imageUrl}
|
||||
alt={`Cover art for ${projectName}`}
|
||||
width={1024}
|
||||
height={1024}
|
||||
className="w-full object-cover"
|
||||
style={{
|
||||
height: "clamp(16rem, 22vw, 22rem)",
|
||||
objectPosition: `center ${focusY}%`,
|
||||
}}
|
||||
unoptimized={imageUrl.startsWith("data:")}
|
||||
priority
|
||||
/>
|
||||
{/* Gradient overlay at bottom for readability */}
|
||||
<div className="absolute inset-x-0 bottom-0 h-16 bg-gradient-to-t from-black/40 to-transparent" />
|
||||
|
||||
Reference in New Issue
Block a user