性能优化是不可避免的
哪些内容可以看做是性能优化
无处不在的前端性能优化
JavaScript 语言的优化:内存管理、垃圾回收与常见的GC算法、v8引擎的垃圾回收、performance工具、代码优化事例
1、JavaScript 内存管理
内存:由可读写单元组成,表示一片可操作空间
管理:人为的去操作一片空间的申请、使用和释放
内存管理:开发者主动申请空间、使用空间、释放空间
管理流程:申请—使用—释放
JavaScript 中的内存管理:申请内存空间、使用内存空间、释放内存空间
2、JavaScript 中的垃圾回收
JavaScript 中内存管理是自动的
对象不再被引用时是垃圾
对象不能从根本上访问到时是垃圾
3、JavaScript 中的可达对象
可以访问到的对象就是可达对象(引用、作用域链)
可达的标准就是从根出发是否能够被找到
JavaScript 中的根就可以理解为是全局变量对象
4、GC定义与作用
GC就是垃圾回收机制的简写
GC可以 找到内存中的垃圾、并释放和回收空间
5、GC里的垃圾是什么
//程序中不再需要使用的对象
Function func () {
Name = ‘lg’;
Return `${name} is a coder`
}
Func()
//程序中不能再访问到的对象
Function func () {
Name = ‘lg’;
Return `${name} is a coder`
}
Func()
6、GC 算法是什么
GC是一种机制,垃圾回收器完成具体的工作
工作的内容就是查找垃圾释放空间、回收空间
算法就是 工作时查找和回收所遵循的规则
常见GC 算法:引用计数,标记清除,标记整理,分代回收
引用计数算法优点:发现垃圾时立即回收;最大限度减少程序暂停
引用计数算法缺点:无法回收循环引用对象;时间开销大
引用计数优缺点(概括):可以即时回收垃圾对象;减少程序卡顿时间;无法回收引用的对象;资源消耗较大
标记清除算法:1、核心思想:分标记和清除二个阶段完成。2、遍历所有对象找标记活动对象;遍历所有对象清除没有标记对象;回收相应的空间
标记清除优缺点:可以回收循环引用的对象;容易产生碎片化空间,浪费空间;不会立即回收垃圾对象
标记整理算法原理:标记整理可以看做是标记清除的增强;标记阶段的操作和标记清除一致;清除阶段会先执行整理,移动对象位置
标记整理优缺点:减少碎片化空间;不会立即回收垃圾对象
7、认识V8
V8 是一款主流的JavaScript 执行引擎
V8 采用即时编译
V8内存设限 64位系统 不超过1.5G, 32位系统 不超过800M
V8是为了浏览器而制造的
V8垃圾回收策略:采用分代回收的思想;内存分为新生代、老生代;针对不同对象采用不同算法
8、中常用GC 算法
分代回收、空间复制、标记清除、标记整理、标记增量
9、V8 内存分配
V8 内存空间一分为二
小空间用于存储新生代对象(32M|16M)、
新生代指的是存活时间较短的对象
10、新生代对象回收实现
回收过程采用复制算法 + 标记整理
新生代内存区分为二个等大小空间
使用空间为From,空闲空间为To
活动对象存储于From空间
标记整理后将活动对象拷贝至To
From 与 To 交换空间完成释放
回收细节说明:
拷贝过程中可能出现晋升
晋升就是将新生代对象移动至老生代
一轮GC 还村活的新生代需要晋升
To 空间使用率超过25%
11、老生代对象回收实现
主要采用标记清除、标记整理、增量标记算法
首先使用标记清除完成垃圾空间的回收
采用标记整理进行空间优化
采用增量标记进行效率优化
老生代对象说明:
老生代对象存放在右侧老生代区域
64位操作系统1.4G,32位操作系统700M
老生代对象就是指存活时间较长的对象
细节对比:
新生代区域垃圾回收使用空间换时间
老生代区域垃圾回收不合适复制算法
12、V8 垃圾回收总结
V8 是一款主流的 JavaScript 执行引擎
V8 内存设置上限
V8 采用基于分代回收思想实现垃圾回收
V8 内存分为新生代和老生代
V8垃圾回收常见的GC 算法
13、Performance 工具介绍
(1)为什么使用performance
GC的目的是为了实现内存空间的良心循环,良性循环的基石是合理使用的,时刻关注才能确定是否合理,Performance 提供多种监控方式
(2)通过performance 时刻监控内存,使用步骤:
打开浏览器输入目标网址
进入开发人员工具面板,选择性能
开启录制功能,访问具体界面
执行用户行为,一段时间后停止录制
分析界面中记录的内存信息
(3)内存问题的体现:
内存问题的外在表现
页面出现延迟加载或经常性暂停
页面持续性出现糟糕的性能
页面的性能随时间延长越来越差
(4)监控内存的几种方式
界定内存问题的标准
内存泄漏:内存使用持续升高
内存膨胀:在多数设备上都存在性能问题
频繁垃圾回收:通过内存变化图进行分析
浏览器任务管理器
Timeline 时序图记录
对快照查找分离DOM
判断是否存在频繁的垃圾回收
(4)浏览器任务管理器监控内存
Shift + esc 打开浏览器任务管理器,内存列和JavaScript 内存列
(5)Timeline 记录内存
(6)堆快照查找分离DOM
界面元素存活在DOM树上
垃圾对象时的DOM 节点
分离状态的DOM节点
(7)为什么确定频繁垃圾回收
GC工作时 应用程序是停止的
频繁且过长的GC会导致应用假死
用户使用中感知应用卡顿
确定频繁的垃圾回收:timeline 中频繁的上升下降,任务管理器中数据频繁的增加减小
(8)总结:Performance使用
Performance使用流程
内存问题的相关分析
Performance时序图监控内存变化
任务管理器监控内存变化
堆快照查找分离DOM
(9)V8 引擎工作流程
14、预解析
跳过未使用的代码
不生成AST, 创建无变量引用和声明的scopes
依据规范抛出特定错误
解析速度更快
15、全量解析
解析被使用的代码
生成AST
构建具体scopes 信息,变量引用、声明等
抛出所有语法错误
Ignition 是V8提供的一个解释器
TurboFan 是V8提供的编译器模块
16、堆栈操作
堆栈准备:Js执行环境、执行环境栈、执行上下文、全局变量对象VO(G)
17、引用类型堆栈处理
18、函数堆栈处理
更正:函数执行的目的是为了将函数所对应的堆内存里的字符串形式代码进行执行,代码在执行的时候肯定要有一个环境,此时意味着函数在执行的时候会生成一个新的执行上下文来管理函数体当中的代码
19、闭包堆栈处理
20、闭包与垃圾回收
更正:3:当前堆内存如果被占用,就不能被释放掉,但是我们如果确认后续不再使用这个内存里的数据,也可以自己主动置空,然后浏览器就会对其进行回收
21、循环添加事件实现与委托事件
22、JSBench 使用