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

7.7 KiB
Raw Blame History

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.