3

js性能优化相关内容笔记整理

 2 years ago
source link: https://segmentfault.com/a/1190000041180657
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

js性能优化相关内容笔记整理

1. 引用计数

核心思想:设置引用数,判断当前引用是否为0

  1. 发现垃圾时,立即回收
  2. 最大限度减少程序暂停
  1. 无法回收循环引用的对象
  2. 时间开销大(需要监听计数值的变化)
function fn() {
    const obj1 = {}
    const obj2 = {}
}

2. 标记清除

核心思想:分标记和清除两个阶段

缺点:
1、 空间碎片化(回收对象在地址上的不连续)
2、 不能立即回收

3. 标记整理

标记,然后将活动对象的地址进行整理,尽量使得活动对象地址连续

4. 分代回收

回收新生代对象(存活时间较短的变量对象)
  • 回收过程采用复制算法+标记整理
  • 新生代内存区分为两个等大小的空间
  • 使用空间为From,用于存储活动对象, 空闲空间为To,用于存储From中的活动对象
  • 活动对象存储于From空间
  • 标记整理后将活动对象拷贝至To
  • From 与To交换空间完成释放

回收细节:From和To之间的拷贝过程可能出现晋升(将新生代对象移动至老生代)下面两种情况会产生晋升

  • 一轮GC后还存活的新生代需要晋升
  • To空间的使用率超过了25%
回收老生代对象

空间大,无法使用复制算法,使用增量标记法优化效率

  • 标记整理: 使得活动对象的地址连续
  • 标记增量: 将原本标记整理的工作拆分为多个小的标记工作,防止程序阻塞

v8垃圾回收策略

v8内存有上限

  1. 采用分代回收思想
  2. 内存分为新生代,老生代
  3. 针对不同对象,采用不同算法

频繁GC(垃圾回收)会带来什么

  • GC工作时,应用程序是停止的
  • 频繁且过长的GC会导致应用假死
  • 用户使用中感知应用卡顿

如何确定是否频繁回收垃圾:

  • Timeline中频繁的上升下降
  • 任务管理器中数据频繁的增加减小

堆快照查找分离dom,这个都是无用的dom引用,需要使用堆快照功能超找
detachedNode
image.png

v8引擎执行流程

image.png

代码优化 函数嵌套会导致v8进行多次的预解析,因此不要嵌套太深

  • js执行环境
  • 执行环境栈(ECStack, execution context stack)
  • 执行上下文
  • VO(G),全局变量对象
  • EC(G),全局执行上下文

基本类型 (栈操作)

  • 基本数据类型是按值进行操作
  • 基本数据类型值是存放在区的
  • 无论我们当前看到的栈内存,还是后续引用数据类型会使用的堆内存都属于计算机内存
  • GO(全局对象)

引用类型 (堆操作)

    1. 确定作用域链(当前执行上下文,上级执行上下文)
    2. 确定this指向,如果是在全局作用域那么就是window
    3. 初始化arguments对象
    4. 变量提升(var声明的关键字,或者函数内部的function声明)
    5. 如果函数内部没有被其他地方所引用,那么就会进行出栈操作,释放栈内存
  1. function fn() {
     var a = 1
     return function(b) {
         console.log(a + b)
     }
    }
    const f = fn()
    f(5)
    f10()
    1. 闭包是一种机制,通过私有的上下文来保护其中的变量的一种机制
    2. 也可以认为,在创建的某一个执行上下文不被释放的时候 就形成了闭包
    3. 保护、保存数据

循环添加事件,看闭包使用的取舍

如果使用闭包,进行多个事件的注册,因为闭包的原因,会申请一个对地址来保存,如果事件越多,那么申请的内存越多,因此需要用到事件代理

变量的申明

变量申明最好是放在局部变量,否则代码在执行的时候 查找作用域链上的变量会比较花时间, 对比下面两段代码 使用的是 jsbench这个工具

var i, str = ""

function parseDom() {
   for(i = 0; i < 100; i++) {
       str += i
   }
}
parseDom()
function parseDom() {
   let str = ''
   for(let i = 0; i < 100; i++) {
       str += i
   }
}
parseDom()

image.png

  • 多次使用的dom变量等
减少判断层级
  • 尽可能的减少判断的层级,如果有嵌套判断,看看是否可以将判断条件往外提
减少循环体活动

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK