前端性能优化提升

前言

本文主要对回流与重绘进行一个简介,并且列举出在实际开发中哪些操作可能会造成回流重绘。如若有问题,请大家多多指教。话不多说,开冲!

回流

当我们对 DOM 的修改引发了 DOM 几何尺寸的变化(比如修改元素的宽、高或隐藏元素等)时,浏览器需要重新计算元素的几何属性(其他元素的几何属性和位置也会因此受到影响),然后再将计算的结果绘制出来。这个过程就是回流(也叫重排),所以回流是产生的最根本原因是dom渲染问题。

重绘

重绘:当我们对 DOM 的修改导致了样式的变化、却并未影响其几何属性(比如修改了颜色或背景色)时,浏览器不需重新计算元素的几何属性、直接为该元素绘制新的样式(跳过了上图所示的回流环节)。这个过程叫做重绘。产生的原因也是因为dom的修改

什么操作会产生回流和重绘?

通过上面的介绍,可以清晰的看出回流和重绘的关系。重绘不一定导致回流,回流一定会导致重绘,如果硬要说二者区别,我想的是,回要做的事情比重绘要做的事情更多,所需要的开销更多。所以在日常开发中,要尽量的吧回流重绘次数降到最低。

回流“导火索”

回流可以说是“牵一发而动全身”
首先,当一个dom元素的几何属性发生变化时,和他相关的所有节点属性(父子节点,兄弟节点)都会放生变化(几何属性),进行重新计算,会带来大量的额计算量。
常见的几何属性有 width、height、padding、margin、left、top、border 等等(常用的基本上就这些,还有其他的也记不住,因为实在是太多了)
其次,获取一些特定的属性,也会造成回流。例如:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight。
因为这些属性进行获取值,是需要实时计算的。因此浏览器为了获取这些东西,也会进行回流操作

重绘“导火索”

相比回流,重绘的导火索就更容易分辨————只要是不触发回流,但又触发了样式改变的 DOM 操作,都会引起重绘,比如背景色、文字色、可见性(可见性这里特指形如visibility: hidden这样不改变元素位置和存在性的、单纯针对可见性的操作,注意与display:none进行区分)等。

如何规避回流与重绘?

实际开发中,我们要尽量的去规避,但是很多时候又不得不用。当无法 避免时,我们就应该去更“聪明”的去使用。
例如:有时我们想要通过多次计算得到一个元素的布局位置,我们就可以将“导火索”缓存起来,避免重复的改动,即:“先循环,再赋值”

// 缓存offsetLeft与offsetTop的值
const el = document.getElementById('el') 
let offLeft = el.offsetLeft, offTop = el.offsetTop

// 在JS层面进行计算
for(let i=0;i<10;i++) {
  offLeft += 10
  offTop  += 10
}

// 一次性将计算结果应用到DOM上
el.style.left = offLeft + "px"
el.style.top = offTop  + "px"

还可以使用一个类名 去合并公共样式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .basic_style {
      width: 100px;
      height: 200px;
      border: 10px solid red;
      color: red;
    }
  </style>
</head>
<body>
  <div id="container"></div>
  <script>
  const container = document.getElementById('container')
  container.classList.add('basic_style')
  </script>
</body>
</html>

还可以进行DOM离线化操作,就是通过display:none.将其从页面上“拿掉”,那么我们的后续操作,将无法触发回流与重绘.虽然拿掉一个元素再把它放回去,也会触发一次昂贵的回流,但我们把它拿下来了,后续不管我操作这个元素多少次,每一步的操作成本都会非常低

小结

之所以考虑dom上的操作,是因为并不是所有浏览器都是聪明的,而我们并不知道用户会使用什么样的浏览器。如果不手动做优化,那么一个页面在不同的环境下就会呈现不同的性能效果。所以养成一个开开发习惯,从根源解决问题,才是最明智的。
(我就是我,全网最菜的前端——痴心。有缘下次更新见。)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值