今天看了一篇文章,有关浏览器的渲染机制,希望自己在下次撸代码的时候运用到相关的知识点。
并不是所有的浏览器都是有渲染机制的,因为起初的浏览器只是呈现一些简单的页面,没有面临现在的各种各样的性能问题,所以还没有这个优化意识。
重绘与重排概念
- 重绘,可以这样想,一个美术生在按照一张画好的艺术照上涂上颜色,即不改变原来的位置和形状,只改变不影响原来艺术照的几何属性就是重绘;站在浏览器的角度就是dom元素的大小(width,height、字体大小等)没有改变,但是呈现的样式发生了改变(如,div的背景颜色从原来的黑色变成了白色)就会发生重绘。
// 发生重绘
var box = document.querySelector('.box');
box.style.backgroundColor = 'red';
- 重排,也叫回流,就是上边的这个美术生把他的女神画成丑八怪了,需要重新排版,重新画;对浏览器来说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】
优化重排或者重绘的性能优化
- 使用类名来将批量操作样式修改
- 使用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);
- 开启GPU渲染,如CSS3中的transform等操作