Hello~大家好,这是我学习浏览器渲染机制时做的笔记,由于本人水平有限,所以在参考文章对于看不懂的便暂时没有作笔记下来,参考文章:
CSDN咨询云计算--有关网页渲染,每个前端开发者都该知道的那点事
浏览器如何进行渲染
- 处理html生成Dom(Document Object Model) Tree
- 处理css生成CSSOM(CSS Object Model) Tree
- 在文档对象模型和CSS对象模型之上,创建一棵由一组待生成渲染的对象组成的渲染树,即Render Tree
- 对Render树进行布局计算,即对渲染树上的每个元素,计算它的坐标,称之为布局。
- 绘制即Painting,渲染树上的元素最终展示在浏览器里
性能优化
(简单了解完浏览器渲染机制,我们可以据此进行性能优化)
首先了解一下重绘和重排
- Repaint****重绘 当改变那些不会影响元素在网页中的位置的元素样式时,譬如background-color(背景色), border-color(边框色), visibility(可见性),浏览器只会用新的样式将元素重绘一次(这就是重绘,或者说重新构造样式),此时布局没有发生改变。
- Reflow重排 当DOM变化影响了元素的几何属性(宽、高改变等等)
浏览器此时需要重新计算元素几何属性
并且页面中其他元素的几何属性可能会受影响
这样渲染树就发生了改变,也就是重新构造RenderTree渲染树
触发重排的情况
- 页面初始渲染
- DOM操作(元素添加、删除、修改或者元素顺序的改变)
- 改变元素位置,改变元素尺寸(宽、高、内外边距、边框等),改变元素内容(文本或图片等)
- 浏览器窗口的操作(缩放,滚动)
- 添加或删除样式表
- 更改“类”的属性
- 伪类激活(悬停)
优化来啦
- 渲染队列
div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
如上,我们改变元素属性会触发重排,理论上会触发四次重排,而实际上它只会进行一次重排,这是因为我们现代的浏览器都有渲染队列的机制 ,当我改变了元素的一个样式会导致浏览器发生重排或重绘时,它会进入一个渲染队列,然后浏览器继续往下看,如果下面还有样式修改,同样入列,直到下面没有样式修改,浏览器会按照渲染队列批量执行来优化重排过程,一并修改样式 。
如果我们现在想修改样式后在后台打印
div.style.left = '10px';
console.log(div.offsetLeft);
div.style.top = '10px';
console.log(div.offsetTop);
div.style.width = '20px';
console.log(div.offsetWidth);
div.style.height = '20px';
console.log(div.offsetHeight);
此时则会发生四次重排,而原因则是因为offsetLeft/Top/Width/Height
事实上,以下属性或方法会刷新渲染队列:
- offsetTop、offsetLeft、offsetWidth、offsetHeight
- clientTop、clientLeft、clientWidth、clientHeight
- scrollTop、scrollLeft、scrollWidth、scrollHeight
- getComputedStyle()(IE中currentStyle)
我们修改为
div.style.left = '10px';
div.style.top = '10px';
div.style.width = '20px';
div.style.height = '20px';
console.log(div.offsetLeft);
console.log(div.offsetTop);
console.log(div.offsetWidth);
console.log(div.offsetHeight);
则优化为一次重排了
- 减少http请求的次数,根据功能和数据加载流程合并相应的js,css,images 减少其请求的次数
- 减少带宽,压缩对应的文件去掉一些空格,注释提高相应速度
- 把样式表放在头部?
- 脚本代码引用加在<body>元素页面内容的后面,这样在解析脚本之前,页面的内容将完全呈现在浏览器中,用户会因为显示空白时间缩短而感觉打开页面速度加快
- 将JavaScript和CSS存放到外部文件中,可以有效地将js, css文档缓存到本地,当你请求同样包含以上js, css的脚本的时候,便无需重新下载,直接从缓存中载入了。此外,它还有一个很明显的优点,就是增强了可重用性,你不必在每个页面都重复地写上一大串的代码,造成资源和带宽的浪费。
-
尽量简化和优化CSS选择器,将嵌套程度保持在最低水平。
以下是CSS选择器的性能排名(从最快者开始):
- 识别器:#id
- 类:.class
- 标签
- 相邻兄弟选择器:a + i
- 父类选择器:ul> li
- 通用选择器:*
- 属性选择:input[type="text"]
- 伪类和伪元素:a:hover
浏览器在处理选择器时依照从右到左的原则,因此最右端的选择器应该是最快的:#id或则.class:
div * {...} // bad
.list li {...} // bad
.list-item {...} // good
#list .list-item {...} // good
- 尽量只给位置绝对或者固定的元素添加动画效果
Author:YY
Date:2017.7.10
网友评论