关于渲染原理上一篇已经详细叙述过,现在对渲染中的一些问题进行分析
1. 渲染过程中遇到JS文件怎么处理
- JavaScript的加载、解析和执行都会阻塞文档的解析,也就是说,在构建DOM树时,HTML解析器若是遇到了JavaScript,那么它会暂停文档的解析,将控制权移交给JavaScript引擎,等JavaScript引擎运行完毕,浏览器再从中断的地方恢复继续解析文档。
- 如果想要首屏渲染速度快,就不应该在首屏就加载JS文件,所以建议将script标签放在body底部。
2.async和defer的作用
- defer:表示延迟执行引入的JavaScript,即该JavaScript在加载时,HTML并未停止解析,这两个过程是并行的。当整个document解析完毕后再执行脚本文件,在DOMContentLoaded事件触发之前完成,多个脚本按顺序执行。
- async:表示异步执行引入的JavaScript,加载和渲染后续文档元素的过程会和script.js的加载与执行并行进行(异步)。如果已经加载好就会执行,执行仍然会阻塞文档的解析。
蓝色线代表网络读取,红色线表示执行时间,是针对于脚本的;绿色线代表HTML解析
- defer和async在网络读取(加载)相对于HTML解析都是异步的。
- 脚本没有 defer 或 async,浏览器会立即加载并执行指定的脚本,也就是说不等 待后续载入的文档元素,读到就加载并执行。
<script async src="script.js"></script>
<script defer src="script.js></script>
3. 文档的预解析
- webkit和firefox都做了这个优化,当执行JavaScript脚本时,另一个线程解析剩下的文档,并加载后面需要通过网络加载的资源。这种方式可以使资源并行加载从而使整体速度更快。预解析并不改变DOM树,它将这个工作留给主解析过程,自己只解析外部资源的引用,比如外部脚本、样式表及图片。 4. CSS阻塞文档解析
- 理论上,CSS不改变DOM树,也就没有必要停下文档的解析等待,但是,当JavaScript脚本执行时有可能会在文档的解析过程中请求样式信息,如果样式还没有加载和解析,脚本将得到错误的值。
- 如果浏览器尚未完成CSSOM的下载和构建,而我们却想在此时运行脚本,那么浏览器将延迟JavaScript脚本执行和文档的解析,直至其完成CSSOM的下载和构建。也就是,在这种情况下,浏览器会先下载和构建CSSOM,然后再执行JavaScript,最后再继续文档的解析。 5. 渲染页面时常见的不良现象
- FOUC:主要指样式闪烁的问题,由于浏览器渲染机制(firefox),在CSS加载之前,先呈现了HTML,就会导致展示出无样式内容,然后样式突然呈现的现象。原因是CSS加载时间过长或者CSS被放在了文档的底部。
- 白屏:有些浏览器渲染机制(chrome)要先构建DOM树和CSSOM树,构建完成后才进行渲染,如果CSS部分放在HTML的尾部,由于CSS未加载完成,浏览器迟迟未渲染,从而导致白屏,也可能是因为把js文件放在头部,脚本的加载会阻塞后面文档内容的解析,从而导致页面迟迟未渲染出来,出现白屏问题。 6. 优化关键渲染路径 最大限度减少以下三种可变因素:
- 关键资源的数量。 关键资源是可能阻止网页首次渲染的资源。这些资源越少,浏览器的工作量就越小,对CPU以及其他资源的占用也就越少。
- 关键路径的长度。 关键路径长度受所有关键资源与其字节大小之间依赖关系图的影响,某些资源只能在上一资源处理完毕后才能开始下载,并且资源越大,下载所需的往返次数就越多。
- 关键字节的数量。 浏览器需要下载的关键字节越少,处理内容并让其出现在屏幕上的速度就越快,要减少字节数,可以减少资源数(删除或设为非关键资源),此外还要压缩和优化各项资源,确保最大限度见识传送大小。 7. 重绘和回流
- 重绘:当渲染树中的一些元素需要更新属性,而这些属性只是影响元素的外观、风格,而不会影响布局的操作,比如background color,我们将这样的操作称为重绘。
- 回流:当渲染树中的一部分(或者全部)因为元素的规模尺寸、布局、隐藏等改变而需要重新构建的操作,会影响到布局的操作,我们将这样的操作称为回流。
- 引起回流的属性和方法:任何会改变元素几何信息(元素的位置和尺寸大小)的操作,都会触发回流。 (1) 添加或者删除可见的DOM元素。 (2) 元素尺寸改变——边距、填充、边框、宽度和高度。 (3) 内容变化——用户在input框中输入内容。 (4) 浏览器窗口尺寸变化——resize事件发生时。 (5) 计算offsetWidth和offsetHeight属性。 (6) 设置style属性的值。 (7) 修改网页默认字体。
- 引起重绘的属性和操作 color background-color visibility
- 回流必定会导致重绘,重绘不一定会发生回流。回流所需的成本比重绘高的多,改变父节点里面的子节点很可能会导致父节点的一系列回流。 8. 如何减少回流
(1) 使用transform替代top (2) 不要把节点的属性值放在一个循环里面当成循环里的变量,尽量在DOM树的最顶端改变class (3) 避免使用table布局,可能很小的一个小改动会造成整个table的重新布局 (4) 把DOM离线后修改。 (5) 避免使用CSS表达式(calc) (6) 避免频繁使用documentFragment对象在内存里操作DOM
9. DOM操作缓慢的原因
一些 DOM 的操作或者属性访问可能会引起页面的回流和重绘,从而引起性能上的消耗。