浏览器的渲染原理

概念:

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

相关推荐
天天向上的鹿茸12 分钟前
前端适配方案
前端·javascript
We་ct31 分钟前
LeetCode 226. 翻转二叉树:两种解法(递归+迭代)详解
前端·算法·leetcode·链表·typescript
哆啦A梦158836 分钟前
Vue3魔法手册 作者 张天禹 013_pinia
前端·vue.js·typescript
哆啦A梦158839 分钟前
Vue3魔法手册 作者 张天禹 014_组件通信
前端·vue.js·typescript
木斯佳42 分钟前
前端八股文面经大全:有赞前端一面二面HR面(2026-1-13)·面经深度解析
前端·状态模式
码云数智-园园1 小时前
Vue 3 + TypeScript 企业级项目架构实战:从0到1打造可维护的前端工程体系
前端·vue.js·typescript
CappuccinoRose1 小时前
CSS 语法学习文档(十五)
前端·学习·重构·渲染·浏览器
Marshall1511 小时前
DC-SDK 实战指南:基于 Cesium 的三维数字孪生大屏开发 前言 在当今数字孪生、智慧城市等领域的开发中,三维地图可视化已经成为核心需求。
前端
少云清2 小时前
【UI自动化测试】5_web自动化测试 _元素操作和元素信息获取
前端·web自动化测试
lyyl啊辉3 小时前
2. Vue数据双向绑定
前端·vue.js