浏览器的渲染原理

概念:

  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不会导致重排,效率更高

相关推荐
Juchecar几秒前
AI教你常识之 npm / pnpm / package.json
前端
薛定谔的猫27 分钟前
前端工程化系列(一):编码规范相关
前端·代码规范·前端工程化
ZKshun10 分钟前
[ 前端性能优化 - 图片压缩 ] WebP格式的的图片性能到底有多优秀?
前端
杜蒙14 分钟前
React Hooks 详解
前端·javascript
南囝coding14 分钟前
Claude Code 从入门到精通:最全配置指南和工具推荐
前端·后端
索马里亚纳海参炒贩15 分钟前
useCallback useMemo memo 三个区别和作用
前端·react native
非ban必选26 分钟前
netty-scoket.io路径配置
java·服务器·前端
じòぴé南冸じょうげん1 小时前
小程序的project.private.config.json是无依赖文件,那可以删除吗?
前端·小程序·json
会豪1 小时前
Electron主进程渲染进程如何优雅的进行通信
前端
jianghaha20111 小时前
前端 Word 模板参入特定数据 并且下载
前端·word