乐趣区

关于javascript:前端性能优化二

运行时性能优化

1. 缩小重绘重排

浏览器渲染过程

  1. 解析 HTML 生成 DOM 树;
  2. 解析 CSS 生成 CSSOM 规定树;
  3. 将 DOM 树与 CSSOM 规定树合并在一起生成渲染树;
  4. 遍历渲染树开始布局,计算 DOM 节点的大小和地位;
  5. 调用 GPU 绘制,合成图层;
  6. 将渲染树每个节点绘制到屏幕。

重排

当扭转 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 === '钱七') {

}
// 应用 switch
swith (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)

如果采取 setTimeoutsetInterval来实现动画的话,回调函数将在帧中的某个工夫点来运行,可能刚好在开端,而这可能常常会使咱们失落帧,导致卡顿。

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 这两个属性更改不会触发重排与重绘,他们是能够由合成器独自解决的属性。

退出移动版