浏览器

浏览器如何渲染UI?

  1. 浏览器获取HTML文件,然后对文件进行解析,形成DOM Tree

  2. 与此同时,进行CSS解析,生成Style Rules

  3. 接着将DOM Tree与Style Rules合成为 Render Tree

  4. 接着进入布局(Layout)阶段,也就是为每个节点分配一个应出现在屏幕上的确切坐标

  5. 随后调用GPU进行绘制(Paint),遍历Render Tree的节点,并将元素呈现出来

浏览器如何解析CSS?

浏览器会『从右往左』解析CSS选择器。

DOM Tree与Style Rules合成为 Render Tree,实际上是需要将Style Rules附着到DOM Tree上,因此需要根据选择器提供的信息对DOM Tree进行遍历,才能将样式附着到对应的DOM元素上。

.mod-nav h3 span {font-size: 16px;}

从右至左的匹配过程是:

  1. 先找到所有的最右节点 span,对于每一个 span,向上寻找节点 h3

  2. 由 h3再向上寻找 class=mod-nav 的节点

  3. 最后找到根元素 html 则结束这个分支的遍历。

DOM Tree是如何构建的?

  1. 转码: 浏览器将接收到的二进制数据按照指定编码格式转化为HTML字符串

  2. 生成Tokens: 之后开始parser,浏览器会将HTML字符串解析成Tokens

  3. 构建Nodes: 对Node添加特定的属性,通过指针确定 Node 的父、子、兄弟关系和所属 treeScope

  4. 生成DOM Tree: 通过node包含的指针确定的关系构建出DOM Tree

浏览器重绘与重排的区别?

  • 重排: 部分渲染树(或者整个渲染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素

  • 重绘: 由于节点的几何属性发生改变或者由于样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变

单单改变元素的外观,肯定不会引起网页重新生成布局,但当浏览器完成重排之后,将会重新绘制受到此次重排影响的部分

重排和重绘代价是高昂的,它们会破坏用户体验,并且让UI展示非常迟缓,而相比之下重排的性能影响更大,在两者无法避免的情况下,一般我们宁可选择代价更小的重绘。

如何触发重排和重绘?

任何改变用来构建渲染树的信息都会导致一次重排或重绘:

  • 添加、删除、更新DOM节点

  • 通过display: none隐藏一个DOM节点-触发重排和重绘

  • 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化

  • 移动或者给页面中的DOM节点添加动画

  • 添加一个样式表,调整样式属性

  • 用户行为,例如调整窗口大小,改变字号,或者滚动。

  • 查询某些属性或调用某些方法。比如说:

    offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight

如何避免重绘或者重排?

  1. 集中改变样式

  2. 使用DocumentFragment

  3. 提升为合成层

最后更新于