- 对高频触发的事件进行节流或者防抖 (debounce, throttle)
- js很快但是 dom 很慢,因为浏览器 由HTML/CSS/Javascript等资源呈现出精彩的页面的过程。浏览器在收到HTML文档后会对文档进行解析,开始构建DOM树,进而在文档中发现样式表,开始解析CSS来构建整个CSSOM,这两个都构建完成之后形成Render树。在每次修改DOM或者样式之后都要进行DOM树的创建,CSSOM重新计算,进而得到新的渲染树。浏览器会利用新的渲染树对页面进行重排和重绘。以及图层的合并。通常浏览器会批量的进行重排和重绘以提高性能。
- 优化渲染性能:浏览器通常每秒更新页面一次,每一帧的时间就是16.6ms。每一帧都包含以下步骤1.javascript改变元素样式,添加元素到dom等,2.style:元素的类或者style改变了,这个时候需要重新计算元素的样式。3.layout:元素的大小改变,需要重新计算尺寸。4.paint:绘制元素。5:composite:合并多个元素。
- 将渐变或者动画放到单独的图层,绘制并非在一个单独的画报上进行的,而是多层,因此将那些会变动的元素提升至元素单独的图层,可以让它影响到的元素更少。可以使用css中的 will-change:transform 或者transform:translate(0)这样可以将元素的图层提升到单独的图层中。图层的作用就是为了避免某个元素的变动影响其他的元素。
- 优化js的执行:使用requestAnimationframe来更新页面。我们希望在每一帧刚开始的时候对页面进行更改,目前只有使用这个可以保证。使用settimeout或者setinterval来触发更新页面的函数,该函数可能在一帧的中间或者结束调用,进而导致该帧后面需要进行的事情没有完成,引发丢帧。requestAnimationFrame会将任务安排在页面重绘之前,这保证动画有足够的时间执行js
- 使用transform或者opacity来完成动画,如今只有这两个属性的修改不需要经历layout和paint
- 优化CSS:因为css选择器是由右至左进行的,所以最后一个选择器通常被称为是关键的选择器,因为最后一个选择越特殊,需要进行匹配的次数越小,要千万避免使用*作为关键选择器,因为他能匹配所有元素,倒数第二个还会再和所有元素进行一次匹配,这导致效率很低下。另外first-child这类伪类选择器也不够特殊,也要避免他们成为关键选择器,关键选择性越特殊,性能就越好。
- 合理处理脚本和样式表:js会阻塞页面解析,外部样式表会阻塞页面的呈现和js的执行,通常情况下认为css是阻塞渲染的资源,在css构建完成之前,页面不会被渲染,放在顶部让样式表能够尽早开始加载。但如果把引入样式表的link放到文档底部,页面虽然能够立即呈现,但是页面加载出来是没有样式的,是混乱的。