运行时性能优化
1.缩小重绘重排
浏览器渲染过程
- 解析HTML生成DOM树;
- 解析CSS生成CSSOM规定树;
- 将DOM树与CSSOM规定树合并在一起生成渲染树;
- 遍历渲染树开始布局,计算DOM节点的大小和地位;
- 调用GPU绘制,合成图层;
- 将渲染树每个节点绘制到屏幕。
重排
当扭转DOM元素地位或大小时,会导致浏览器从新生成渲染树,这个过程叫重排。
重绘
当从新生成渲染树render tree后,就要将渲染树每个节点绘制到屏幕,这个过程叫重绘。不是所有动作都会导致重排,例如扭转字体色彩,只会导致重绘。重排会导致重绘,重绘不会导致重排。
重排和重绘这两个操作都是十分低廉的,因为Javascript引擎线程与GUI渲染线程是互斥的,它们同时只能一个在工作。
什么操作会导致重排
- 增加或删除DOM元素
- 扭转元素的地位
- 扭转元素的大小
- 元素内容的扭转
- 浏览器窗口尺寸的扭转
如何缩小重绘重排
- 用js批改款式时,用class来批改,而不是间接用js来批改款式;
- 如果要对 DOM 元素执行一系列操作,能够将 DOM 元素脱离文档流,批改实现后,再将它带回文档。举荐应用暗藏元素(display:none)或文档碎片(DocumentFragement),都能很好的实现这个计划。
2.应用事件委托
事件委托利用了事件冒泡的原理,只制订一个事件处理程序,就能够治理某一类型的所有事件。少数鼠标事件和键盘事件都适合采纳事件委托技术,应用事件委托能够节俭内存。
// good 应用事件委托const ul = document.querySelector('ul') ul.onclick = (e) => { const target = e.target if (target.nodeName === 'LI') { console.log(target.innerText) } } // bad 没有应用事件委托,事件间接绑定在li上document.querySelector('li').forEach((e) => { e.target.onclick = function () { console.log(this.innerText) }})
3.if-else 比照 switch
if (name === '张三') {} else if (name === '李四') {} else if (name === '王五') {} else if (name === '赵六') {} else if (name === '钱七') {}// 应用switchswith (name) { case '张三': break case '李四': break case '王五': break case '赵六': break case '钱七': break}
以上这种状况,应用switch比拟好。假如name值为钱七,if-else要通过5次判断,而switch只须要进行一次。
4.查找字典表
持续下面的例子,当条件语句特地多时,应用if-else和switch都不是最佳抉择,这时能够用字典表:
const map = { '张三': result1, '李四': result2, '王五': result2, '赵六': result2, '钱七': result2,}return map[name]
5.应用requestAnimationFrame来实现视觉变动
咱们晓得,大多数设施屏幕的刷新率为60次/秒,也就是说每一帧的均匀工夫为16.6毫秒。在应用Javascript实现动画成果的时候,最好的状况就是每次代码都在帧的结尾开始执行。而保障Javascript在帧开始运行的惟一形式是应用requestAnimationFrame
。
function undateScreen() { // 设置动画 ...}window.requestAnimationFrame(undateScreen)
如果采取setTimeout
或setInterval
来实现动画的话,回调函数将在帧中的某个工夫点来运行,可能刚好在开端,而这可能常常会使咱们失落帧,导致卡顿。
6.应用位操作
位操作比其余数学运算和布尔操作快得多。
取整
~~5.34 // 5~~'5.34' // 5~~undefined // 0~~null // 0
7.不要笼罩原生办法
无论你的 JavaScript 代码如何优化,都比不上原生办法。因为原生办法是用 C/C++ 写的,并且被编译成机器码,成为浏览器的一部分。当原生办法可用时,尽量应用它们,特地是数学运算和 DOM 操作。
8.升高CSS选择器的复杂性
- 浏览器读取CSS选择器,遵循的准则是从选择器的左边到右边读取。
#app .wrap div { color: white;}
1、查找所有div元素
2、查找后果1中的元素是否有类名为 wrap 的父元素
3、查找后果2中的元素是否有id为app的父元素
所以,能够得出结论:
1、选择器越短越好
2、尽量应用高优先级选择器
3、防止应用通配符 *
9.应用flex布局
flex布局要比晚期的浮动、绝对定位和相对定位布局性能要好。
10.应用transfrom和opacity属性更改来实现动画
在CSS中,transform和opacity这两个属性更改不会触发重排与重绘,他们是能够由合成器独自解决的属性。