Comprehensive Overview of Browser Rendering Process and HTTP Request Flow
This article provides a detailed, step‑by‑step explanation of how a browser processes a simple HTTP request—from URL parsing, DNS lookup, and TCP connection through server handling, response reception, HTML/CSS parsing, layout, painting, reflow/repaint, and JavaScript execution—highlighting key concepts, optimizations, and common pitfalls.
The article begins with a preface stating that the author, a front‑end developer, has compiled a comprehensive note on the browser rendering pipeline, focusing on the stages most relevant to front‑end performance.
Overall Process
URL parsing
DNS query
TCP connection
Request handling
Response reception
Page rendering
1. URL Parsing
The browser first determines whether the input is a valid URL or a search keyword, performs auto‑completion and character encoding, and may enforce HSTS to upgrade to HTTPS. Additional checks such as security restrictions and cache inspection are also performed.
2. DNS Query
DNS resolution proceeds through multiple caches: browser cache, OS cache, router cache, ISP cache, and finally the root name servers if no cached entry exists. Both recursive and iterative lookup methods are described, along with notes on DNS hijacking and front‑end dns-prefetch optimizations.
3. TCP Connection
TCP/IP is divided into four layers. The application layer constructs the HTTP request (method, headers, body). The transport layer establishes a TCP three‑way handshake and segments the data. The network layer adds IP addresses and resolves MAC addresses via ARP. The link layer transmits Ethernet frames.
4. Server Processing
Typical HTTP servers (Apache, Nginx, IIS) listen for connections, spawn worker processes, parse the HTTP request, verify virtual host configuration, method permissions, and user authentication. They may issue redirects (301) or apply URL rewrite rules before invoking the appropriate backend interpreter.
5. Browser Receives Response
The browser examines response headers, handles status codes, decompresses compressed payloads (e.g., gzip), caches the resource, and selects a parser based on the MIME type.
6. Rendering the Page
Different browser engines follow a similar rendering pipeline: HTML parsing, CSS parsing, construction of the render tree, layout calculation, painting, and compositing.
6.1 HTML Parsing
Parsing proceeds line by line and consists of decoding, pre‑parsing (resource pre‑fetch), tokenization (lexical analysis), and tree construction. The parser builds DOM nodes as it encounters start tags.
6.2 CSS Parsing
The CSS parser tokenizes the stylesheet, builds a rule table, and matches selectors from right to left. Specificity (tag, class, id, inline style, !important) determines which rules apply.
6.3 Render Tree
The render tree merges the DOM tree with applicable CSS rules, discarding nodes with display:none. Layout computes geometric properties for each node, and painting draws the visual representation.
6.4 Layout & Painting
After layout, the engine calls paint() on each render node to rasterize content. Layers are then composited into the final bitmap.
6.5 Reflow & Repaint
Reflow (layout) occurs when changes affect geometry, while repaint occurs for visual changes that do not affect layout. Reflow is more costly; developers should minimize it (e.g., prefer visibility:hidden over display:none for toggling visibility).
6.6 JavaScript Execution
JavaScript execution involves lexical analysis, parsing to an AST, and code generation. Execution contexts (global, function, eval) form a call stack. The engine creates variable objects, scope chains, and determines this binding.
Task Queues
Browser threads include the JS engine thread, event thread, timer thread, and async HTTP thread. Tasks are divided into macro‑tasks (synchronous code, setTimeout, I/O) and micro‑tasks (Promises, process.nextTick), with micro‑tasks running after the current macro‑task but before the next one.
console.log('1'); // macro task sync
setTimeout(function(){ console.log('2'); }, 0); // macro task async
new Promise(function(resolve){ console.log('3'); resolve(); }).then(function(){ console.log('4'); }); // micro task
console.log('5'); // macro task syncThe execution order of the above code is 1, 3, 5, 4, 2.
Reference Documents
Links to HSTS, DNS, MIME, CSS syntax, browser caching, rendering principles, and JavaScript engine execution are provided for further reading.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
