Преглед изворни кода

feat: update analysis ledger with new KPIs and measurement results for module optimization

Yuki Takei пре 1 месец
родитељ
комит
81b0f0c317
1 измењених фајлова са 71 додато и 0 уклоњено
  1. 71 0
      .kiro/specs/reduce-modules-loaded/analysis-ledger.md

+ 71 - 0
.kiro/specs/reduce-modules-loaded/analysis-ledger.md

@@ -1,6 +1,8 @@
 # Analysis Ledger
 
 ## Measurements
+
+### Legacy KPI (total modules from `Compiled ... (N modules)`)
 | Step | Task | Modules | Time | Date |
 |------|------|---------|------|------|
 | Baseline (no changes) | 1.1 | 10,066 | ~31s | 2026-02-19 |
@@ -12,6 +14,17 @@
 | Revert only serializer fix | bisect | 10,281 | ~31.2s | 2026-02-19 |
 | Revert only axios fix | bisect | 10,281 | ~31.1s | 2026-02-19 |
 
+> **Note**: Total module count includes both initial (eager) and async (lazy) chunks. Dynamic imports move modules to async chunks without reducing the total, so this metric does NOT reflect lazy-loading improvements. Replaced by ChunkModuleStats KPI below.
+
+### New KPI: ChunkModuleStats (initial / async-only / total)
+
+Measured via `ChunkModuleStatsPlugin` in `next.config.utils.js`. The `initial` count represents modules loaded eagerly on page access — this is the primary reduction target.
+
+| Step | Task | initial | async-only | total | Compiled modules | Date |
+|------|------|---------|------------|-------|------------------|------|
+| **Baseline (no Phase 2 changes)** | 8.1 | **2,704** | 4,146 | 6,850 | 10,068 | 2026-02-20 |
+| + MermaidViewer dynamic + date-fns subpath | 8.1 | **2,128** | 4,717 | 6,845 | 10,058 | 2026-02-20 |
+
 > **Note**: Originally reported baseline was 51.5s, but automated measurement on the same machine consistently shows ~31s. The 51.5s figure may reflect cold cache, different system load, or an earlier codebase state.
 
 ### Measurement Method
@@ -131,3 +144,61 @@ The following approaches can actually reduce compilation time for `[[...path]]`:
 3. `I18NextHMRPlugin` — webpack-specific; may need alternative
 
 **Decision**: Phase 1 committed changes are kept as code quality improvements (server/client boundary enforcement, dead code removal). Phase 2 evaluation is needed for actual compilation time reduction.
+
+## Phase 2: Module Graph Analysis and Dynamic Import Optimization (Task 8.1 continued)
+
+### Module Composition Analysis
+
+Client bundle module paths extracted from `.next/static/chunks/` — 6,822 unique modules total.
+
+**Top 10 module-heavy packages in [[...path]] compilation:**
+
+| Package | Modules | % of Total | Source |
+|---------|---------|-----------|--------|
+| lodash-es | 640 | 9.4% | Transitive via mermaid → chevrotain |
+| date-fns | 627 | 9.2% | Direct (barrel imports) + react-datepicker (v2) |
+| highlight.js | 385 | 5.6% | react-syntax-highlighter → CodeBlock |
+| refractor | 279 | 4.1% | react-syntax-highlighter → CodeBlock |
+| core-js | 227 | 3.3% | Next.js polyfills (not controllable via imports) |
+| @codemirror | 127 | 1.9% | Editor components |
+| lodash | 127 | 1.9% | Transitive via express-validator |
+| d3-array | 120 | 1.8% | Transitive via mermaid |
+| react-bootstrap-typeahead | 106 | 1.6% | Search/autocomplete UI |
+| **Top 10 total** | **2,752** | **40%** | |
+
+### Changes Applied
+
+1. **MermaidViewer → `next/dynamic({ ssr: false })`**
+   - Split `import * as mermaid from '~/features/mermaid'` into:
+     - Static: `remarkPlugin` + `sanitizeOption` from `~/features/mermaid/services` (lightweight, no npm mermaid)
+     - Dynamic: `MermaidViewer` via `next/dynamic` (loads mermaid npm + lodash-es + chevrotain on demand)
+   - SSR impact: None — client renderer only (`assert(isClient())`)
+
+2. **CodeBlock → `next/dynamic({ ssr: false })`**
+   - Removed static `import { CodeBlock }` from shared renderer (`src/services/renderer/renderer.tsx`)
+   - Added `DynamicCodeBlock` via `next/dynamic` in client renderer only
+   - SSR impact: Code blocks render without syntax highlighting during SSR (accepted trade-off)
+
+3. **date-fns barrel → subpath imports (12 files)**
+   - Converted all `import { ... } from 'date-fns'` to specific subpath imports
+   - e.g., `import { format } from 'date-fns/format'`
+   - Files: Comment.tsx, ShareLinkForm.tsx, ActivityListItem.tsx, DateRangePicker.tsx, FormattedDistanceDate.jsx, create-custom-axios.ts, activity.ts, user-activation.ts, forgot-password.js, thread-relation.ts, normalize-thread-relation-expired-at.ts, normalize-thread-relation-expired-at.integ.ts
+
+4. **core-js — no action possible**
+   - 227 modules come from Next.js automatic polyfill injection, not application imports
+   - Can only be reduced by `.browserslistrc` (targeting modern browsers) or Next.js 15+ upgrade
+
+### Measurement Results
+
+| Metric | Before | After | Change |
+|--------|--------|-------|--------|
+| Modules | 10,066 | 10,054 | -12 |
+| Compile time (run 1) | ~31s | 26.9s | -4.1s |
+| Compile time (run 2) | ~31s | 26.7s | -4.3s |
+| **Average compile time** | **~31s** | **~26.8s** | **-4.2s (14%)** |
+
+### Analysis
+
+- **Module count decreased only 12**: Dynamic imports still count as modules in the webpack graph, but they're compiled into separate chunks (lazy). The "10,054 modules" includes the lazy chunks' modules in the count.
+- **Compile time decreased ~14%**: The significant improvement suggests webpack's per-module overhead is not uniform — mermaid (with chevrotain parser generator) and react-syntax-highlighter (with highlight.js language definitions) are particularly expensive to compile despite their module count.
+- **date-fns subpath imports**: Contributed to the module count reduction but likely minimal time impact (consistent with Phase 1 findings).