前端性能优化-代码优化

JS开销和如何缩短解析时间

代码解决方案

  • Code splitting代码拆分,按需加载
  • Tree shaking代码减重

减少主线程工作量

  • 避免长任务
  • 避免超过1KB的行间脚本
  • 使用rAF(requestAnimationFrame)和rIC(requestIdleCallback)进行时间调度

逐步引导(progressive bootstrapping)

  • 可见不可交互vs最小可交互资源集

配合V8有效优化代码

抽象语法树

  • 源码 => 抽象语法树 => 字节码Bytecode => 机器码
  • 编译过程会进行优化
  • 运行时可能发生反优化

V8优化机制

  • 脚本流
  • 字节码缓存
  • 懒解析

函数优化

  • lazy parsing懒解析vs eager parsing饥饿解析 – (function Fn() {})
  • 利用Optimize.js优化初次加载时间

对象优化

  • 以相同顺序初始化对象成员,避免隐藏类型的调整
class RectArea { // HC0
  constructor(l, w) {
    this.l = l // HC1
    this.w = w // HC2
  }
}

const rect1 = new RectArea(3, 4)
const rect2 = new RectArea(5, 6)

// 隐藏类型无法复用
const car1 = {color: 'red'} // HC0
car1.seats = 4 // HC1
const car2 = {seats: 2} // HC2
car1.color = 'blue' // HC3
  • 实例化后避免添加新属性
const car1 = {color: 'red'} // In-object属性
car1.seats = 4 // Normal/Fast属性,存储property store里,需要通过描述数组间接查找
  • 尽量使用Array代替array-like对象
Array.prototype.forEach.call(arrObj, (value, index) => { // 不如在真实数组上效率高
  console.log(`${index}:${value}`)
})

const arr = Array.prototype.slice.call(arrObj, 0) // 转换的代价比影响优化小
arr.forEach((value, index) => {
  console.log(`${index}:${value}`)
})
  • 避免读取超过数组的长度
function foo(array) {
  for(let i = 0; i <= array.length; i++) { // 越界比较
    if(array[i] > 1000){ // 1、造成undefined跟数字比较 2、沿原型链的查找
      console.log(array[i]) // 业务上无效
    }
  }
}
  • 避免元素类型转换
const array = [3, 2, 1] // PACKED_SMI_ELEMENTS
array.push(4.4) // PACKED_DOUBLE_ELEMENTS

HTML优化

  • 减少iframes使用
  • 压缩空白符
  • 避免节点深层级嵌套
  • 避免table布局
  • 删除注释
  • CSS&JavaScript尽量外链
  • 删除元素默认属性

借助工具

  • html-minifier

CSS优化

  • 降低CSS对渲染的阻塞
  • 利用GPU进行完成动画
  • 使用contain属性
  • 使用font-display属性
(0)
上一篇 2020年9月26日 下午9:15
下一篇 2020年9月26日 下午9:22

相关推荐

发表评论

登录后才能评论