浏览器的渲染原理

概念:

  1. 渲染:画页面

渲染过程:

  1. 解析html
  2. 生成DOM树(1、2两步同时进行)
  3. 生成渲染树
  4. 重排reflow
  5. 重绘repaint

解析html文件

  1. 文件从哪里拿?本地或服务器上
  2. 从上至下,一行一行读取、解析
  3. 遇到css和js文件,停止解析html(阻塞),进而解析css、js
  4. 遇到图片、音频、视频不会阻塞
  5. css文件放头部,是为了让用户优先看到好看的页面,不会看到空白的、丑陋的页面;js放尾部,是因为用户不着急交互

生成DOM树

  1. html解析完成,立即触发DOMContentLoaded事件
js 复制代码
document.addEventListener("DOMContentLoaded",(event)=>{
  
})

onDOMContentLoaded = (event)=>{}
  1. 所有资源加载完成(包括样式、图片等资源),会触发load事件
js 复制代码
window.addEventListener('load',(event)=>{
  
})
window.onLoad = (event)=>{}

// 也可针对单个资源加载完成触发
let img1 = document.querySelector('#img1')
img.onLoad = (event)=>{
  console.log('图片加载完成')
}

DOMContentLoaded事件和load事件的区别:

**** 触发条件 注册在哪里
DOMContentLoaded事件 html解析完成 document上
load事件 所有资源加载完成(包括图片、样式表) window上

生成渲染树

浏览器一边生成DOM树,一边计算DOM树中每个节点的样式规则,最终形成渲染树

css属性的计算过程,发生在这一步骤。先看声明值,再层叠、再冲突、再使用继承值、再使用默认值

布局layout/重排reflow

这一步浏览器一边生成渲染树,一边计算出每个元素最终的位置和尺寸。位置尺寸包含窗口有多大、滚动条在哪个位置、元素显示在窗口哪个位置。

完成后,页面中所有元素的位置和尺寸就确定下来了,即将被渲染到页面。

为什么叫重排?因为这个步骤会反复执行。

这个步骤会在页面之后的运行中不断的重复,下面的js操作均会导致reflow:

  • 获取元素位置和尺寸
js 复制代码
window.screenLeft
  • 直接或间接改变元素的位置和尺寸
js 复制代码
dom.style.width = '100px'

重排非常耗时,浏览器为了提升性能,做了一些处理,最常见的处理是这样的,对js连续导致reflow的代码,会把reflow的时间延后,看下面的例子:

js 复制代码
dom.style.width = '100px'
dom.style.height = '200px'
dom.style.left = '10px'
dom.style.top = '10px'

每一次改变元素的位置都会导致重排,按理说会导致四次,但是重排非常耗时,这样做没有必要,浏览器会这样做:

代码运行完,页面不变,最后reflow一次

但是,如果在代码中夹杂了读取高度,会导致强行reflow,比如:

js 复制代码
dom.style.width = '100px'
dom.style.height = '200px'
dom.clientHeight; // 读取高度,会导致强行reflow
dom.style.left = '10px'
dom.style.top = '10px'

这段代码会重排两次。

因此:对于我们开发而言,读取宽高、尺寸时,能不频繁读取就不频繁读取。

重绘repaint

浏览器一边reflow,一边生成对应的图形绘制到页面,绘制的过程称为repaint。

为什么叫重绘?还是跟reflow一样,这个步骤会反复执行。

绘制的过程是靠GPU完成的,速度非常快。因此,相对于导致reflow的代码,不触发reflow的代码,仅触发re'paint的代码效率会更高。

比如说,不涉及尺寸和位置的代码,仅影响元素外观的代码都不会导致reflow,仅导致repaint:

  • 改变背景颜色
  • 改变字体颜色
  • 圆角边框
  • 背景图

思考:为什么css3的动画比js动画效率高?

比如:要实现每隔1秒改变元素left值

js 复制代码
setInterval(()=>{
  div.style.left = 'xxx'
},1000)
css 复制代码
div
{
  animation: 3s ease-in 1s infinite reverse both running slidein;
}

用js每一次改变left的值会导致reflow,因为元素的位置变了。但用css3不会导致重排,效率更高

相关推荐
烛阴15 分钟前
开发者神器:如何在浏览器控制台玩转第三方库,让调试效率翻倍!
前端·javascript
crary,记忆24 分钟前
Module Federation 和 Native Federation 的比较
前端·webpack·angular
why技术29 分钟前
翻译翻译,什么叫“编程专用”的显示器?
前端·后端
拉不动的猪1 小时前
JQ常规面试题
前端·javascript·面试
海上彼尚1 小时前
Monorepo + PNPM 搭建高效多项目管理
前端·js·源代码管理
Random_index2 小时前
#Uniapp篇:chrome调试&&unapp适配
前端·chrome·uni-app
Shimeng_19892 小时前
前端如何通过(手机)扫描二维码下载app
前端·javascript·vue.js·二维码·扫描二维码下载软件app
一只一只妖2 小时前
前端导出带有合并单元格的列表
前端
lilye663 小时前
精益数据分析(98/126):电商转化率优化与网站性能的底层逻辑
前端·数据挖掘·数据分析
前端 贾公子3 小时前
《Vuejs设计与实现》第 8 章(挂载与更新)
开发语言·前端·javascript