Transform vs Absolute: How Browser Rendering Impacts Performance
This article compares CSS transform and absolute positioning animations, explains why transform avoids costly repaint operations, and delves into the browser’s rendering pipeline—including DOM, CSSOM, render tree, render objects, layers, and graphics layers—to show how compositing optimizations improve performance.
1 Transform Animation
Similar to the “fly into cart” animation when clicking a product, many have encountered or implemented such moving animations. However, compared with using Absolute positioning, what are the differences when using Transform?
From the above figure, the implementations of Transform and Absolute appear similar. To better observe the differences, we enable the repaint toggle in the browser to monitor element repainting.
The case shows that elements using Absolute remain in repaint throughout movement, while those using Transform do not trigger repaint. Thus transform does not cause repaint; to understand why, we need to discuss browser rendering.
2 Browser Rendering
2.1 What Happens After the DOM Tree?
After the browser fetches front‑end resources, it builds the DOM tree and the CSSOM tree. These two trees are combined into a Render tree, which is used to calculate layout for each visible element and then painted to the screen. Between the DOM and the final picture, the browser goes through several steps such as creating Render Object, RenderLayer, and Graphics Layer.
2.2 Render Object Tree
The CSSOM and DOM are merged into the Render Tree. Each visible node in the DOM corresponds to a Render Object. The Render Object Tree is essentially the DOM and CSSOM combined, with invisible nodes removed.
Rules for generating Render Object:
Document node in the DOM tree.
Visible nodes (marked with 1).
Anonymous Render Object generated in certain cases (marked with 2).
[1] Invisible nodes such as meta, head, script, or elements with display:none have no visual meaning (note that visibility:hidden is still considered visible).
[2] Anonymous Render Object The browser may create an anonymous render object when an inline element contains both block and inline children, according to CSS specifications.
RenderObject knows how to draw a Node on the canvas by issuing drawing calls to a GraphicsContext . In Chrome, GraphicsContext wraps the Skia 2D graphics library.
2.3 Render Layer
The page layout involves complex stacking relationships such as z-index and clipping via overflow. These relationships cannot be expressed in a single Render Object, so the browser introduces Render Layer to store layer information.
Common situations where a Render Object is associated with a Render Layer:
Root object of the page.
Objects with explicit CSS positioning ( relative, absolute, transform).
Transparent objects ( opacity < 1).
Objects with overflow, alpha mask, or reflection properties.
Objects with a CSS filter. <canvas> 2D/3D (WebGL) contexts. <video> elements.
2.4 Graphics Layer
The browser splits the DOM into multiple Render Layer s, rasterizes each independently, and uploads the bitmap as a texture to the GPU for compositing. When a render layer contains heavy content such as video or WebGL, even a small update can become a performance bottleneck.
To avoid this, the browser provides a backend storage called a Graphics Layer for specific render layers, allowing the compositor to skip reflow and repaint and perform composition directly on the GPU.
In theory, any Render Layer could be promoted to a Graphics Layer, but doing so wastes memory. In practice, a render layer can have its own graphics layer only when certain conditions are met:
3D or perspective transforms ( perspective, transform).
Elements that use accelerated video decoding.
Elements with a 3D (WebGL) or accelerated 2D context.
Embedded plugins (e.g., Flash).
Elements animating opacity or using a transform animation.
Elements with accelerated CSS filters. iframe or elements with position:fixed.
2.5 Promote Composite Layers
Benefits of composite layers:
The bitmap of a composite layer is used as a texture by the GPU, making graphic calculations fast.
When a layer is repainted or re‑flowed, other layers are unaffected.
2.5.1 transform: translateZ(0)
Early browsers used transform: translateZ(0) to force GPU acceleration, even if no visual perspective change occurs.
Note: Using transform creates a containing block, which can affect the positioning context of position:fixed/absolute elements.
2.5.2 backface-visibility: hidden
In early Chrome and Safari versions, transform: translateZ(0) caused flickering, so developers switched to backface-visibility:hidden.
2.5.3 will-change
Since iOS 9, the will-change property informs the browser that a property may change, allowing it to apply optimizations in advance. Using will-change:transform or will-change:opacity forces the element to be promoted to a composite layer.
2.6 Reasonable Use of Composite Layers
Although composite layers are a powerful tool for animation optimization, misuse can backfire.
2.6.1 Creation Overhead
Rendering consists of painting (JS, style, layout, paint) on the CPU and compositing on the GPU. The transition from CPU to GPU requires several preparatory steps:
CPU renders each composite layer as a separate image.
Prepare layer data (size, offset, opacity, etc.).
Prepare shaders for animation if needed.
Send data to the GPU.
Each promotion or demotion of a composite layer incurs these costs, which depend on the layer’s size and count.
2.6.2 Layer Explosion
The GPU caches uploaded textures for reuse, but bandwidth between CPU and GPU is limited. Excessive composite layers can become expensive, especially on resource‑constrained devices.
For example, a 320 × 240 px JPEG occupies 320 × 240 × 3 = 230 400 bytes, while a PNG with transparency uses 320 × 240 × 4 = 307 200 bytes.
2.6.3 Managing Composite Layers
DevTools lets you visualize the number and memory usage of composite layers. Open the console, press Shift + Command + P, type “show Layer”, and open the Layer panel.
The left side shows a composite layer; the right side displays its composition reasons and memory usage.
Reduce the number of composite layers.
The most direct method is to lower the layer count, which involves both explicit promotion and implicit composition. Implicit composition occurs when:
If element B (a composited element such as canvas, iframe, or video) overlaps element A, A may be passively promoted to a composite layer. Consider whether this stacking order is appropriate or replace the design.
Reduce the size of composite layers.
Instead of using a large 39 KB image, a small 400 B image can be scaled with transform:scale(...) to achieve the same visual size, reducing memory and bandwidth usage.
3 Reference Documents
CSS GPU Animation: Doing It Right
GPU Accelerated Compositing in Chrome
Browser Rendering Page Workings (MDN)
WEBKIT Rendering: The Four Trees You Must Know
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.
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.
