html+css+js解析全过程

528 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

主流程

从浏览器请求html文件,到屏幕上出现渲染的实际像素等,可以分为以下部分:

  1. 构建DOM Tree
  2. 构建CSSOM Tree
  3. 合成Render Tree
  4. layout 回流:主要涉及到大小、长宽等css属性,计算元素的相对位置
  5. repaint 重绘:颜色等css属性,显示在屏幕上

细节

解析HTML文件

  1. 解析DOM元素
  2. 遇script,DOM解析暂停
    • 包含js代码
    • 外联:加载js
  3. 执行js(该js代码在css前,则不受cssom的阻塞)
  4. 遇link css
  5. 加载css文件,不阻塞DOM解析
    • 遇到script:js加载,等待CSSOM Tree构建完成后再运行
      • 防止js代码执行时 获取旧的css属性
  6. 构建CSSOM Tree,DOM继续解析
  7. 若有js,则运行
  8. 构建DOM Tree
  9. 渲染

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非渐进