Saltar al contenido principal
ADR-015accepted

Critical Rendering Path Optimization Strategy

Contexto

The portfolio's target audience — technical hiring managers and VPs of Engineering — often evaluate sites on mobile devices during commutes or between meetings, on variable network conditions. First Contentful Paint (FCP) and Largest Contentful Paint (LCP) directly determine whether a visitor waits or bounces. The default Next.js setup produces reasonable performance, but several render-blocking patterns exist by default: external font loading, synchronous script execution, unoptimized resource discovery, and third-party script payloads (Google Analytics). Each of these adds milliseconds to the critical path — the sequence of resources that must load before the user sees meaningful content. The cumulative effect of unoptimized defaults can add 500ms-1s to FCP on 3G connections. For a portfolio that competes with other candidates' sites in a hiring manager's browser tabs, every 100ms matters.

Decisión

Implement a multi-layer critical rendering path optimization. Font loading: Geist fonts loaded via next/font/local with font-display: swap, eliminating external font CDN requests and ensuring text is visible immediately with system font fallback during load. Resource hints: preconnect to critical origins (statics.lucioduran.com, api.lucioduran.com, googletagmanager.com) in _document.js Head, with dns-prefetch fallbacks for browsers that don't support preconnect. Script loading: Google Analytics loaded with async attribute, and the gtag configuration executed inline to avoid a second network round-trip. No other third-party scripts are loaded. CSS delivery: styled-components' ServerStyleSheet extracts critical CSS during SSR and inlines it in the document head, eliminating FOUC and the need for external CSS requests. Image optimization: Next.js Image component with priority flag on above-the-fold images, automatic WebP/AVIF conversion, and lazy loading for below-the-fold content. HTTP: poweredByHeader disabled (removes X-Powered-By header, reducing response size by ~20 bytes per request), compress enabled for gzip/brotli.

Consecuencias

Positive: Lighthouse performance score consistently 95-100 across all pages. FCP under 1.0s on 4G, under 1.8s on 3G. LCP under 1.5s on 4G. Zero external CSS requests — all styles are inlined via ServerStyleSheet. The preconnect hints save ~100ms on the first API request by establishing TCP/TLS connections early. font-display: swap ensures text is visible within 50ms of page load (system font rendering) before Geist loads. The single third-party script (GA) loads asynchronously and does not block any rendering. Negative: ServerStyleSheet adds server-side rendering overhead (~20ms per page) — acceptable for SSG where rendering happens at build time, but would be a concern for SSR pages. The inline critical CSS increases HTML document size by 15-30KB per page (all styled-component styles are embedded). Preconnect hints are only effective for the first page load — subsequent navigations benefit from HTTP keep-alive instead. The optimization is tuned for the current page structure; significant layout changes would require re-evaluating the critical path.

Incertidumbre Calibrada

Predicciones al Momento de la Decisión

Expected Lighthouse scores above 90 after optimization. Predicted FCP under 1.5s on 4G. Assumed preconnect hints would save 50-150ms on initial API requests. Predicted the inline CSS approach would increase HTML size by 10-20KB. Expected Google Analytics to be the only performance-impacting third-party script.

Resultados Medidos

Lighthouse scores consistently hit 95-100, exceeding the >90 target. FCP measured at <1.0s on 4G, significantly better than the 1.5s prediction. Preconnect hints save approximately 100ms on the first API-dependent request — within the predicted range. Inline CSS increases HTML size by 15-30KB, slightly above the 10-20KB prediction due to the number of styled components growing from 80 to 120+ as new sections were added. GA remains the only third-party script. The unexpected outcome: the font-display: swap strategy produces a barely noticeable FOUT (Flash of Unstyled Text) on the very first visit — Geist loads within ~100ms, so the system font flash is brief but technically present.

Incógnitas al Momento de la Decisión

Did not know at decision time how many styled components would exist at scale — the inline CSS size grows linearly with component count. At 120+ components, the 15-30KB inline CSS is approaching the point where extraction to external CSS with caching would be more efficient for repeat visitors. Also unknown: whether Vercel's edge network would implement early hints (103 responses) that could further optimize resource discovery. They have not as of February 2026. Unknown: the cumulative impact of future third-party scripts (error monitoring, heatmaps, A/B testing) that might be added — the current strategy assumes GA is the only third-party dependency.

Clasificación de Reversibilidad

Puerta de Ida y Vuelta

Each optimization is independently reversible. Preconnect hints: remove link tags from _document.js. Font strategy: switch next/font/local config. Script loading: change async to defer or remove. ServerStyleSheet: remove from _document.js (accepting FOUC). Each change is localized to one file and testable independently. Estimated effort to reverse any single optimization: 15-30 minutes.

Contra-Argumento Más Fuerte

The optimization effort targets marginal gains that are invisible to the user. The difference between 0.9s FCP and 1.4s FCP is not consciously perceptible — both register as 'fast.' A simpler approach: use Next.js defaults, add the Google Font link, and accept the ~1.5s FCP. The engineering time spent on preconnect hints, font-display strategies, and ServerStyleSheet configuration could be spent on content. Most hiring managers evaluate portfolio content, not Lighthouse scores. The counter-counter: performance optimization is itself a signal of engineering quality. A portfolio that scores 100 on Lighthouse communicates attention to detail — a meta-signal that the Lighthouse score itself is less important than the discipline it represents.

Contexto Técnico

Stack
next/font/localServerStyleSheetpreconnectdns-prefetchasync scriptsNext.js Image
Lighthouse Performance
95-100
Fcp On4g
<1.0s
Fcp On3g
<1.8s
Lcp On4g
<1.5s
External Css Requests
0
Third Party Scripts
1
Restricciones
  • No external font CDN
  • GA is the only third-party script
  • ServerStyleSheet required for styled-components SSR

Decisiones Relacionadas