携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情 >>
浏览器获取到 html 资源后开始解析 html (dom tree) -> 构建 DOM 树
解析到 css 后根据 css 生成 css 规则树 (style rules) -> 产生 CSS 规则树
在 dom 树和 css 规则树都生成完后,
通过 dom 树和 css 规则树生成渲染树( render tree ) -> 构建 render 树
渲染树构建完成后,浏览器开始计算元素的大小和位置( layout ) -> 布局 render 树
根据计算好的节点信息将内容绘制到屏幕上( painting ) -> 绘制 render 树
详细过程
-
dom 树和 css 规则树的先后顺序
浏览器获取的 html 资源后自上而下开始解析,生成 dom 树;如果遇到 style 的内联样式和 link 会将 css 交由 css 渲染器构建 css 规则树; 其中加载 link 引入的外部样式文件是异步加载的,并且整个 css 规则树也是与 dom 树的构建是并行的;
-
Javascript脚本的加载
由于 js 可以操作 dom,所以在 html 解析到 Javascript 脚本时会停止对 dom 的解析;而 css 的解析会阻塞 js 的执行,所以在某些情况下 css 的解析会导致 dom 的解析;
script的defer 属性
- 给 script 标签添加 defer 属性,适用于 js 中涉及到 dom 的操作,或者与其他的 js 有相互引用的关系 添加 defer 属性会将 Javascript 脚本延迟执行,但是 html 解析过程中遇到 script 标签仍然会进行下载
- defer 脚本会在 dom 解析完成后,DOMContentLoaded事件调用前执行,而且 defer 属性的 js 脚本会按照顺序执行,即在 dom 解析完成后会依次执行 script标签
script的async属性
- 给 script 标签添加 async 属性,适用于 js 与 dom 和其他 js 文件无关的情况
- 添加 defer 属性会将 Javascript 脚本异步执行,html 解析过程中遇到 script 标签会进行下载,且下载完成后立即进行异步执行
- 由于是异步执行,所以当有多个异步的 js 脚本时无法控制先后执行的顺序,所以有多个异步 js 时,这些 js 不要互相有引用
- 由于添加 async 属性,使 js 在下载完成后立即执行,所以为了在该 js 中不要进行 dom 的相关操作
-
渲染树( render tree )的构建过程
- 从 dom 树的根节点开始遍历每一个可见的节点;例如引用 css 文件的 link 标签、引入js 文件的 script 标签和 css 属性设置了 display: none; 的节点
- 从 css 规则树 (style rules) 中找到对应的节点,然后根据节点信息和样式组合成渲染树( render tree )