Open tomoya06 opened 4 years ago
如果 DOM 或 CSSOM 被修改,以上过程需要重复执行,这样才能计算出哪些像素需要在屏幕上进行重新渲染。
浏览器渲染进程是多线程模型,主要包含了如下一些线程类型:
GUI渲染线程和JS引擎线程是互斥的,当JS引擎线程执行时,GUI渲染线程会被挂起。
参考这篇博客
参考自己实现代码 另外有看到document.onload事件,测试时发现这个方法已经失效。参考栈溢出网友的回答,window.onload在整个页面加载完成时触发,document.onload在DOM树构建好的时候触发。不过现在的浏览器都默认用window.onload直接替代document.onload事件。
document.onload
<script>
defer和async可以改变script标签阻塞的情况。
首先,注意 async 与 defer 属性对于 inline-script 都是无效的,还是会按顺序执行。主要看带src属性的script标签。
<script defer src="script.js"></script>
defer 表示延迟执行。与相比普通 script,有两点区别:
整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer-script 加载的 JavaScript 代码,然后再触发 DOMContentLoaded 事件。
<script async src="script.js"></script>
async 表示同步执行。如果已经加载好,就会开始执行,注意这种方式加载的 JavaScript 依然会阻塞 load 事件。
使用 document.createElement 创建的 script 默认是异步的,不会阻塞。
一般来说,可以把普通文档流看成一个图层。特定的属性可以生成一个新的图层。不同的图层渲染互不影响,所以对于某些频繁需要渲染的建议单独生成一个新图层,提高性能。
通过以下几个常用属性可以生成新图层
重绘和回流是渲染步骤中的一小节,但是这两个步骤对于性能影响很大。
回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列回流。
渲染机制
渲染过程
如果 DOM 或 CSSOM 被修改,以上过程需要重复执行,这样才能计算出哪些像素需要在屏幕上进行重新渲染。
多线程
浏览器渲染进程是多线程模型,主要包含了如下一些线程类型:
GUI渲染线程和JS引擎线程是互斥的,当JS引擎线程执行时,GUI渲染线程会被挂起。
加载完成事件
事件触发流程
阻塞环节
<script>
标签应靠后改变script阻塞
defer和async可以改变script标签阻塞的情况。
首先,注意 async 与 defer 属性对于 inline-script 都是无效的,还是会按顺序执行。主要看带src属性的script标签。
defer
<script defer src="script.js"></script>
defer 表示延迟执行。与相比普通 script,有两点区别:
整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer-script 加载的 JavaScript 代码,然后再触发 DOMContentLoaded 事件。
async
<script async src="script.js"></script>
async 表示同步执行。如果已经加载好,就会开始执行,注意这种方式加载的 JavaScript 依然会阻塞 load 事件。
动态创建sciprt标签
使用 document.createElement 创建的 script 默认是异步的,不会阻塞。
图层
一般来说,可以把普通文档流看成一个图层。特定的属性可以生成一个新的图层。不同的图层渲染互不影响,所以对于某些频繁需要渲染的建议单独生成一个新图层,提高性能。
通过以下几个常用属性可以生成新图层
重绘(Repaint)和回流(Reflow)
重绘和回流是渲染步骤中的一小节,但是这两个步骤对于性能影响很大。
回流必定会发生重绘,重绘不一定会引发回流。回流所需的成本比重绘高的多,改变深层次的节点很可能导致父节点的一系列回流。
引起重绘的属性和方法
引起回流的属性和方法
如何减少回流重绘