浏览器的渲染原理

概念:

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

相关推荐
xkxnq10 小时前
第二阶段:Vue 组件化开发(第 16天)
前端·javascript·vue.js
烛阴10 小时前
拒绝配置地狱!5 分钟搭建 Three.js + Parcel 完美开发环境
前端·webgl·three.js
xkxnq11 小时前
第一阶段:Vue 基础入门(第 15天)
前端·javascript·vue.js
anyup12 小时前
2026第一站:分享我在高德大赛现场学到的技术、产品与心得
前端·架构·harmonyos
BBBBBAAAAAi12 小时前
Claude Code安装记录
开发语言·前端·javascript
xiaolyuh12312 小时前
【XXL-JOB】 GLUE模式 底层实现原理
java·开发语言·前端·python·xxl-job
源码获取_wx:Fegn089512 小时前
基于 vue智慧养老院系统
开发语言·前端·javascript·vue.js·spring boot·后端·课程设计
毕设十刻12 小时前
基于Vue的人事管理系统67zzz(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
anyup12 小时前
从赛场到产品:分享我在高德大赛现场学到的技术、产品与心得
前端·harmonyos·产品
前端工作日常13 小时前
我学习到的A2UI的功能:纯粹的UI生成
前端