06 优化总结篇
一、页面加载阶段的优化 - 提高反馈性强的资源优先级
第三节聊到的GUI线程渲染过程和第四节结合performance讲解,相信你已经对过程了解的比较清晰了。
在我看来真正影响页面展示的东西是:
- 线程之间来回切换,JS线程和GUI线程的轮番切换异常消耗性能
- JavaScript的执行一直是阻塞页面渲染的
- CSS放头 和 JS放尾 ?
- 懒加载(lazy load 针对图片)
- HTML的第一次渲染的大小(分页滚动加载数据)
(1) 第一点怎么解决?
尽量减少style和script的数量。减少script的数量,解析就尽量的消耗少的线程切换资源和时间;减少style更快加载样式。
(2) 第二点呢?
JavaScript的计算通过事件队列延迟加入,比如setTimeOut,代码是回调自然不会立即执行,JS阻塞不了太长时间,在这轮事件循环中,必定要进行一次渲染,这就使得页面渲染极大的加快。
举个例子:
<body>
<div id="title">第一次渲染</div>
<script>
function long(){
for (var i = 0; i<1000; i++){
for (var j = 0; j<1000; j++){
for (var k = 0; k<10000; k++){
}
}
}
console.log('执行函数完成' )
}
//1. long()
//2. setTimeout(long, 0)
</script>
</body>
- 的话你需要等到long执行完成,继续解析HTML,再paint + idsplay。
- 的话,浏览器执行执行完成,完成渲染,当Main执行这个任务时,切换到JS线程执行long。
虽然两个都会让浏览器页面很长一段时间无法操作,但是一打开至少能看到各种元素DOM,至少比三秒白屏要好的太多。
(3) 很多人说,CSS和JS都会发生阻塞(当然css要在一些情况下)
前提:阻塞DOM Tree和CSSOM不一定真的就阻塞渲染,浏览器已经很智能,当解析HTML发生太长时间了,它会直接停下Parse HTML,反而执行Render Tree构建并进行 paint + display,这也真是它所说的渐进式渲染。
- CSS不会阻塞DOM Tree的构建(这只是对于外联CSS。如果执行到style内联,和内嵌,依旧需要进行一段时间的CSSOM的构建,但是没有线程切换的资源消耗,无关紧要)
- CSS会阻塞渲染?会的,一旦外联CSS加载完成,浏览器就会尽力的去解析CSS(我没有找到证据,但是performance都是这么去做的,仿佛是一个潜规则,当然没有样式的HTML确实丑,如果它真的这么做也可以理解)。因此,其实CSS的资源优先级比较高 => 很多优化都提到CSS应该尽早的加载,放在head里。
- JS阻塞是真的阻塞DOM Tree和渲染,毕竟别人是需要切换线程去执行的,这将导致性能被消耗。JS放在最下面是为了尽量能够渐进式渲染,在渐进式渲染中,没有解析到script就不会执行脚本。不然从总体过程来说,JS的执行是必然的它的位置没有太大影响
二、页面完成之后回调函数代码优化
代码层次的优化分为几个部分:
- 事件任务的频繁出发,任务队列被挤满(节流和防抖)
- 操作DOM、样式
- 内存管理,用户的无效对象太多却无法自动清除
主要讲第二点:操作DOM、样式
核心:减少操作,或者一次性操作,具体的就是
DOM:代码片段DocumentFragment、innerHTML开始JS引擎加速
CSS:样式一次性写入 => cssText、样式连续接入(浏览器对回流和重绘的优化)、操作className写入、缓存读、缓存写、分离读写
PS: 写入(无论是样式还是DOM),并不会迫使浏览器提前layout回流,一定要注意读写DOM和样式的区别。
三、写完这篇,这个番外要停下了
下一篇番外,应该是关于JS的执行,包括变量提升、闭包的解释、上下文执行环境。
感谢陪伴!!!