web性能优化1->有关重绘和重排性能优化

312 阅读2分钟

今天看了一篇文章,有关浏览器的渲染机制,希望自己在下次撸代码的时候运用到相关的知识点。

并不是所有的浏览器都是有渲染机制的,因为起初的浏览器只是呈现一些简单的页面,没有面临现在的各种各样的性能问题,所以还没有这个优化意识。

重绘与重排概念

  1. 重绘,可以这样想,一个美术生在按照一张画好的艺术照上涂上颜色,即不改变原来的位置和形状,只改变不影响原来艺术照的几何属性就是重绘;站在浏览器的角度就是dom元素的大小(width,height、字体大小等)没有改变,但是呈现的样式发生了改变(如,div的背景颜色从原来的黑色变成了白色)就会发生重绘。
	// 发生重绘
	var box = document.querySelector('.box');
    box.style.backgroundColor = 'red'; 
  1. 重排,也叫回流,就是上边的这个美术生把他的女神画成丑八怪了,需要重新排版,重新画;对浏览器来说dom元素的几何属性,字体大小发生了改变就叫重排! 常见的重排操作: 页面初始化,添加移除/改变位置/元素尺寸,改变窗口大小都会发生重排操作
	// 发生重排
    var box = document.querySelector('.box');
    box.style.width = 888 + 'px'; // 看,盒子几何属性变化了

传统浏览器和现代浏览器的操作

说下渲染队列吧,其实也简单就是

将各个操作放入队列中,然后批量更新,就好像添加元素的时候先使用documentFragment(文档碎片)先把要添加到页面的dom元素添加进documetFragement中,然后在将documentFragment添加到页面中

  	<div class="box">test</div>
    <script>
      var box = document.querySelector('.box');
      box.style.width = 333 + 'px';
      box.style.height = 333 + 'px';
      box.style.backgroundColor = '#f09';
    </script>
// 你猜猜这个发生了几次重排?

答案揭晓:

传统浏览器发生了两次重排操作,因为没有渲染队列;

现代浏览器发生一次重排,因为有渲染队列,且渲染队列没有被强制刷新 因为有的属性会强制刷新渲染队列,比如offsetX,clientX,scrollX三大家族的操作会强制刷新渲染队列【X代表Top,Left,Width,Height,如offsetTop】

优化重排或者重绘的性能优化

  1. 使用类名来将批量操作样式修改
  2. 使用documentFragment来添加元素,即元素批量操作
  // 这个例子来自于MDN 
  // 地址: https://developer.mozilla.org/zh-CN/docs/Web/API/DocumentFragment
  const list = document.querySelector('#list');
  const fruits = ['Apple', 'Orange', 'Banana', 'Melon'];

  const fragment = document.createDocumentFragment();

  fruits.forEach(fruit => {
    const li = document.createElement('li');
    li.innerHTML = fruit;
    fragment.appendChild(li);
  });

  list.appendChild(fragment);
  1. 开启GPU渲染,如CSS3中的transform等操作