js性能优化相关内容笔记整理
GC 算法
1. 引用计数
核心思想:设置引用数,判断当前引用是否为0
优点:
- 发现垃圾时,立即回收
- 最大限度减少程序暂停
- 无法回收循环引用的对象
- 时间开销大(需要监听计数值的变化)
function fn() {
const obj1 = {}
const obj2 = {}
}
2. 标记清除 核心思想:分标记和清除两个阶段
缺点:
1、 空间碎片化(回收对象在地址上的不连续)
2、 不能立即回收
3. 标记整理 标记,然后将活动对象的地址进行整理,尽量使得活动对象地址连续
4. 分代回收 回收新生代对象(存活时间较短的变量对象)
- 回收过程采用复制算法+标记整理
- 新生代内存区分为两个等大小的空间
- 使用空间为From,用于存储活动对象, 空闲空间为To,用于存储From中的活动对象
- 活动对象存储于From空间
- 标记整理后将活动对象拷贝至To
- From 与To交换空间完成释放
- 一轮GC后还存活的新生代需要晋升
- To空间的使用率超过了25%
- 标记清除
- 标记整理: 使得活动对象的地址连续
- 标记增量: 将原本标记整理的工作拆分为多个小的标记工作,防止程序阻塞
v8内存有上限
- 采用分代回收思想
- 内存分为新生代,老生代
- 针对不同对象,采用不同算法
- 分代回收
- 空间复制
- 标记清除
- 标记整理
- 标记增量
- GC工作时,应用程序是停止的
- 频繁且过长的GC会导致应用假死
- 用户使用中感知应用卡顿
- Timeline中频繁的上升下降
- 任务管理器中数据频繁的增加减小
detachedNode
文章图片
v8引擎执行流程
文章图片
代码优化 函数嵌套会导致v8进行多次的预解析,因此不要嵌套太深
堆栈操作
- js执行环境
- 执行环境栈(ECStack, execution context stack)
- 执行上下文
- VO(G),全局变量对象
- EC(G),全局执行上下文
- 基本数据类型是按值进行操作
- 基本数据类型值是存放在栈区的
- 无论我们当前看到的栈内存,还是后续引用数据类型会使用的堆内存都属于计算机内存
- GO(全局对象)
- 函数执行
- 确定作用域链(当前执行上下文,上级执行上下文)
- 确定this指向,如果是在全局作用域那么就是window
- 初始化arguments对象
- 形参赋值
- 变量提升(var声明的关键字,或者函数内部的function声明)
- 执行代码
- 如果函数内部没有被其他地方所引用,那么就会进行出栈操作,释放栈内存
- 闭包理解
function fn() { var a = 1 return function(b) { console.log(a + b) } } const f = fn() f(5) f10()
- 闭包是一种机制,通过私有的上下文来保护其中的变量的一种机制
- 也可以认为,在创建的某一个执行上下文不被释放的时候 就形成了闭包
- 保护、保存数据
变量的申明 变量申明最好是放在局部变量,否则代码在执行的时候 查找作用域链上的变量会比较花时间, 对比下面两段代码 使用的是 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()
【js性能优化相关内容笔记整理】
文章图片
变量缓存
- 数组长度
- 多次使用的dom变量等
- 尽可能的减少判断的层级,如果有嵌套判断,看看是否可以将判断条件往外提
推荐阅读
- 数据库设计与优化
- Improve|Improve Nested Conditionals(优化嵌套的条件语句) 面对大量的if-else语句
- 首屏时间,你说你优化了,那你倒是计算出给给我看啊!
- 数据库|SQL行转列方式优化查询性能实践
- 思维导图作业3—工作相关导图
- 性能测试中QPS和TPS的区别
- AnyProxy抓取http/https请求
- day16-Linux|day16-Linux 软件管理
- #12-UITableView|#12-UITableView 优化方案
- javascript|javascript 性能测试笔记