Dive into browser architecture and rendering flow.
- Chromium architecture overview
- How Blink works
- Life of a pixel(Video|PPT)
Chromium has one browser process and N sandboxed renderer processes
- Browser process
- main process, startup process, broker process
- Main thread
- render browser UI
- I/O thread
- communicate with other process
- N Worker threads
- run tasks, like DNS lookup
- there exists a worker pool to add/remove threads dynamically
- Sandboxed renderer process
- Usually one process per tab
- because of the performance, no 1:1 mapping between renderer processes, iframes and tabs
- Main thread (runs Blink)
- render web content
- JavaScript, CSS, DOM
- I/O thread
- communicate with browser process
- from the view of renderer process, the browser process is a set of services
- N worker threads
- Internal threads
- web audio
- database
- GC
- Usually one process per tab
- A Page corresponds to a concept of a tab
- Renderer process : Page = 1 : N
- A Frame corresponds to a concept of a frame (the main frame or an iframe)
- Page : Frame = 1 : M
- A DOMWindow corresponds to a
window
object in JavaScript- Frame : DOMWindow = 1 : 1
- A Document corresponds to a
window.document
object in JavaScript- DOMWindow : Document = 1 : 1
- An ExecutionContext is a concept that abstracts a Document (the main thread) and a WorkerGlobalScope (a worker thread)
- e.g.,
iframe.contentWindow.location.href = "https://example.com";
- original Page
- original Frame
- new DOMWindow
- new Document
- new ExecutionContext
From an HTML file to pixels in the screen
- HTML
<div> <p> hello </p> <p> world </p> </div>
- Parse HTML:
HTML -> DOM
- DOM (document object model)
- Document - HTML - BODY - DIV - P - Text - P - Text
- contains shadow DOM
- Style
/* rules */ p { /* selector */ color: red; /* declaration: property + value */ }
- Parse Style:
Style -> StyleSheetContents
- StyleSheetContents
type CSSProperty = Color | ...; type CSSValue = CSSColorValue | ...; type CSSPropertyValue = { Property: CSSProperty; Value: CSSValue; } type StyleRule = { CSSSelectorList: CSSSelector[]; CSSPropertyValueSet: CSSPropertyValue[]; }; type StyleSheetContents = StyleRule[];
- Style Calculation:
StyleSheetContents + DOM -> ComputedStyle
- Style recalc: for every node in the DOM tree, compute the value of every style property
- Document::UpdateStyle
- StyleResolver::ResolveStyle
- JS:
getComputedStyle(element)["propertyName"]
- DOM with ComputedStyle (CSSOM?)
- Document + ComputedStyle - HTML + ComputedStyle - BODY + ComputedStyle - DIV + ComputedStyle - P + ComputedStyle - Text + ComputedStyle - P + ComputedStyle - Text + ComputedStyle
- Layout:
DOMTree -> LayoutTree -> FragmentTree
- Computes the exact position and size of each object
- Block box and inline box
- Normal flow. floats and absolute
- Text font, size, family
- Overflow and scrollable
- StyleEngine::RebuildLayoutTree
- LocalFrameView::UpdateLayout
- Computes the exact position and size of each object
- Layout Tree: ready to layout
- Document --> - LayoutView - HTML --> - LayoutBlockFlow - BODY --> - LayoutBlockFlow - DIV --> - LayoutBlockFlow - P --> - LayoutBlockFlow - Text --> - LayoutText - P --> - LayoutBlockFlow - Text --> - LayoutText
- DOM nodes are not 1:1 with layout objects.
- usually, one DOM node gets one LayoutObject
- a node -> no LayoutObject:
display: none;
- a node -> more than one LayoutObject: inline box with text before and after a block box(demo)
- no node -> a LayoutObject: Anonymous block boxes and Anonymous inline boxes
- DOM nodes are not 1:1 with layout objects.
- FragmentTree: layout result
- Walks the layout tree, computing the visual geometry of each LayoutObject
Box (block-flow) at 0,0 100x12 Box (block-flow children-inline) at 0,0 100x54 LineBox at 24.9,0 0x18 Box (floating block-flow children-inline) at 0,0 24.9x34 LineBox at 8,8 8.9x18 Text 'F' at 8,8 8.9x17 Text '\n' at 24.9,0 0x17 LineBox at 24.9,18 67.1x18 Text 'The ' at 24.9,18 28.9x17 Text 'quick' at 53.8,18 38.25x17 LineBox at 0,36 69.5x18 Text 'brown' at 0,36 44.2x17 Text ' fox' at 44.2,36 25.3x17 Box (block-flow children-inline) at 80,-6 20x18 LineBox at 0,0 39.125x18 Text 'jumps' at 0,0 39.125x17
- Paint:
FragmentTree -> PaintOperation[]
- Paint records paint operations into a list of display items.
- Paint elements in stacking order (controlled by
z-index
) - Paint runs in multiple phases, each paint phase is a separate traversal of a stacking context.
- LocalFrameView::PaintTree
- Raster(Compositor thread):
PaintOperation[] -> ColorBitmap
- Raster can be accelerated by the GPU process
- Draw(Compositor thread)
- Display content with GPU process
- Each pipeline stage tracks granular asynchronous invalidations.
- Style ->
Node::SetNeedsStyleRecalc()
- Layout ->
LayoutObject::SetNeedsLayout()
- Paint ->
PaintInvalidator::InvalidatePaint()
- Raster ->
RasterInvalidator::Generate()
- Style ->
- Layers
- New stacking context will promote a layout object to a layer
- Main thread will decompose the page into layers before paint
- Compositor thread will raster layers independently and composite them into one
- The compositor can handle input events like scroll, clip, scale, ...
- Compositing Assignments
- Build layers before paint in the main thread
- PaintLayerCompositor::UpdateAssignmentsIfNeeded
- Pre-paint
- Build the property trees before paint in the main thread
- PrePaintTreeWalk::Walk
- PaintPropertyTreeBuilder
- The property trees contain various properties for a layer
- overflow
- clip
- transform
- ...
- The compositor can apply them to a layer
- Recap the render pipeline:
Style -> Layout -> Paint -> Composite
- Main thread:
Style
,Layout
,Paint
- Compositor thread:
Composite
- Main thread:
- Whole pipeline: some properties will reflow the page
- Geometry:
width
,height
,top
,left
,padding
,margin
, ... - Position:
float
,display
,position
,flex
, ... - BFC Changing:
overflow
- Geometry:
- Skip
Layout
: some properties are "paint only"- Visual:
background
,color
- Stacking Context Changing:
z-index
,opacity
- Visual:
- Only
Composite
: best performance!- Layer properties:
transform
,opacity
- Promote elements with
will-change
ortranslateZ
- Avoid layer explosions
- Layer properties:
- Resources
- CSS Triggers: A CSS property will trigger which render flow