打开浏览器,输入一个网址,页面唰一下就出来了。这个过程看起来简单,背后其实有一套复杂的机制在跑——网页渲染引擎就是那个幕后操盘手。
从URL到像素:第一步是解析
当你敲下回车,浏览器先向服务器请求HTML文件。拿到内容后,渲染引擎开始干活。它先把原始的HTML文本转换成一种叫DOM(文档对象模型)的数据结构。你可以把DOM想象成一棵树,每个标签都是一个节点,比如<html>是根节点,下面连着<head>和<body>。
与此同时,CSS文件也被下载并解析成CSSOM,也就是样式规则的树状结构。这一步很重要,因为光有结构不知道长啥样也不行。
合并规则,生成布局树
DOM和CSSOM各自建好后,渲染引擎会把它们合并起来,生成一个“渲染树”。这个树只包含真正要显示的元素,像那些被display: none;隐藏的节点,直接被踢出去了。
有了渲染树,引擎就知道哪些元素该画、长什么样。接下来进入布局阶段,也叫重排(reflow)。它会计算每个元素在屏幕上的位置和大小,比如这个div宽多少、离顶部多远。这一步的结果是一张详细的“施工图”。
绘制与合成:把数据变成画面
施工图画好了,就开始“画”。渲染引擎把每个元素拆成一个个图层,然后交给GPU去 rasterize(光栅化),也就是把矢量描述转成像素点阵。你看到的文字、边框、阴影,都是这么一格一格填出来的。
现代浏览器为了提升效率,会对复杂动画或滚动区域单独分层。比如一个固定定位的导航栏,可能自己占一层,不动的时候不用重复绘制,滑动时只需移动图层位置,省时省力。
JavaScript是怎么插队的
很多人不知道,JS脚本会阻塞渲染。默认情况下,浏览器遇到<script>标签就会停下来,先执行脚本。如果这段JS还去改DOM或样式,前面辛辛苦苦建好的结构可能又要重新来一遍。
<script>
document.body.style.background = '#f00';
</script>
这种操作会让浏览器被迫重新计算样式和布局,俗称“强制重排”,卡顿往往就这么来的。所以建议把脚本放在body底部,或者加async、defer属性,让加载不耽误页面展示。
实际体验中的影响
你有没有遇到过页面加载一半突然乱跳?多半是后面加载的资源改变了布局。比如图片没设尺寸,等图下来才发现占地方比预想的大,下面的内容全被顶下去了。提前给img设置宽高,或者用容器预留空间,能有效避免这种“页面抖动”。
再比如,用transform做动画比直接改left/top性能好得多。因为transform属于合成阶段的操作,不触发重排,GPU直接处理,丝般顺滑。