Files
marketplaces/docs/archive/PERFORMANCE_REPORT.md
sdarbinyan 5374401257 docs: consolidate documentation and archive temporary reports
Step 1-2 (audit + plan): classified 35 project markdown files into
Core/Architecture/ADR/Temporary-audit/Sprint-report/Generated-review/
Duplicate/Obsolete/Historical. Agent-tooling files (.agents/skills/**,
.superpowers/**, docs/context/**, CLAUDE.md/GEMINI.md/AGENTS.md/
.github/copilot-instructions.md) explicitly out of scope — intentional
per-tool duplication, not documentation debt.

Step 3 (merge, no information lost):
- docs/PROJECT.md -> docs/PROJECT_INDEX.md, rewritten as the single
  entry point: system overview, living-doc index, archive pointer,
  current status, and a critical-finding callout up top.
- docs/backend/BACKEND-INTEGRATION.md -> docs/BACKEND_API.md,
  docs/backend/REMAINING-BACKEND-WORK.md ->
  docs/BACKEND_API_REMAINING_WORK.md (also folded in a legitimate
  uncommitted status update that had been sitting unstaged all
  session: categories marked DONE, order-creation endpoint noted done).
- RELEASE-NOTES.md merged into CHANGELOG.md (was a near-duplicate of
  the same release content in friendlier prose), then deleted.
- KNOWN-ISSUES.md: added item 13 (see below) and item 14 (missing
  canDeactivate on admin/products edit, from the archived PROJECT-STATE
  audit, re-verified still true); added a correction note to Fixed
  item 7.
- All cross-references to renamed/moved files fixed across every
  kept doc (grep+sed pass, then verified with a link-existence check
  across all 58 in-scope markdown files -> 0 broken links).

Step 4 (archive, nothing deleted without merging first): created
docs/archive/, moved 19 files there (3 root sprint reports, 1 platform
report, SPRINT-PLAN.md, and 14 one-off audit/review/report docs).
Added correction headers to the 3 archived docs whose conclusions were
affected by the finding below, rather than silently leaving them
misleading.

Step 5: docs/PROJECT_INDEX.md rewritten per the mission brief -
someone opening the repo should understand the whole system from it.

IMPORTANT FINDING (surfaced during this audit, not the mission's
primary goal but too significant to bury): pages/category/*,
pages/search/*, pages/item-detail/*, pages/info/**, pages/legal/**
(40+ files) are entirely unrouted dead code - app.routes.ts's
cmsContentRoutes is a literal empty array, and category/search/product
routes redirect to CatalogContainerComponent/
ProductDetailsContainerComponent, not these files. Confirmed against
app.routes.ts directly and cross-checked against FRONTEND.md's own
routing description. This means several fixes from earlier this cycle
(RC-Premium-01, RC STORE-01) and the dead-code cleanup sprint's
conclusion that these files were live were all wrong - documented as
KNOWN-ISSUES.md item 13, flagged at the top of PROJECT_INDEX.md, and
noted on the 3 archived docs whose conclusions it affects. No
application code was changed to fix this (out of scope per this
session's 'documentation only' constraint) - it needs a wire-it-up-or-
delete-it decision first.

Verification: tsc --noEmit clean, npm run build green, all markdown
links across 58 in-scope files resolve (checked programmatically).
No application/Angular/backend code modified.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-25 19:10:49 +04:00

56 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Performance Report — RC PERF-01
Production-readiness performance audit + fixes, application-wide. No redesign, no UI/visual changes, no route/API changes — pure performance/correctness work. Three sequential commits on branch `B2B` (not pushed):
| Commit | Scope |
|---|---|
| `61a5714` | Angular reactivity, change detection, rendering, memory |
| `4bf0666` | Bundles, lazy-loading, tree-shaking, large chunks |
| `2e931bb` | Assets: images, fonts, SVG, CSS |
`npm run build` verified green after every commit. `npx tsc --noEmit` clean throughout.
## Headline result
Initial bundle: **1.47 MB → 1.12 MB raw** (350 KB / 24%), transfer estimate **263.59 kB → 221.51 kB** (16%). Budget overage shrank from 769 KB over to 417 KB over (still a warning, not an error — the 700 KB budget itself is unchanged and still exceeded, see Remaining below). Global CSS bundle: 9.60 kB → 8.41 kB raw (12%).
## Findings and fixes by area
### Angular reactivity / change detection / memory (`61a5714`)
- **`.subscribe()` audit**: 149 call sites across 44 files. Spot-checked every long-lived stream in the highest-risk components (route params, router events, polling/intervals) — all already use `takeUntilDestroyed(this.destroyRef)` or an explicit `Subscription` + `ngOnDestroy` unsubscribe. One-shot HTTP-backed subscribes self-complete, no leak. **No leaks found** — the codebase's existing discipline here was already solid.
- **`ChangeDetectionStrategy.OnPush`**: 191 components, 190 already had it. Added to the 1 remaining (`app.ts`, the root component) — verified safe (signal-driven template, no direct DOM mutation).
- **`@for`/`track`**: fully compliant app-wide — the codebase is entirely on the new control-flow syntax, which the compiler requires `track` on, so there was nothing to fix. Legacy `*ngFor` without `trackBy`: zero occurrences.
- **Duplicate HTTP calls**: `CategoryFacade` and `ConfigService` already cache via `shareReplay({bufferSize:1, refCount:true})`, applied consistently — no duplicate-request pattern found.
- **Flagged, not fixed**: 2 `combineLatest` sites (`catalog-container.component.ts`, `subcategories.component.ts`) are narrow, already-minimal RxJS composition — converting to `computed()` would touch adjoining facade state shape, judged out of this pass's risk budget. Per-item template method calls in `@for` loops (`getDiscountedPrice`, `itemName`, `categoryName`, `stockLabelKey`) are cheap pure lookups on an already-OnPush host — flagged as pipe-conversion candidates for a future pass, not urgent.
### Bundles / lazy-loading / tree-shaking (`4bf0666`)
- **Lazy-loading boundaries**: already correct — every storefront/builder/backoffice route in `app.routes.ts` uses `loadComponent`, nothing eagerly imported.
- **i18n eager-loading — the biggest single win**: `TranslateService` statically imported all three locale packs (ru/en/hy, 346 KB raw combined) into the initial bundle regardless of visitor language. Fixed: `ru` (default) stays eager, `en`/`hy` are now `import()`ed on demand via a new `preloadLanguage()`, awaited inside `languageGuard` before route activation — router blocks navigation until the pack resolves, so there's no untranslated-flash risk.
- **Dead code**: `knip` found `src/app/components/items-carousel/*` (3 files) completely unreferenced anywhere, and the sole consumer of the `primeng` dependency. Deleted the component and its now-dead `primeicons.css` import from `src/styles.scss`.
- **Tree-shaking**: fixed one accidental barrel import in `widget-host.service.ts` (now imports `UnknownWidgetComponent` directly instead of through the `widgets/ui` barrel) — negligible measured impact, but correct going forward. `@lucide/angular` icons already use named tree-shakeable imports.
- **Duplicate deps**: `npm ls` confirms a single deduped `rxjs@7.8.2` — no duplicate module instances.
- **Flagged, not fixed**: `primeng`/`primeicons` remain in `package.json`/lockfile — `npm install`/`uninstall` fails in this environment (`ETARGET`) on a pre-existing, unrelated broken `barry-cache` devDependency, so the lockfile couldn't be safely regenerated by hand. **Follow-up needed**: fix the `barry-cache` devDependency resolution, then `npm uninstall primeng primeicons` to drop the dependency entirely (the code reference is already gone). Large chunks (`project-editor` 320 kB, `catalog-container` 126 kB, `product-details-container` 88 kB, `cart` 61 kB) unchanged — no mechanical split found inside their scope; a real reduction here would mean lazy-loading a sub-feature (e.g. an embedded editor), which is a larger, dedicated task.
### Assets: images, fonts, SVG, CSS (`2e931bb`)
- **Images**: storefront `<img>` tags already have `loading="lazy"`/`decoding="async"` on grids/galleries and CLS is already handled via CSS `aspect-ratio` (from prior RC-Visual-02/RC-Premium-01 passes) — nothing to fix. Flagged: a handful of single-image admin/editor previews lack `loading="lazy"` (page-editor, brand-overview, asset-details-drawer) — negligible traffic, left alone.
- **Fonts**: `index.html` already preconnects to Google Fonts, loads DM Sans 400/500/600/700 with `display=swap`; all 4 loaded weights are actually used. Flagged: weights 800/900 are referenced in some component SCSS but never loaded (pre-existing faux-bold rendering) — changing loaded weights risks a visible text difference, left out of scope for a perf-only pass.
- **SVG**: icon system is fully centralized through `@lucide/angular` via `icon-registry.ts` — no inline path duplication. `public/` SVGs checked for editor cruft (metadata/inkscape artifacts) — already clean. Flagged: 5 branding SVGs (`mastercard-logo.min.svg`, `dexar-logo*.svg`, `dexar-favicon.svg`, `novo-logo.svg`, `novo-favicon.svg`) appear unreferenced in `src`, left in place — may back tenant branding resolved from the backend at runtime, deletion needs a human decision, not this pass's call.
- **CSS**: manual grep-based cross-check (literal + hyphen-safe, checked for dynamic `[class.x]`/string-built classes too) of `src/styles.scss` utility classes against all templates. Confirmed-dead and removed: `.btn-primary`/`.btn-secondary`+hover, `.catalog-product-card`, `.item-badges-overlay`, `.item-simple-desc`, `.text-center`, `.mt-1..4`, `.mb-1..4`, `.p-1..4`.
## Remaining recommendations (not applied — flagged for follow-up)
1. **`primeng`/`primeicons` still in `package.json`** despite the only consumer being deleted — needs the pre-existing `barry-cache` devDependency resolution issue fixed first, then a clean `npm uninstall`. Highest-value remaining action: would likely close most of the remaining 417 KB budget overage in one move once confirmed.
2. **Large lazy chunks** (`project-editor` 320 kB, `catalog-container` 126 kB) — no mechanical fix found; needs a dedicated task to identify a genuinely lazy-loadable sub-feature inside each.
3. **2 `combineLatest` sites** — safe to leave, candidates for a `computed()` conversion in a future facade-focused pass.
4. **Per-item template method calls** in `@for` loops — pipe-conversion candidates, not urgent (already bounded by OnPush).
5. **Font weights 800/900** used in SCSS but not loaded — either load them explicitly or normalize the SCSS to a loaded weight; a design-system call, not a perf call.
6. **5 unreferenced branding SVGs** — confirm with backend/tenant-branding owner before deleting.
7. **Admin/editor preview images** missing `loading="lazy"` — low priority, low traffic.
## Verification
`tsc --noEmit` and `npm run build` run and green after each of the three commits. No live browser session available this session — real-world Core Web Vitals (LCP/CLS/INP) were not measured; recommend a Lighthouse/WebPageTest pass against a deployed build before the client demo referenced in `docs/FRONTEND-ROADMAP.md`.