We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
浏览器内核分为两个部分,一是渲染引擎,二是JS引擎(在《js编译原理》中有记录)
在接受浏览器渲染之前先介绍下页面的加载过程。要点如下:
例如: 在浏览器输入https://juejin.im/timeline,然后经过DNS解析,juejin.im对应的IP是36.248.217.149(不同时间,不同地点对应的IP可能不同)。然后浏览器向该IP发送请求。 服务端接收到HTTP请求,然后经过计算返回请求。通常就是一堆HTML格式的字符串。接下来就是浏览器渲染过程。
浏览器渲染过程大体如下:
渲染树并不是DOM Tree和CSS Tree简单的融合 渲染树只会包括需要显示的节点和这些节点的样式信息,如果某个节点是display:none;那么这个节点就不会在渲染树中显示。 渲染过程中遇到<script> 渲染就会暂停,执行js脚本。这也就是为什么建议将js放在body标签底部,以及不建议将js放在网站首屏的原因。并不是说必须将js放在底部。也可以给<script>标签加defer或者async属性。
<script>
这是因为 JavaScript 不只是可以改 DOM,它还可以更改样式,也就是它可以更改 CSSOM。因为不完整的 CSSOM 是无法使用的,如果 JavaScript 想访问 CSSOM 并更改它,那么在执行 JavaScript 时,必须要能拿到完整的 CSSOM。所以就导致了一个现象,如果浏览器尚未完成 CSSOM 的下载和构建,而我们却想在此时运行脚本,那么浏览器将延迟脚本执行和 DOM 构建,直至其完成 CSSOM 的下载和构建。也就是说,在这种情况下,浏览器会先下载和构建 CSSOM,然后再执行 JavaScript,最后在继续构建 DOM。
当浏览器生成渲染树以后就会根据渲染树进行布局(也叫回流)。这一阶段浏览器要做的事情是要弄清楚各个节点在页面中的确切位置和大小。 布局流程的输出是一个“盒模型”,它会精确地捕获每个元素在视口内的确切位置和尺寸,所有相对测量值都将转换为屏幕上的绝对像素。
<script src="script.js"></script>
没有 defer 或 async,浏览器会立即加载并执行指定的脚本,也就是说不等待后续载入的文档元素,读到就加载并执行。
<script async src="script.js"></script>
async 加载的js可能在 DOMContentLoaded 触发之前或之后执行,但一定在 load 触发之前执行
整个 document 解析完毕且 defer-script 也加载完成之后(这两件事情的顺序无关),会执行所有由 defer script 加载的 JavaScript 代码,然后触发 DOMContentLoaded 事件 总结: async 是无顺序的加载,而 defer 是有顺序的加载
把 DOM 和 JavaScript 各自想象成一个岛屿,它们之间用收费桥梁连接。——《高性能 JavaScript》 DOM属于渲染引擎中的东西,js属于js引擎中的东西,当我们用 JS 去操作 DOM 时,本质上是 JS 引擎和渲染引擎之间进行了“跨界交流”这个“跨界交流”的实现并不简单,它依赖了桥接接口作为“桥梁”(如下图) 过桥是要收费的,所以每访问或者操作一次DOM都要过一次桥,过的次数多了就会引起性能问题。所以建议尽量减少DOM操作,如果必须要访问则增加DOM对象缓存。
渲染的流程基本上是这样(如下图黄色的四个步骤):
注意:上图流程中有很多连接线,这表示了 Javascript 动态修改了 DOM 属性或是 CSS 属性会导致重新 Layout,但有些改变不会重新 Layout,就是上图中那些指到天上的箭头,比如修改后的 CSS rule 没有被匹配到元素。
这里重要要说两个概念,一个是 Reflow,另一个是 Repaint
重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(跳过了上图所示的回流环节)。
回流:当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来,这个过程就是回流(也叫重排)
回流必定会发生重绘,重绘不一定会引发回流。重绘和回流会在我们设置节点样式时频繁出现,同时也会很大程度上影响性能。回流所需的成本比重绘高的多,改变父节点里的子节点很可能会导致父节点的一系列回流。
任何会改变元素几何信息 (元素的位置和尺寸大小) 的操作,都会触发回流,
The text was updated successfully, but these errors were encountered:
No branches or pull requests
浏览器渲染
页面加载过程
浏览器渲染过程
浏览器会解析三个东西
解析完成后,浏览器引擎会通过DOM Tree和CSS Rule Tree来构造Rendering Tree
布局与绘制
async和defer的作用和区别
<script src="script.js"></script>
<script async src="script.js"></script>
(异步下载)为什么操作DOM慢?
你真的了解回流和重绘吗?
The text was updated successfully, but these errors were encountered: