Artikel

Browser rendering pipeline — Fra HTML til pixels

Browser rendering pipeline: HTML → DOM, CSS → CSSOM, DOM + CSSOM → Render tree → Layout → Paint → Composite. Hvert trin har performance-implikationer. At kende pipelinen er fundamentet for performance-optimering.

Browseren gennemgår en veldefineret sekvens af trin for at konvertere HTML og CSS til pixels på skærmen: HTML-parsing, CSSOM-opbygning, render tree-konstruktion, layout, paint og compositing. At forstå disse trin og deres afhængigheder er fundamentet for al performance-optimering — det forklarer præcist hvorfor visse ændringer er dyre og andre gratis for browseren at udføre.

Trin 1: HTML-parsing og DOM-opbygning

Browseren downloader HTML og parser det linje for linje til Document Object Model (DOM) — en træstruktur af noder der repræsenterer alle HTML-elementer og deres relationer.

HTML-parsing er ikke blokerende — browseren kan parse og vise dele af siden mens resten downloades. Men JavaScript uden defer stopper parsingen: browseren er nødt til at afvente script-download og -eksekvering.

Speculative parsing (lookahead parsing) er en browser-optimering: parseren scanner fremad og identificerer ressourcer (billeder, scripts, stylesheets) der kan downloades parallelt.

Trin 2: CSS-parsing og CSSOM-opbygning

CSS-filer downloades og parses til CSS Object Model (CSSOM) — en lignende træstruktur for styles. CSSOM er render-blocking: browseren kan ikke fortsætte til render tree-opbygning inden al CSS er processeret.

Årsagen: CSS er “cascade first” — en sen regel kan overskrive en tidlig. Browseren skal kende alle CSS-regler inden den beregner finale styles.

/* Begge regler er nødvendige for at beregne final color */
.button { color: blue; }
.button { color: red; }  /* override */

Trin 3: Render tree

Render tree kombinerer DOM og CSSOM. Det inkluderer kun synlige elementer — noder med display: none er ikke med. Hvert node i render tree har sine beregnede styles.

Render tree er inputtet til layout-steget.

Trin 4: Layout (reflow)

Layout beregner præcis position og størrelse på hvert element i render tree — i pixels, relativt til viewport. Det er en dyr operation fordi ét elements størrelse kan påvirke alle andre elementer.

Forced synchronous layout opstår når JavaScript læser layout-properties (offsetTop, clientWidth) efter at have modificeret DOM — browseren tvinges til at genberegne layout synkront. Undgå read-after-write patterns i hot paths.

Trin 5: Paint

Paint rasteriserer de beregnede elementer til pixels i lag. Tekst males. Baggrunde males. Borders males. Hvert lag males separat.

Paint er relativt dyrt sammenlignet med compositing, men billigere end layout. CSS-egenskaber der kun trigger paint (og ikke layout) inkluderer color, background-color og box-shadow.

Trin 6: Compositing

Compositor-threaden kombinerer de malede lag til det endelige billede der sendes til skærmen. Compositing kører på en separat thread fra main thread — det er grunden til at transform og opacity-animationer er hurtige: de håndteres udelukkende af compositor og blokerer ikke JavaScript-eksekvering.

/* Kun compositing — kører på compositor thread */
.fade { transition: opacity 0.3s; }
.slide { transition: transform 0.3s; }

/* Trigger paint — kører på main thread */
.color { transition: color 0.3s; }

GPU-acceleration

will-change: transform promoverer et element til sit eget compositor-lag, behandlet af GPU. Det eliminerer paint-overhead for animerede elementer — men bruger mere GPU-hukommelse. Brug det målrettet, ikke globalt.

Kritisk rendering path

Den korteste sekvens fra HTML til første pixels er: HTML-download → DOM-parse → CSS-download → CSSOM-build → Render tree → Layout → Paint → Composite. At forkorte denne vej er essensen af performance-optimering. → Denne artikel er en del af Web Performance — Core Web Vitals og teknisk hastighed.

Andre artikler i samme emne

Ofte stillede spørgsmål

Hvad er forskellen på layout, paint og compositing?
Layout (reflow) beregner position og størrelse på alle elementer. Paint rasteriserer elementer til pixels i lag. Compositing kombinerer de malede lag til det endelige billede der vises på skærmen. Layout er dyrest. Compositing er billigst. Animationer der kun kræver compositing (transform, opacity) kører uden at involvere layout eller paint.
Hvornår blokerer JavaScript rendering?
JavaScript-filer i `<head>` uden `defer` eller `async` stopper HTML-parsing og rendering. Browseren antager at scriptet kan modificere DOM og venter på download og eksekvering inden den fortsætter. CSS-filer blokerer rendering fordi CSSOM skal bygges inden render tree kan konstrueres.
Hvad er forced synchronous layout og hvorfor er det et problem?
Forced synchronous layout opstår når JavaScript læser layout-egenskaber som offsetTop eller clientWidth umiddelbart efter at have modificeret DOM. Browseren tvinges til at genberegne layout synkront på main thread — en dyr operation der blokerer alt andet. Det er en hyppig årsag til dårlig INP og lange tasks. Undgå read-after-write patterns i event handlers.
Hvad er forskellen på paint og compositing i rendering pipeline?
Paint rasteriserer elementer til pixels i separate lag — tekst, baggrunde, borders. Det kører på main thread. Compositing kombinerer de malede lag til det endelige billede og kører på compositor thread — en separat thread fra main thread. Animationer der bruger transform og opacity springer paint-trinnet over og kører udelukkende som compositing, hvilket giver jævne 60fps uden main thread-blokeringer.
Hvad er render tree og hvad indeholder det?
Render tree er kombinationen af DOM og CSSOM — et træ der kun indeholder synlige elementer med deres beregnede styles. Elementer med display:none er ikke med i render tree. Render tree er inputtet til layout-steget, hvor browseren beregner præcis position og størrelse på alle elementer. Render tree bygges forfra ved enhver DOM- eller CSSOM-ændring.

Placering i ordbogen

Browser rendering pipeline — Fra HTML til pixels