浏览器的渲染原理

概念:

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

相关推荐
满栀5853 分钟前
插件轮播图制作
开发语言·前端·javascript·jquery
切糕师学AI8 分钟前
Vue 中的计算属性(computed)
前端·javascript·vue.js
程琬清君12 分钟前
Vue3DraggableResizable可移动范围有问题
前端·javascript·vue.js
lkbhua莱克瓦2413 分钟前
CSS盒子模型:网页布局的基石与艺术
前端·css·笔记·javaweb
Curvatureflight14 分钟前
前端性能优化指南:从加载到交互的每一毫秒
前端·性能优化·交互
♩♬♪.16 分钟前
HTML学校官网静态页面
前端·css·html
天天开心a26 分钟前
Vue.js 基础教程笔记(一):Vue入门与环境搭建
前端·javascript·vue.js·笔记·前端框架
weixin_4462608527 分钟前
解锁 React 开发新体验!Puck - 智能可视化编辑器
前端·react.js·编辑器
hzb6666628 分钟前
xd_day28js原生开发-day31 day41asp.net
开发语言·前端·javascript·安全·web安全
tan 9131 分钟前
KaliLinux2025.4 root用户修改显示语言
linux·服务器·前端·安全