持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
主流程
从浏览器请求html文件,到屏幕上出现渲染的实际像素等,可以分为以下部分:
- 构建DOM Tree
- 构建CSSOM Tree
- 合成Render Tree
- layout 回流:主要涉及到大小、长宽等css属性,计算元素的相对位置
- repaint 重绘:颜色等css属性,显示在屏幕上
细节
解析HTML文件
- 解析DOM元素
- 遇script,DOM解析暂停
- 包含js代码
- 外联:加载js
- 执行js(该js代码在css前,则不受cssom的阻塞)
- 遇link css
- 加载css文件,不阻塞DOM解析
- 遇到script:js加载,等待CSSOM Tree构建完成后再运行
- 防止js代码执行时 获取旧的css属性
- 遇到script:js加载,等待CSSOM Tree构建完成后再运行
- 构建CSSOM Tree,DOM继续解析
- 若有js,则运行
- 构建DOM Tree
- 渲染
DOMContentLoaded事件
在完成DOM解析完成,js执行完毕后触发的事件 大多数浏览器也会等到css文件加载并解析完成后
load事件
所有外部资源与文件下载完毕触发
async defer
关于外联js文件的异步加载:
async:加载不阻塞html的后续解析,加载完成后立即执行,因此有可能执行时,html还未解析完成,不一定顺序执行多个async;
defer:加载不阻塞html的后续解析,加载完成后等到html全部解析完成后再执行,因此有多个defer的js会使顺序执行的。
关于阻塞/非阻塞
- 内联js会阻塞DOM的解析
- 内联css会阻塞DOM解析
- 外联css加载不阻塞DOM解析,阻塞DOM渲染
- 外联css加载阻塞后续script内的js代码执行,不阻塞前面的)
- js文件的普通加载与执行(非async defer)会阻塞DOM的解析
- 因此实际上,后面有script的外联css会阻塞DOM的解析
- defer js不会阻塞DOM的解析
- async js加载不阻塞,执行阻塞
- iframe image等资源不阻塞DOM解析
其他注意点
- DOM Tree增量构建,而CSSOM Tree非渐进