不懂JavaScript 内存管理的前端不是好程序员!

简介: 不懂JavaScript 内存管理的前端不是好程序员!

一位客户报告说,当点击一个按钮后,Chrome关闭了该页面,该页面就失去了响应。我最初认为这可能是Chrome扩展的问题。所以,我在隐身模式下进行了测试,但问题也在隐身模式下重现。


在解决这个问题之后,我花了很多时间阅读和理解JavaScript及其编译器。


因此就有了该篇文章


内存泄漏

内存泄漏是因为不需要的内存,但由于某种原因,它没有被回收返回到内存池。


JavaScript的设计方式是,一旦变量被使用,它将自动删除分配的内存,这个过程称为垃圾收集。


JavaScript编译器使用两种不同的垃圾收集器,一种是主Major GC,另一种是Minor GC。


更多: https://v8.dev/blog/trash-talk


Major GC: Major GC从整个堆中收集垃圾。


Minor GC: 小GC收集年轻代的垃圾。


Major GC:

主GC是主垃圾收集器,它识别活对象和死对象,并删除死对象。但是Major GC是在主线程上运行的,所以如果经常调用GC,页面就会变得无响应。


垃圾回收为什么冻结页面?


Garage collector运行在主线路上,所以它会阻塞所有用户输入,因此页面变得无响应。


好吧,但为什么主线程阻塞所有用户输入?


简单的回答是事件循环。更详细的答案,你需要看这个视频。对事件循环和JavaScript编译器有更详细的解释。


更多:https://www.youtube.com/watch?v=8aGhZQkoFbQ


改善应用程序内存管理的通用建议

1. 全局变量

垃圾收集器从不收集全局变量的内存,因此在开始声明全局变量之前,请三思。

但有时,我们会不小心引入了一个全局变量。


请看代码

function foo(arg) { 
  bar = "this is a hidden global variable";
}

您可能会注意到,该变量没有定义但赋值,因此它将成为一个全局变量。

这里,我们泄漏了一个字符串内存,你可能认为这不会产生大问题,但它会覆盖其他一些全局方法,这会引起新的隐患。


2. 引用没法回收

当涉及到对象和数据绑定时,一定要关注内存。

function run(){
  var domObjects = $(".myClass");
  domObjects.click(function(){
    domObjects.addClass(".myOtherClass");
  });
}


一旦函数被调用,JavaScript将删除分配的内存。但是在上面的代码中,GC没有办法收集“domObjects”的内存,因为它绑定到了事件监听器。


如果你想删除这些引用,你可以手动删除它们。

function run(){
  var domObjects = $(".myClass");
  domObjects.click(function(){
    if(domObjects){
      domObjects.addClass(".myOtherClass");
      domObjects = null;
    }
  });
}

3. 字符串连接

这听起来很奇怪,但是字符串连接需要额外的内存。因此,避免字符串连接,而使用模板字面量代替。


33.png


4. 避免创建新对象

新的内存被分配给新的对象、数组等。想办法减少这种情况。


让我们看一个jQuery的例子,


当你从不使用jQuery时,它会增加堆中的内存,所以我们可以避免使用jQuery链接方法。


44.png


6. JSON Parse

当您的应用程序在页面加载期间基于JSON进行渲染时,请考虑使用JSON.stringify和JSON.parse来处理这些数据。

22.png

更多: https://v8.dev/blog/cost-of-javascript-2019#json


7. 避免 try-catch

Try-catch比if分配更多的内存。但是try-catch对于大多数应用程序都是必要的,如果你分析得当,你可以把它们变成try-catch。


11.png

00.png

请看看下面链接中的问题,由node js环境中的try-catch引起的内存泄漏问题。您将获得一些关于try-catch和内存泄漏的知识


https://github.com/nodejs/node/issues/35048


8. 创建新窗口

当创建一个新窗口时,请把废弃的window引用设置为null。


当关闭窗口时,只调用Minor GC,因此只清除年轻代内存块。


如果您想检查JSHeap内存占用情况,请在您的控制台上输入此代码:

memory.usedJSHeapSize

。。.png


9. Callbacks回调

如果事件的回调频率非常高,考虑避免它。让我们以滚动为例。当您将滚动事件绑定到窗口用户向下/向上滚动时,回调调用的频率非常高。


