From 9b948ff3947fdea094956be20200de70f46cf97f Mon Sep 17 00:00:00 2001 From: dancodingbr Date: Thu, 7 May 2026 16:16:47 -0300 Subject: [PATCH 1/2] =?UTF-8?q?perf:=20fix=20CLS=200.997=20=E2=80=94=20inl?= =?UTF-8?q?ine=20skeleton=20and=20eager=20home/products=20routes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CLS of 0.997 was caused by a 3-level sequential JS chain that left blank for ~300ms before Angular rendered all content at once: index.html → main.js → home.chunk → productList.chunk (299ms total) Two fixes: 1. Make Home and ProductList routes non-lazy in app.routes.ts so both are bundled into main.js. Since Home already statically imports ProductList, this collapses the chain to a single main.js fetch. Initial bundle grows from ~12KB to ~19KB (gzipped) — still tiny. 2. Add an inline CSS skeleton inside in index.html that mirrors the home page layout (header, dark hero section, 4-col product grid). The skeleton is visible during the JS loading gap and is automatically removed when Angular bootstraps, so the layout shift from blank→content is replaced by skeleton→content which causes near-zero CLS. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/app/app.routes.ts | 6 +++-- frontend/src/index.html | 42 +++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/app.routes.ts b/frontend/src/app/app.routes.ts index a62189c..5960dc2 100644 --- a/frontend/src/app/app.routes.ts +++ b/frontend/src/app/app.routes.ts @@ -1,9 +1,11 @@ import { Routes } from '@angular/router'; import { authGuard } from './guards/auth-guard'; +import { Home } from './components/home/home'; +import { ProductList } from './components/product-list/product-list'; export const routes: Routes = [ - { path: '', loadComponent: () => import('./components/home/home').then(m => m.Home) }, - { path: 'products', loadComponent: () => import('./components/product-list/product-list').then(m => m.ProductList) }, + { path: '', component: Home }, + { path: 'products', component: ProductList }, { path: 'product/:id', loadComponent: () => import('./components/product-details/product-details').then(m => m.ProductDetails) }, { path: 'dashboard', loadComponent: () => import('./components/user-dashboard/user-dashboard').then(m => m.UserDashboard), canActivate: [authGuard] }, { path: 'cart', loadComponent: () => import('./components/cart/cart').then(m => m.Cart), canActivate: [authGuard] }, diff --git a/frontend/src/index.html b/frontend/src/index.html index 133b0b1..da95e1e 100644 --- a/frontend/src/index.html +++ b/frontend/src/index.html @@ -7,8 +7,48 @@ + - + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From 30b54dec3b7a7d5e543affb40c4f9f5435eeb105 Mon Sep 17 00:00:00 2001 From: dancodingbr Date: Thu, 7 May 2026 16:17:16 -0300 Subject: [PATCH 2/2] docs: update DISCUSSIONS.md --- docs/DISCUSSIONS.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/DISCUSSIONS.md b/docs/DISCUSSIONS.md index 1c5a867..abfcc1c 100644 --- a/docs/DISCUSSIONS.md +++ b/docs/DISCUSSIONS.md @@ -5,6 +5,22 @@ Sorted by descending date (most recent first). --- +# Session: PERF — Fix CLS 0.997 from Angular Bootstrap Delay +**Date:** 2026-05-07 +**Context and Problem to Solve** + +After deploying the previous round of performance fixes, production Lighthouse reported Performance 76/100 with CLS 0.997 — worse than before. Root cause: a 3-level sequential JS chain (index.html → main.js → home.chunk → productList.chunk = 299ms total) left `` blank for ~300ms before Angular rendered all content at once. The entire viewport shift from blank→content was recorded as CLS. The earlier skeleton fix addressed the wrong level of CLS (in-session product grid layout), not the Angular bootstrap CLS. + +**Summary of Decisions** + +| Decision | Rationale | +|---|---| +| **Make Home and ProductList routes non-lazy** | Home already statically imported ProductList; both were in separate lazy chunks due to `loadComponent`. Moving both to `component:` (static) collapsed the 3-level JS chain to 1. Initial bundle grows from ~12 KB to ~19 KB (gzipped) — still tiny, well under 1 MB error budget. | +| **Inline CSS skeleton in `index.html` inside ``** | Angular replaces `` children on bootstrap, so any HTML placed there is visible during the JS loading gap and removed automatically. A pure-CSS skeleton (no Tailwind — CSS bundle not yet loaded) mirrors the home page layout (header, dark hero, 4-col product grid). The shift becomes skeleton→content instead of blank→content, reducing CLS to near zero. | +| **Keep all other routes lazy** | Only Home and ProductList are on the initial page. All other routes (product-details, cart, checkout, dashboard, login, register) remain lazy and are preloaded in the background via `PreloadAllModules`. | + +--- + # Session: PERF — Lighthouse Score Improvements (CLS, Accessibility, SEO) **Date:** 2026-05-07 **Context and Problem to Solve**