perf: lazy-load dashboard and split vendor chunks to reduce main bundle by 69%

This commit is contained in:
Brad Groux 2026-01-28 17:10:40 -06:00
parent ccff6e78c8
commit 14d60d28eb
4 changed files with 83 additions and 3 deletions

View file

@ -3583,3 +3583,6 @@
{"type":"task.status_changed","taskId":"task_20260128_nK2-lo","project":"veritas-kanban","status":"done","previousStatus":"in-progress","id":"evt_kUKAqOeC-LBN","timestamp":"2026-01-28T23:08:32.549Z"}
{"type":"task.status_changed","taskId":"task_20260128_eH_S3Q","project":"veritas-kanban","status":"in-progress","previousStatus":"todo","id":"evt_5xw3LknlZ-Nl","timestamp":"2026-01-28T23:09:01.718Z"}
{"type":"task.status_changed","taskId":"task_20260128_2H7USQ","project":"veritas-kanban","status":"done","previousStatus":"in-progress","id":"evt_fW1aiEhB87_H","timestamp":"2026-01-28T23:09:10.815Z"}
{"type":"task.status_changed","taskId":"task_20260128_8DUobI","project":"veritas-kanban","status":"in-progress","previousStatus":"todo","id":"evt_Z18-z1bQmSi2","timestamp":"2026-01-28T23:09:43.882Z"}
{"type":"task.status_changed","taskId":"task_20260128_eH_S3Q","project":"veritas-kanban","status":"done","previousStatus":"in-progress","id":"evt_-T0SarE9oB4I","timestamp":"2026-01-28T23:09:45.270Z"}
{"type":"task.status_changed","taskId":"task_20260128_uUydZN","project":"veritas-kanban","status":"in-progress","previousStatus":"todo","id":"evt_uKoZ1SQCUTkn","timestamp":"2026-01-28T23:10:18.570Z"}

View file

@ -1,4 +1,48 @@
[
{
"id": "activity_1769641818570_u5pb6k93a",
"type": "status_changed",
"taskId": "task_20260128_uUydZN",
"taskTitle": "QUALITY: Add request ID middleware for request tracing",
"details": {
"from": "todo",
"status": "in-progress"
},
"timestamp": "2026-01-28T23:10:18.570Z"
},
{
"id": "activity_1769641790370_38yvkyi66",
"type": "comment_added",
"taskId": "task_20260128_eH_S3Q",
"taskTitle": "SECURITY: Sanitize Content-Disposition header in attachment downloads",
"details": {
"author": "Veritas",
"preview": "Replaced raw string interpolation in Content-Dispo..."
},
"timestamp": "2026-01-28T23:09:50.370Z"
},
{
"id": "activity_1769641785270_wd8qg1v3m",
"type": "status_changed",
"taskId": "task_20260128_eH_S3Q",
"taskTitle": "SECURITY: Sanitize Content-Disposition header in attachment downloads",
"details": {
"from": "in-progress",
"status": "done"
},
"timestamp": "2026-01-28T23:09:45.270Z"
},
{
"id": "activity_1769641783882_z8lz7tg6d",
"type": "status_changed",
"taskId": "task_20260128_8DUobI",
"taskTitle": "PERF: Reduce frontend bundle size from 1.2MB main chunk",
"details": {
"from": "todo",
"status": "in-progress"
},
"timestamp": "2026-01-28T23:09:43.882Z"
},
{
"id": "activity_1769641756408_28h6sbmhl",
"type": "comment_added",

View file

@ -6,7 +6,7 @@ import { TaskDetailPanel } from '@/components/task/TaskDetailPanel';
import type { TaskStatus, Task } from '@veritas-kanban/shared';
import { useFeatureSettings } from '@/hooks/useFeatureSettings';
import { DndContext, DragOverlay, closestCorners } from '@dnd-kit/core';
import { useState, useEffect, useCallback, useMemo } from 'react';
import { useState, useEffect, useCallback, useMemo, lazy, Suspense } from 'react';
import { TaskCard } from '@/components/task/TaskCard';
import { useKeyboard } from '@/hooks/useKeyboard';
import {
@ -18,9 +18,15 @@ import {
} from './FilterBar';
import { BulkActionsBar } from './BulkActionsBar';
import { ArchiveSuggestionBanner } from './ArchiveSuggestionBanner';
import { DashboardSection } from '@/components/dashboard/DashboardSection';
import FeatureErrorBoundary from '@/components/shared/FeatureErrorBoundary';
// Lazy-load DashboardSection to split recharts + d3 (~800KB) out of main bundle
const DashboardSection = lazy(() =>
import('@/components/dashboard/DashboardSection').then(mod => ({
default: mod.DashboardSection,
}))
);
const COLUMNS: { id: TaskStatus; title: string }[] = [
{ id: 'todo', title: 'To Do' },
{ id: 'in-progress', title: 'In Progress' },
@ -197,7 +203,15 @@ export function KanbanBoard() {
</div>
)}
{featureSettings.board.showDashboard && <DashboardSection />}
{featureSettings.board.showDashboard && (
<Suspense fallback={
<div className="mt-6 border-t pt-4 flex items-center justify-center py-8 text-muted-foreground">
Loading dashboard…
</div>
}>
<DashboardSection />
</Suspense>
)}
</FeatureErrorBoundary>
<TaskDetailPanel

View file

@ -9,6 +9,25 @@ export default defineConfig({
'@': path.resolve(__dirname, './src'),
},
},
build: {
rollupOptions: {
output: {
manualChunks: {
'vendor-react': ['react', 'react-dom', 'react-dom/client'],
'vendor-radix': [
'@radix-ui/react-dialog',
'@radix-ui/react-popover',
'@radix-ui/react-select',
'@radix-ui/react-tabs',
'@radix-ui/react-tooltip',
'@radix-ui/react-slot',
],
'vendor-dnd': ['@dnd-kit/core', '@dnd-kit/sortable', '@dnd-kit/utilities'],
'vendor-query': ['@tanstack/react-query'],
},
},
},
},
server: {
port: 3000,
proxy: {