浏览器渲染相关

179 阅读2分钟

浏览器渲染机制

主要过程为:

  1. 解析HTML并构建DOM树
  2. 解析CSS并构建CSSDOM树
  3. 将DOM和CSSDOM合并成渲染(render)树
  4. 根据渲染树布局,计算每个节点的位置
  5. 将各个节点绘制到屏幕上

阻塞机制

CSS

  • style标签会阻塞HTML的解析,直至生成CSSDOM后才会继续解析
  • link标签引入的外部资源,资源下载不会阻塞HTML解析,会阻塞之后的渲染
  • link标签引入的外部资源,资源下载不会阻塞js的加载,会阻塞js的执行(这里的js是同步的)

js

  • js的加载和执行都会阻塞HTML的解析

防阻塞机制

CSS

  • 可以使用媒体类型和媒体查询解除对渲染的阻塞
<link href="index.css" rel="stylesheet">
<link href="print.css" rel="stylesheet" media="print">
<link href="other.css" rel="stylesheet" media="(min-width: 30em) and (orientation: landscape)">

js

defer

  • defer会延迟执行js,使得js加载时不会阻塞HTML的解析
  • defer不会改变script代码的执行顺序
  • defer在HTML解析完成后执行,执行完成后才会触发DOMContentLoaded

async

  • async会异步执行js,如果加载完毕会立即执行。不会按照顺序执行。
  • async可能会在DOMContentLoaded 事件之前或之后执行,但是一定会在load触发之前执行

document.createElement

  • 动态创建的script默认是异步的(async:true),所以不会阻塞页面
  • 动态创建的link标签不会阻塞之后的js的加载和执行

preload 和 prefetch

  • preload 可以强制浏览器请求资源,同时不阻塞文档onload事件
  • prefetch提示浏览器这个资源将来可能需要,但是把决定是否和什么时间加载这个资源的决定权交给浏览器
  • 具体可看:medium.com/reloading/p…

渲染时机

浏览器渲染页面并不一定是解析完HTML之后才会渲染,也可能才解析了一部分。那么它的首次渲染时机是什么?根据上面的分析,总结如下:

  • 若head标签里面有同步的css,那么即使已经生成了DOM,也一定会等待css下载并执行完之后才会开始渲染
  • 若head标签里面有同步的js,那么会直接阻塞,等待它下载执行完后才会向后执行
  • 若script标签在body里面,若正在下载资源,此时HTML解析被阻塞,并且满足上面的两个条件,并且js引擎线程也空闲,则会进行渲染。