浏览器垃圾回收机制与性能提升

一. 为什么浏览器需要垃圾回收?

JavaScript 的内存空间

在 JavaScript 的执行过程中, 主要有三种类型内存空间,分别是 代码空间 、 栈空间 和 堆空间 。其中代码空间主要存储可执行代码。
在这里插入图片描述

栈空间和堆空间

即调用栈,用来存储执行上下文,包括变量环境、词法环境等。

function foo(){
 var a = "Chrome"
 var b = a
 var obj1 = {name:"jack"}
 var obj2=obj1;
}
foo()

在这里插入图片描述
当执行一段代码时,需要先编译、创建执行上下文,然后才能顺序执行代码,上述代码当执行到第2,3行时候,变量 a 和变量 b 的值都被保存在执行上下文中,而执行上下文又被压入到栈中。继续执行第 4 行代码, c是一个对象是个引用类型,这时候会把c的值存放到堆空间中,分配后该对象会有一个在“堆”中的地址。这个地址会写到c的变量值。

所以JavaScript 程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。只要像这样动态地分配了内存,最终都要释放这些内存以便他们能够被再用,否则,JavaScript 的解释器将会消耗完系统中所有可用的内存,造成系统崩溃。

二. 浏览器垃圾回收机制

浏览器的 Javascript 具有自动垃圾回收机制,垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。

1. 标记清除

js中最常用的垃圾回收方式就是标记清除。当变量进入环境时,例如,在一个函数中声明一个变量,就将这个变量标记为"进入环境",从逻辑上讲,永远不能释放进入环境变量所占用的内存,因为只要执行流进入相应的环境,就可能会用到它们。而当变量离开环境时,则将其标记为"离开环境"。
function test(){
    var a = 10;    //被标记"进入环境"
    var b = "hello";    //被标记"进入环境"
}
test();    //执行完毕后之后,a和b又被标记"离开环境",被回收

2. 引用计数

引用计数的含义是跟踪记录每个值被引用的次数。当声明了一个变量并将一个引用类型赋值给该变量时,则这个值的引用次数就是 1。相反,如果包含对这个值引用的变量又取得了另外一个值,则这个值的引用次数就减 1。当这个引用次数变成 0 时,则说明没有办法再访问这个值了,因而就可以将其所占的内存空间给收回来。

三. 浏览器内存泄漏

1)意外的全局变量引起的内存泄露

function leak(){  
  leak="xxx";//leak成为一个全局变量,不会被回收  
} 

2)滥用闭包引起的内存泄露
3) 被遗忘的定时器或者回调
4) 对象循环引用

function fn(){  
  var a={};  
  var b={};  
  a.pro=b;  
  b.pro=a;  
}  
fn();  

四. 检测浏览器性能

1.Performance 性能检测

在这里插入图片描述
区域1:网页性能总览图
总览图包含 FPS(每秒帧数情况)、CPU(CPU占用情况)、NET(网络资源情况)、HEAP(JS占用情况)一共四项指标。
区域2:各项指标的区块图
在这里插入图片描述
1.Network:表示每个服务器资源的加载情况。

2.Frames:表示每幅帧的运行情况。

3.Timings:上图中有 4 条虚线,分别表示如下。
(1)DCL(DOMContentLoaded)表示 HTML 文档加载完成事件。当初始 HTML 文档完全加载并解析之后触发,无需等待样式、图片、子 frame 结束。作为明显的对比,load 事件是当个页面完全被加载时才触发。
(2)FP(First Paint)首屏绘制,页面刚开始渲染的时间。
(3)FCP(First Contentful Paint)首屏内容绘制,首次绘制任何文本,图像,非空白canvas 或 SVG 的时间点。
(4)FMP(First Meaningful Paint)首屏有意义的内容绘制,这个“有意义”没有权威的规定,本质上是通过一种算法来猜测某个时间点可能是 FMP。有的理解为是最大元素绘制的时间,即同LCP(Largest Contentful Paint )。
其中 FP、FCP、FMP 是同一条虚线,三者时间不一致。比如首次渲染过后,有可能出现 JS 阻塞,这种情况下 FCP 就会大于 FP。
(5)L(Onload)页面所有资源加载完成事件。
(6)LCP(Largest Contentful Paint )最大内容绘制,页面上尺寸最大的元素绘制时间。

4.Main:表示主线程。
合成线程主要负责:
Javascript 的计算与执行;
CSS 样式计算;
Layout 布局计算;
将页面元素绘制成位图(paint),也就是光栅化(Raster);
将位图给合成线程。

5.Raster:光栅化(处理光栅图,即位图)。

6.GPU:表示 GPU 占用情况。

7.Chrome_childIOThread:子线程。

8.Compositor:合成线程。
合成线程主要负责:
将位图(GraphicsLayer 层)以纹理(texture)的形式上传给 GPU;
计算页面的可见部分和即将可见部分(滚动);
CSS 动画处理;
通知 GPU 绘制位图到屏幕上。

区域3:数据统计与汇总
在这里插入图片描述
Summary:表示各指标时间占用统计报表;
Bottom-Up:表示事件时长排序列表(倒序);
Call tree:表示事件调用顺序列表;
Event Log:表示事件发生的顺序列表;

2.Lighthouse(Audits) 面板

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

五. 如何提高浏览器性能

1.删除未使用的JavaScript
2.避免内存泄漏(死循环爆栈,对象循环引用,滥用闭包等)
3.优先访问局部变量,避免使用全局变量
4. 适当的使用Web worker
5. vue 组件化

性能优化参考文章:
https://juejin.cn/post/6844903657318645767#heading-6
https://juejin.cn/post/6911472693405548557#heading-43

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值