可以使用 Underscore.js 中 _.throttle 和 _.debounce 来减少回调执行,避免页面卡顿。

function log( event ) {
  console.log( $(window).scrollTop(), event.timeStamp );
};
// 控制台记录窗口滚动事件,触发频率比你想象的要快
$(window).scroll( log );
// 控制台记录窗口滚动事件,每250ms最多触发一次
$(window).scroll( _.throttle( log, 250 ) );
function ajax_lookup( event ) {
  // 对输入的内容$(this).val()执行 Ajax 查询
};
// 字符输入的频率比你预想的要快,Ajax 请求来不及回复。
$('input:text').keyup( ajax_lookup );
// 当用户停顿250毫秒以后才开始查找
$('input:text').keyup( _.debounce( ajax_lookup, 250 ) );

更多请阅读https://blog.coding.net/blog/the-difference-between-throttle-and-debounce-in-underscorejs

相关文章
|
1天前
|
缓存 JavaScript 前端开发
前端框架与库 - Vue.js基础:模板语法、数据绑定
【7月更文挑战第14天】Vue.js 是渐进式框架,以简洁API和高效数据绑定知名。本文聚焦模板语法与数据绑定,解释常见问题和易错点,助力初学者避坑。模板语法中,{{ expression }} 用于渲染值,v-bind/: 用于动态绑定属性。数据绑定涉及文本、属性和事件,注意v-model适用于表单元素,计算属性有缓存。理解正确用法,借助文档和IDE,可提升开发质量和效率。善用Vue.js,打造响应式UI。
|
9天前
|
前端开发 NoSQL 数据库
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
部署常用的流程,可以用后端,连接宝塔,将IP地址修改好,本地只要连接好了,在本地上前后端跑起来,前端能够跑起来,改好了config.js资料,后端修改好数据库和连接redis,本地上跑成功了,再改
|
5天前
|
测试技术 API Android开发
autox.js如何监听异常情况,比如网络中断、内存慢、应用死机或者页面无响应
autox.js如何监听异常情况,比如网络中断、内存慢、应用死机或者页面无响应
|
10天前
|
前端开发 NoSQL JavaScript
若依修改---重新部署项目注意事项,新文件初始化需要修改的地方,打包后的文件很难进行修改,如果想要不断修改项目,注意保存原项目,才可以不断修改,前端:在Vue.config.js文件中修改target
若依修改---重新部署项目注意事项,新文件初始化需要修改的地方,打包后的文件很难进行修改,如果想要不断修改项目,注意保存原项目,才可以不断修改,前端:在Vue.config.js文件中修改target
|
10天前
|
前端开发 JavaScript Linux
若依修改之后,无法访问前端项目如何解决,只能访问后端的接口,我的接口8083,端不显示咋解决?在vue.config.js文件中的映射路径要跟后端匹配,到软件商店里找到Ngnix配置代理,设80不用加
若依修改之后,无法访问前端项目如何解决,只能访问后端的接口,我的接口8083,端不显示咋解决?在vue.config.js文件中的映射路径要跟后端匹配,到软件商店里找到Ngnix配置代理,设80不用加
|
11天前
|
前端开发 JavaScript
js 打开资源管理器(经典范例:纯前端选择并预览图片)
js 打开资源管理器(经典范例:纯前端选择并预览图片)
23 0
|
13天前
|
前端开发 JavaScript API
只会用插件可不行,这些前端动画技术同样值得收藏-JavaScript篇(下)
只会用插件可不行,这些前端动画技术同样值得收藏-JavaScript篇(下)
14 0
|
13天前
|
监控 JavaScript 前端开发
只会用插件可不行,这些前端动画技术同样值得收藏-JavaScript篇(上)
只会用插件可不行,这些前端动画技术同样值得收藏-JavaScript篇(上)
16 0
|
13天前
|
JavaScript 前端开发 API
JS案例:前端Iframe及Worker通信解决思路
JS案例:前端Iframe及Worker通信解决思路
14 0
|
13天前
|
存储 JavaScript 前端开发
面试官:JS中变量定义时内存有什么变化?
面试官:JS中变量定义时内存有什么变化?
13 0