39:浏览器底层渲染机制3:DOM回流和重绘

DOM的重绘和回流

重绘:元素样式的改变(但宽高、大小、位置等不变)
如 outline, visibility, color、background-color等

回流:元素的大小或者位置发生了变化(当页面布局和几何信息发生变化的时候),触发了重新布局,导致渲染树重新计算布局和渲染

如添加或删除可见的DOM元素 ;
元素的位置发生变化;
元素的尺寸发生变化;
内容发生变化(比如文本变化或图片被另一个不同尺寸的图片所替代);
页面一开始渲染的时候(这个无法避免);
因为回流是根据视口的大小来计算元素的位置和大小的,所以浏览器的窗口尺寸变化也会引发回流.

注意:回流一定会触发重绘,而重绘不一定会回流

前端性能优化之:避免DOM的回流

1.放弃传统操作dom的时代,基于vue/react开始数据影响视图模式 mvvm / mvc / virtual dom / dom diff…

2.分离读写操作 (现代的浏览器都有渲染队列的机制)

offsetTop、offsetLeft、offsetWidth、offsetHeight、clientTop、clientLeft、clientWidth、clientHeight
scrollTop、scrollLeft、scrollWidth、scrollHeight、getComputedStyle、currentStyle…会刷新渲染队列

	//=>渲染队列机制导致引发一次回流(读写分离)
 navBox.style.width = '100px';
 navBox.style.height = '100px';
 console.log(navBox.clientWidth);

	//=>触发两次
navBox.style.width = '100px';
console.log(navBox.clientWidth);
navBox.style.height = '100px';

3.样式集中改变
div.style.cssText = ‘width:20px;height:20px;’
div.className = ‘box’;

4. 缓存布局信息

//运行一次获取一次,回流一次
 div.style.left = div.offsetLeft + 1 + 'px';     
 div.style.top = div.offsetTop + 1 + 'px';
 //=>改为
//获取一次,暂时存放起来,只需要回流一次
var curLeft = div.offsetLeft;   
var curTop = div.offsetTop;
div.style.left = curLeft + 1 + 'px';    
div.style.top = curTop + 1 + 'px';

5.元素批量修改
文档碎片:createDocumentFragment
模板字符串拼接

//=>10次回流
for (let i = 0; i < 10; i++) {
    let span = document.createElement('span');
	navBox.appendChild(span);
	}

//改为  示例一
//创建一个节点
//因为文档片段存在于内存中,并不在DOM树中,所以将子元素插入到文档片段时不会引起页面回流(对元素位置和几何上的计算)。因此,使用文档片段通常会带来更好的性能。
let frag = document.createDocumentFragment();
for (let i = 0; i < 10; i++) {
	let span = document.createElement('span');
		frag.appendChild(span);
	}
	navBox.appendChild(frag); 
	
//示例二 模板拼接
let str = ``;
for (let i = 0; i < 10; i++) {
	str += `<span></span>`;
	 }
navBox.innerHTML = str;

6.动画效果应用到position属性为absolute或fixed的元素上(脱离文档流)
尽量不要用 margin,

7.CSS3硬件加速(GPU加速)
比起考虑如何减少回流重绘,我们更期望的是,根本不要回流重绘;transform \ opacity \ filters … 这些属性会触发硬件加速,不会引发回流和重绘…
可能会引发的坑:过多使用会占用大量内存,性能消耗严重、有时候会导致字体模糊等

8.牺牲平滑度换取速度
每次1像素移动一个动画,但是如果此动画使用了100%的CPU,动画就会看上去是跳动的,因为浏览器正在与更新回流做斗争。每次移动3像素可能看起来平滑度低了,但它不会导致CPU在较慢的机器中抖动

9.避免table布局和使用css的javascript表达式
避免使用table布局,在布局完全建立之前,table需要很多关口,table是可以影响之前已经进入的DOM元素的显示的元素。即使一些小的变化和会导致table中所有其他节点回流。
避免使用css的JavaScript表达式,该规则较过时,但是个好主意。因为每次都需要重新计算文档,或部分文档、回流。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值