前端基础:从浏览器渲染原理到性能优化
浏览器渲染流程
当我们输入 URL 到页面呈现在屏幕上,浏览器主要经历以下几个阶段:
1. 解析阶段
浏览器接收到 HTML 字节流后,会经过以下转换:
字节 → 字符 → Token → 节点 → DOM 树
同时,CSS 也会被解析为 CSSOM(CSS Object Model):
// CSSOM 的结构示例
const cssom = {
rules: [
{
selector: 'body',
styles: { fontSize: '16px', color: '#333' }
}
]
};
2. 样式计算
将 DOM 和 CSSOM 合并,生成渲染树(Render Tree):
- 只包含可见元素(
display: none的元素不包含) - 每个节点都有计算后的样式
3. 布局(Layout)
计算每个节点的几何信息:
/* 盒模型决定了元素的布局 */
.box {
width: 200px;
height: 100px;
padding: 16px;
margin: 8px;
/* 实际占用宽度 = 200 + 16*2 + 8*2 = 248px (content-box) */
}
4. 绘制(Paint)
将布局信息转换为屏幕上的像素点。
性能优化策略
关键渲染路径优化
<!-- 内联关键 CSS -->
<style>
.above-the-fold { /* 首屏样式 */ }
</style>
<!-- 异步加载非关键 CSS -->
<link rel="preload" href="non-critical.css" as="style"
onload="this.onload=null;this.rel='stylesheet'">
减少重排(Reflow)
// 不好的写法 - 触发多次重排
element.style.width = '100px';
element.style.height = '100px';
element.style.margin = '10px';
// 好的写法 - 一次重排
element.style.cssText = 'width: 100px; height: 100px; margin: 10px;';
// 或者使用 class
element.classList.add('new-style');
虚拟列表
当列表数据量很大时,使用虚拟列表只渲染可视区域的元素:
// 虚拟列表核心思路
const visibleCount = Math.ceil(viewportHeight / itemHeight);
const startIndex = Math.floor(scrollTop / itemHeight);
const endIndex = startIndex + visibleCount;
// 只渲染 startIndex 到 endIndex 的元素
renderItems(list.slice(startIndex, endIndex));
总结
理解浏览器渲染原理是前端性能优化的基础。记住关键路径:DOM → CSSOM → Render Tree → Layout → Paint,针对性地优化每个环节。