mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
perf: dynamic-import LineProfilerView to defer prism-react-renderer (#2557)
## Summary - Replaces static import of `LineProfilerView` with `next/dynamic` + `ssr: false` - Defers loading of `prism-react-renderer` (~100KB+) until user navigates to profiler tab - Adds `<Skeleton>` loading fallback for smooth UX ## Evidence - Proof doc: `js/cf-webapp/proof/13-dynamic-import-line-profiler.md` ## Test plan - [ ] `bash js/cf-webapp/proof/reproducers/13-dynamic-import-line-profiler.sh` — 7/7 checks pass - [ ] `npm run build` succeeds - [ ] Profiler page loads and renders LineProfilerView correctly
This commit is contained in:
parent
fbedf0c1ee
commit
67ec032429
3 changed files with 116 additions and 1 deletions
39
js/cf-webapp/proof/13-dynamic-import-line-profiler.md
Normal file
39
js/cf-webapp/proof/13-dynamic-import-line-profiler.md
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Proof 13: Dynamic-import LineProfilerView
|
||||
|
||||
## What Changed
|
||||
- Replaced static import of `LineProfilerView` with `next/dynamic` in the profiler page
|
||||
- Added `ssr: false` since the component uses browser-only APIs
|
||||
- Added `<Skeleton>` loading fallback
|
||||
|
||||
## Why
|
||||
`LineProfilerView` depends on `prism-react-renderer`, which pulls in Prism.js grammar definitions (~100KB+). By using `next/dynamic` with `ssr: false`:
|
||||
- The profiler page's initial JS bundle shrinks — Prism grammars are loaded on-demand
|
||||
- The component only loads when the user navigates to the profiler tab, not on initial page load
|
||||
- SSR is skipped for a component that relies on client-side rendering anyway
|
||||
|
||||
## Evidence
|
||||
|
||||
### Before (static import)
|
||||
```tsx
|
||||
import { LineProfilerView } from "@/components/LineProfiler"
|
||||
```
|
||||
|
||||
### After (dynamic import)
|
||||
```tsx
|
||||
import dynamic from "next/dynamic"
|
||||
import { Skeleton } from "@/components/ui/skeleton"
|
||||
|
||||
const LineProfilerView = dynamic(
|
||||
() => import("@/components/LineProfiler").then(mod => mod.LineProfilerView),
|
||||
{
|
||||
ssr: false,
|
||||
loading: () => <Skeleton className="h-full w-full" />,
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
## How to Verify
|
||||
```bash
|
||||
cd js/cf-webapp
|
||||
bash proof/reproducers/13-dynamic-import-line-profiler.sh
|
||||
```
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
#!/usr/bin/env bash
|
||||
# Proof reproducer for commit 13: dynamic-import LineProfilerView
|
||||
set -euo pipefail
|
||||
|
||||
PASS=0
|
||||
FAIL=0
|
||||
TOTAL=0
|
||||
|
||||
check() {
|
||||
local desc="$1"; shift
|
||||
TOTAL=$((TOTAL + 1))
|
||||
if "$@" >/dev/null 2>&1; then
|
||||
echo " PASS: $desc"
|
||||
PASS=$((PASS + 1))
|
||||
else
|
||||
echo " FAIL: $desc"
|
||||
FAIL=$((FAIL + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
check_not() {
|
||||
local desc="$1"; shift
|
||||
TOTAL=$((TOTAL + 1))
|
||||
if "$@" >/dev/null 2>&1; then
|
||||
echo " FAIL: $desc"
|
||||
FAIL=$((FAIL + 1))
|
||||
else
|
||||
echo " PASS: $desc"
|
||||
PASS=$((PASS + 1))
|
||||
fi
|
||||
}
|
||||
|
||||
PROFILER_PAGE="src/app/(dashboard)/review-optimizations/[traceId]/profiler/page.tsx"
|
||||
|
||||
echo "=== Proof 13: dynamic-import LineProfilerView ==="
|
||||
echo ""
|
||||
|
||||
echo "--- Dynamic import checks ---"
|
||||
check "next/dynamic is imported" \
|
||||
grep -q 'import dynamic from "next/dynamic"' "$PROFILER_PAGE"
|
||||
|
||||
check "LineProfilerView uses dynamic()" \
|
||||
grep -q 'const LineProfilerView = dynamic(' "$PROFILER_PAGE"
|
||||
|
||||
check "ssr: false is set" \
|
||||
grep -q 'ssr: false' "$PROFILER_PAGE"
|
||||
|
||||
check_not "no static import of LineProfilerView" \
|
||||
grep -q 'import { LineProfilerView }' "$PROFILER_PAGE"
|
||||
|
||||
echo ""
|
||||
echo "--- Loading fallback checks ---"
|
||||
check "Skeleton component is imported" \
|
||||
grep -q 'import { Skeleton }' "$PROFILER_PAGE"
|
||||
|
||||
check "loading fallback uses Skeleton" \
|
||||
grep -q 'loading:' "$PROFILER_PAGE"
|
||||
|
||||
echo ""
|
||||
echo "--- Module resolution check ---"
|
||||
check "dynamic import resolves @/components/LineProfiler" \
|
||||
grep -q '@/components/LineProfiler' "$PROFILER_PAGE"
|
||||
|
||||
echo ""
|
||||
echo "=== Results: $PASS/$TOTAL passed, $FAIL failed ==="
|
||||
[ "$FAIL" -eq 0 ] && echo "ALL CHECKS PASSED" || echo "SOME CHECKS FAILED"
|
||||
exit "$FAIL"
|
||||
|
|
@ -5,7 +5,16 @@ import { useParams, useRouter } from "next/navigation"
|
|||
import { ArrowLeft, Zap, Loader2, AlertTriangle } from "lucide-react"
|
||||
import { getOptimizationEventById } from "../action"
|
||||
import { getUserIdAndUsername } from "@/app/utils/auth"
|
||||
import { LineProfilerView } from "@/components/LineProfiler"
|
||||
import dynamic from "next/dynamic"
|
||||
import { Skeleton } from "@/components/ui/skeleton"
|
||||
|
||||
const LineProfilerView = dynamic(
|
||||
() => import("@/components/LineProfiler").then(mod => mod.LineProfilerView),
|
||||
{
|
||||
ssr: false,
|
||||
loading: () => <Skeleton className="h-full w-full" />,
|
||||
},
|
||||
)
|
||||
import { useViewMode } from "@/app/app/ViewModeContext"
|
||||
import { toast } from "sonner"
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue