浏览器渲染原理 —— 网页是如何显示出来的
写了这么久代码,我一直很好奇:浏览器拿到 HTML 文件后,到底是怎么把它变成我们看到的网页的?带着这个疑问,我去了解了浏览器的渲染流程。
简单来说分这么几步:首先解析 HTML 生成 DOM 树,同时解析 CSS 生成 CSSOM 树;然后把 DOM 树和 CSSOM 树结合,生成渲染树(Render Tree);接下来进行布局(Layout),计算每个元素在页面上的位置和大小;最后进行绘制(Paint),把像素画到屏幕上。
了解这个过程之后,很多之前的疑惑都解开了。比如为什么建议把 CSS 放在头部、JS 放在底部?因为 JS 执行会阻塞 DOM 解析,而 CSS 虽然不阻塞 DOM 解析,但会阻塞渲染,放在头部能避免页面闪烁。
还有重排和重绘。修改元素的几何属性会触发重排,修改颜色、背景这类属性会触发重绘。重排成本比重绘高得多,所以优化性能的一个重要方向就是减少重排次数。
javascript
运行
// ❌ 不好的写法:多次修改样式,多次重排
const box = document.querySelector('.box');
box.style.width = '100px';
box.style.height = '200px';
box.style.marginLeft = '10px';
// ✅ 好的写法:通过class批量修改,只触发一次重排
box.classList.add('new-style');
还有批量修改 DOM 时,可以先让元素脱离文档流,修改完再放回去:
javascript
运行
const list = document.querySelector('ul');
list.style.display = 'none'; // 脱离文档流
// 批量添加li
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = i;
list.appendChild(li);
}
list.style.display = 'block'; // 放回文档流
知其然更要知其所以然。理解了浏览器渲染原理,写代码的时候就会下意识地考虑性能问题,而不只是实现功能就行。
浙公网安备 33010602011771号