- Goal:
- See with my own eyes a page rendering experience: JS → Layout → Paint → Composite
1. Prepare a demo that “must produce results”
First create the simplest HTML (just open it locally):
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<title>Render Demo</title>
<style>
.box {
width: 100px;
height: 100px;
background: red;
margin: 20px;
transition: transform 0.5s;
}
</style>
</head>
<body>
<button id="btn">Move</button>
<div class="box" id="box"></div>
<script>
const box = document.getElementById('box')
document.getElementById('btn').onclick = () => {
// Dirty layout before reading geometry to demonstrate a forced flush.
box.style.width = '120px';
console.log(box.offsetWidth)
// Subsequent transform animation can reuse layers.
box.style.transform = 'translateX(200px)'
}
</script>
</body>
</html>This example intentionally contains:
- One time forced reflow
- Once Only the animation of the composite layer
2. Open the Performance panel (core tool)
open page
F12/Cmd + Option + ICut to Performance
Check:
- ✅ Screenshots
- ✅ Web vitals (optional)
3. Record a rendering process
1️⃣ Click Record (●)
2️⃣ Click Move on the page
3️⃣ Wait for the animation to end
4️⃣ Click Stop (■)
What you are seeing now is the browser The most realistic internal execution trace
4. Understand the Performance Timeline (Key Points)
1️⃣ Overview area (top)
You will see several color bars:
| Color | Meaning |
|---|---|
| 🟨 Yellow | JS execution |
| 🟪 Purple | Style / Layout |
| 🟩 Green | Paint |
| 🟦 Blue | Composite |
📌 Target State: The animation phase is almost only 🟦
2️⃣ Main thread (the most important)
Expand Main:
Task
├── Event: click
│ ├── Function Call
│ │ ├── offsetWidth ← 强制回流
│ │ ├── set style
│ ├── Layout
│ ├── Paint
└── Composite LayersYou will clearly see:
👉 read offsetWidth → The browser is forced to execute Layout → Subsequent transforms no longer trigger layout
🔥Key knowledge points (very important)
Why does offsetWidth trigger Layout?
Because inside the browser is Lazy calculation of layout :
- Change the style: Account first
- Reading layout information: must be counted once
This is the root of Layout Thrashing
5. Verification: Does the transform really have no reflow?
Open the Rendering panel
DevTools →
More tools→RenderingCheck:
- ✅ Paint flashing
- ✅ Layer borders
Click the button again
You will see:
- Box Flash Blue Border (composition layer)
- NO GREEN FLASH (NO REDRAW)
✔️ Proof only happens with Composite
6. Comparative experiment (very critical)
Change JS to:
box.style.left = '200px'And add:
.box {
position: relative;
}Re-record the Performance.
You will see:
Each frame has:
- Layout
- Paint
Significant drop in FPS
👉 This is why animations use transform
7. Use FPS Meter to check fluency
- Rendering panel
- Check FPS meter
Comparison:
leftAnimation: FPS fluctuates greatlytransform: measure actual frame rate; a stable 60 FPS is not guaranteed on every device.
8. Summary
- A complete browser rendering process is:
- After the DOM and CSSOM are built, the Render Tree is generated.
- Then perform Layout to calculate geometric information,
- Then Paint draws the pixels,
- Finally, the GPU performs Composite synthesis.
- In the Performance panel of DevTools, you can see
- Execution time of JS, Layout, Paint, and Composite,
- Transforms and opacity can reduce Layout/Paint for reusable layers with unchanged content; confirm with a trace.