浏览器背后的故事
当服务器提供了资源之后(HTML,CSS,JS,图片等),浏览器会执行下面的操作:
-
解析 —— HTML,CSS,JS
-
渲染 —— 构建 DOM 树 → 渲染 → 布局 → 绘制
页面渲染
-
通过遍历DOM节点树创建一个“Frame 树”或“渲染树”,并计算每个节点的各个CSS样式值
-
通过累加子节点的宽度,该节点的水平内边距(padding)、边框(border)和外边距(margin),自底向上的计算"Frame 树"中每个节点的首选(preferred)宽度
-
通过自顶向下的给每个节点的子节点分配可行宽度,计算每个节点的实际宽度
-
通过应用文字折行、累加子节点的高度和此节点的内边距(padding)、边框(border)和外边距(margin),自底向上的计算每个节点的高度
-
使用上面的计算结果构建每个节点的坐标
-
当存在元素使用
floated,位置有absolutely或relatively属性的时候,会有更多复杂的计算,详见http://dev.w3.org/csswg/css2/ 和 http://www.w3.org/Style/CSS/current-work -
创建layer(层)来表示页面中的哪些部分可以成组的被绘制,而不用被重新栅格化处理。每个帧对象都被分配给一个层
-
页面上的每个层都被分配了纹理(?)
-
每个层的帧对象都会被遍历,计算机执行绘图命令绘制各个层,此过程可能由CPU执行栅格化处理,或者直接通过D2D/SkiaGL在GPU上绘制
-
上面所有步骤都可能利用到最近一次页面渲染时计算出来的各个值,这样可以减少不少计算量
-
计算出各个层的最终位置,一组命令由 Direct3D/OpenGL发出,GPU命令缓冲区清空,命令传至GPU并异步渲染,帧被送到Window Server。