Key points
This Chinese forum post (zhichai.net) explains what modern browsers actually do between a user pressing Enter and a page appearing, based on Addy Osmani's writing on how modern browsers work. The author argues that the classic 12-step answer (DNS resolution, TCP handshake, TLS negotiation, HTTP request, DOM construction, CSSOM, render tree, layout, paint, composite) is a 1980s-era linear model, and the real question is how browsers finish all of this in ~200ms — and how common coding habits silently break their optimizations.
About Addy Osmani
- Built a browser (XWebs) in C++ at age 16; won a national youth science competition in Ireland
- Joined Google in 2012 and led Chrome Developer Experience
- Overseen Chrome DevTools (~40M developers daily), co-created Lighthouse and Core Web Vitals, worked on Speedometer with Apple WebKit, and led Gemini AI integration into DevTools (2023–2025)
- Preload scanner: while the HTML parser is blocked on a synchronous
<script>, a separate scanner "peeks ahead" in the raw HTML to start downloading images, CSS, fonts, and JS early. Chrome experiments show roughly a 20% page-load improvement. Critically, it cannot execute JavaScript — resources whose URLs are generated dynamically in JS are invisible to it. Fix: keep resources in HTML or use<link rel="preload" href="hero.jpg" as="image" fetchpriority="high">. - Speculation Rules API: Chrome can prerender pages the user is predicted to visit next (e.g.,
/next-page), making navigation instant. Google Search already uses it. - HTML parsing is a state machine with 80+ states defined in the HTML5 spec, designed for fault tolerance on malformed HTML (browsers may recover slightly differently).
- CSS is a context-free language: tokenization then parsing. An unrecognized property invalidates the entire rule, which matters for vendor-prefix ordering.
- Render-blocking insight: synchronous JS blocks DOM construction, CSS blocks rendering, and synchronous JS can also block CSSOM construction — hence "CSS in head, JS at end of body."
- JIT pipeline: Ignition (bytecode interpreter, fast startup) collects profiling data; hot code is compiled by TurboFan into optimized machine code; broken assumptions trigger deoptimization.
- Hidden classes: objects with the same property structure share hidden classes; adding properties at runtime (e.g.,
p3.z = 7) forces new hidden classes and loses optimization. Keep property order consistent; keep arrays single-typed. - Garbage collection: generational — Scavenge (copying) for the young generation, Mark-Sweep-Compact for the old generation, with incremental marking and concurrent sweeping to reduce pauses.
- Chrome uses a multi-process architecture (browser, per-site renderer, GPU, network service, utility processes) with sandboxing and Site Isolation.
- Pipeline: JavaScript → Style → Layout → Layer → Paint → Composite.
- Cost hierarchy: reflow (geometry changes like width/top — most expensive) > repaint (color, visibility) > composite (transform, opacity — cheapest). Use
transforminstead oftop/leftand batch style writes. - Avoid forced synchronous layout: interleaved reads (
offsetHeight) and writes force immediate reflow. Batch all reads first, then all writes. - Core Web Vitals targets: LCP ≤ 2.5s, INP (formerly FID) ≤ 200ms, CLS ≤ 0.1. Keep the LCP element visible in HTML with
fetchpriority="high"; never insert it via JS; set explicit dimensions to prevent CLS. - Resource priorities range from Highest (HTML, sync CSS, fonts) to Lowest (prefetch); tune with
fetchpriority. - Osmani's checklist: inline critical CSS, defer non-critical JS, code splitting, lazy-load images, modern formats (WebP/AVIF), font subsetting.
- Addy Osmani, "How Modern Browsers Work" (Medium, 2025)
- Addy Osmani biography: https://addyosmani.com/bio/
- Ilya Grigorik, *High Performance Browser Networking* (O'Reilly)
- Chrome Developers Documentation: developers.google.com/web
- V8 Blog: v8.dev/blog
Network layer: speculative loading
Parsing layer
V8 JavaScript engine
Rendering pipeline
Performance optimization
The "70% problem"
Most performance issues come from basics: unoptimized images (~30%), uncompressed JS/CSS (~20%), render-blocking resources (~15%), font loading (~5%). ~70% of problems are solved without advanced techniques.
Takeaway
> Don't fight the browser — work with its rules. If you don't understand how browsers load, parse, and render your code, your optimization is guesswork — and guesswork is usually wrong.