性能检测工具
webpagetest:https://www.webpagetest.org/(测试功能需要*)
lighthouse:npm全局安装,或直接使用chrome devtools的lighthouse
performance: chrome devtools的performance
浏览器的渲染:
浏览器构建Dom对象和构建cssOM对象;
浏览器构建渲染树;
布局(位置、大小);
绘制;
合图层;
浏览器的渲染流程:
1.触发view变化;
2.重新计算样式变化(dom,cssom,render树);
3.布局;
4.绘制(分层绘制,提高效率);
5.合图层;
优化:如果变化不改变布局,可以不经历布局和重绘
影响回流(再次布局)的操作:
- 添加、删除元素;
- 操作styles
- display:none;
- offsetLeft,scrollTop,clientWidth;
- 移动元素的位置;
- 修改浏览器大小,字体大小;
避免layout thrashing:
- 避免回流,比如:避免修改top,bottom位置,使用transform(触发复合图层)
- 读写分离, 比如:将读取元素位置和大小的属性offsetTop,和修改元素位置和大小属性,分离,先批量读,在批量写。
- fastdom可以帮你处理读写分离
优化前(回流):
let cards = document.getElementsByClassName('card') const update=(timestamp) => { for (let index = 0; index < cards.length; index++) { const card = array[index]; card.style.width = ((Math.sin(card.offsetTop + timestamp / 1000) + 1) * 200) + 'px' window.requestAnimationFrame(update) } } window.addEventListener('load', (event) => { update() })
优化后(读写分离,避免了回流):
let cards = document.getElementsByClassName('card') const update=(timestamp) => { for (let index = 0; index < cards.length; index++) { fastdom.measure(()=>{ //读取top const card = cards[index]; const offsetTop = card.offsetTop; fastdom.mutate(()=>{ //写 card.style.width = ((Math.sin(offsetTop + timestamp / 1000) + 1) * 200) + 'px' }) }) } window.requestAnimationFrame(update) } window.addEventListener('load', (event) => { update() })
复合线程
将页面拆分图层进行绘制再进行复合
拆分图层的规则
由浏览器决定
元素之间的相互影响,如果图层对其他图层影响比较多
只影响复合的样式
Position:transform:translate(x,y)
Scale: transform:scale(n)
Rotation: transform: rotate(n)
Opacity: opacity: 0~1
优化: 避免修改产生重绘样式,选择只复合的样式