Modern browsers separate painting and compositing to enable smooth scrolling, animations, and visual effects without recalculating layout.
Layer tree construction
The browser constructs a layer tree to determine which elements should be painted to separate layers for efficient compositing.Why layers matter
Layers enable performance optimizations:Isolated repainting
Changes to one layer don’t require repainting other layers, reducing paint work.
GPU acceleration
Layers can be uploaded to the GPU as textures and composited with hardware acceleration.
Transform optimization
CSS transforms on a layer can be applied by the GPU without repainting.
Smooth animations
Animations of certain properties (transform, opacity) can run on the compositor thread.
What creates a layer?
Elements are promoted to their own layer based on several criteria:- Explicit promotion
- Visual effects
- Overflow and clipping
- Special elements
CSS properties that explicitly create layers:
Layer tree structure
The layer tree is a hierarchy of compositing layers:Identify compositing reasons
Scan the layout tree to find elements that require their own layer based on CSS properties and content type.
Build layer tree
Create a tree of layers where each layer corresponds to one or more elements that will be painted together.
Paint recording and display lists
Paint recording captures drawing commands without immediately rasterizing them to pixels.Display lists
A display list is a sequence of drawing commands that can be replayed later:Display lists decouple paint recording from rasterization, enabling optimizations like partial invalidation and threaded rasterization.
Paint recording process
The browser walks the layer tree and records paint commands:Record drawing commands
For each element, emit paint commands:
- Background (color, image, gradient)
- Border
- Decorations (outline, box-shadow, text-decoration)
- Content (text, replaced elements, children)
Paint invalidation
When elements change, the browser determines which parts need repainting:- Full repaint
- Partial repaint
- No repaint
The entire layer is marked dirty and must be completely repainted.Triggered by:
- Major layout changes
- Layer boundary changes
- Fundamental style changes
Rasterization strategies
Rasterization converts display lists into pixel buffers (bitmaps).Software rasterization
CPU-based rasterization using algorithms like Skia:
Advantages:
- Highly accurate rendering
- Supports all drawing operations
- Works on systems without GPU support
- Slower than GPU rasterization
- Blocks the main thread if not done asynchronously
GPU rasterization
Direct rasterization using GPU shaders:
Advantages:
- Much faster for simple shapes and common operations
- Reduces CPU load
- Eliminates bitmap upload step
- May be less accurate for complex paths
- GPU memory constraints
- Driver compatibility issues
Modern browsers use hybrid approaches: GPU rasterization for most content with software fallback for complex cases.
Tiling for large layers
Large layers are divided into tiles for efficient rasterization:Prioritize visible tiles
Rasterize tiles in viewport first, then nearby tiles that might scroll into view.
GPU compositing and texture management
The compositor combines all layers into the final frame.Compositor thread
Compositing runs on a dedicated thread, independent of the main thread:Smooth scrolling
Scrolling can update layer positions on the compositor thread without blocking on JavaScript or layout.
Smooth animations
Transform and opacity animations run on the compositor, maintaining 60fps even when the main thread is busy.
Input responsiveness
The compositor can respond to input events faster by not waiting for the main thread.
Reduced jank
Separating compositing from JavaScript execution prevents scripting from causing frame drops.
Compositing algorithm
The compositor draws the final frame:Build quad list
Create a list of textured quads (rectangles) representing each layer, with position, texture ID, transform, and effects.
Draw to framebuffer
Use the GPU to draw each quad:
- Bind the layer’s texture
- Apply transform matrix
- Apply opacity and blend mode
- Draw two triangles forming a rectangle
Texture management
Managing GPU textures efficiently is critical for performance:- Upload strategy
- Memory management
- Atlas packing
Minimize texture uploads by:
- Reusing textures when content doesn’t change
- Uploading asynchronously when possible
- Compressing textures for faster transfer
Advanced compositing features
Modern compositors support sophisticated effects:Filters and effects
Apply blur, brightness, contrast, and other filters using GPU shaders during compositing.
Backdrop filters
Capture the backdrop behind an element, apply filters, and composite the result (e.g., frosted glass effect).
Performance optimization strategies
Minimize layer count
Each layer has memory and processing overhead. Only create layers when necessary for performance.
Use compositor-only properties
Animate
transform and opacity instead of properties that trigger layout or paint.Avoid paint invalidation
Design animations to avoid changing painted content when possible.
Profile with DevTools
Use browser DevTools to identify layers, paint regions, and compositor activity.
Batch DOM changes
Group multiple DOM updates to trigger a single paint/composite cycle.
Debounce expensive operations
Throttle operations that cause excessive layer updates or repaints.
Measurement is key: Use
requestAnimationFrame timestamps and Performance API to measure paint and composite timing in production.Implementation checklist
When building paint and composite systems:Layer tree construction
Implement logic to identify elements requiring layers and build the layer tree hierarchy.
Rasterization engine
Choose a rasterization strategy (software, GPU, or hybrid) and implement tile-based rasterization.
Invalidation tracking
Implement efficient invalidation to minimize unnecessary repainting and reuploading.
Project checkpoint: Build a complete paint and composite pipeline in your browser engine (C++ or Rust). Implement layer tree construction, paint recording, rasterization (CPU or GPU), and GPU compositing. Render complex websites like Wikipedia with images, CSS animations, and fonts. Measure every phase and optimize for 60fps scrolling and animations.