Web 应用的内存优化

更新日期: 2019-06-30阅读: 2.3k标签: 内存

随着 Web 应用复杂程度越来越高,以及 NodeJS 大规模投入生产环境,许多 Web 应用都会长时间运行, JavaScript 的内存管理显得更为重要。

JavaScript 具备自动回收垃圾的机制, 执行环境会负责管理代码在执行环境过程中使用的内存,将某些不再被使用的的变量所占用的内存释放掉,正因如此,大多数情况我们在前端开发的时候,并不是那么关注我们的页面用了多少内存,是否合理,需不需要优化。

JavaScript 基础中有很多重要的知识点是和内存相关的,比如深拷贝和浅拷贝、闭包、原型、引用数据类型和引用传递等。

当然,关于 JS 的内存空间和内存相关的知识已经有很多专业的文章解释的很详细了,这里就不再赘述了。

在 Web 应用开发中,我们应该注意:


1. 避免没有必要全局变量的使用

前端开发者都知道,在局部作用域中,当函数执行完毕,局部变量也就没有存在的必要了,它很容易被垃圾回收器回收,当使用全局变量定义值时,垃圾回收器,很难判断全局变量需要什么时候释放内存空间,因此是不会去对其进行回收销毁的。而该变量会一直存在老生代堆内存中,直到页面被关闭。

function setName () {
  name = "alloy";
}
// 等价
function setName () {
  window.name = "alloy"
}

另外一种意外情况是;

function setName (name) {
    this.name = name;
}
setName("alloy");

我们可以在 JS 文件的开头通过添加"use strict" 开启严格的解析模式,来避免一些意外创建的全局变量。


2. 及时解除引用

如果必须要一个全局变量来存储大量数据,那么请确保在用完之后将其赋值为 null。

delete 操作符用于删对象的某个属性;如果没有指向这个属性的引用,那它最终会释放。

但注意的一点是,尽量不要在需要密集运算的函数中去使用 delete,这很可能会引发浏览器在不恰当的时候的 GC,和其他语言一样,JavaScript 的 GC 策略无法避免 GC 时停止响应其他操作,而 JavaScript 的 GC 在 50ms 甚至以上,对普通应用还好,如果是对于操作频繁的 Web 应用或者游戏来说,就比价烦恼了。

const Room = {
  desks: 10,
  chairs: 22
};
console.log(Room.desks); // 10;
delete Row.desks;
console.log(Room.desks); // undefined

有时候我们虽然用 removeChild 移除了 button,但是还在 node 对象里保存着 #button 的引用,dom 元素还在内存里面,需要及时解除引用。

var node = {
   button: document.getElementById('button');
};
document.body.removeChild(document.getElementById('button'));


3. 减少对象的创建

垃圾回收周期性运行,如果分配的内存非常多,或者新建很很多实例的话,那么回收工作也会很辛苦。

尽量避免在经常调用的方法中循环使用 new 对象,而且还要花时间对这些对象进行垃圾回收和处理。

设计模式中的享元模式就是为了减少对象的多次创建而来的。在我们可以控制的范围内,最大限度的重用对象。


4. 内存不是缓存

缓存在需求开发中举足轻重,但是很多时候我们会把许多大数据缓存在内存中,导致我们的内存占用始终处于高位,内存对任何程序开发都是寸土寸金 的,若果不是很重要的资源,请不要直接放在内存中,或者制定过期机制,自动销毁过期缓存。


5. 避免复杂的递归调用;

通常情况下,简单的递归调用还不至于导致堆栈溢出,但遇到复杂且每次调用需要 在栈里存储大量信息的时候,成千上万个此类空间累积起来,很容易就超过了栈空间。


6. 合理使用的 IndexedDB

其实这个是和 JS 关系不是很大,但是对于 Web 应用的影响却十分重要,曾经我遇到过一个用户案例,由于长时间的本地数据写入,和一些上报日志没有被及时清除,导致用户的浏览器中对应域名下的 IndexedDB 存储高达 12GB,浏览器在访问对应域名的时候,也可以初始化 IndexedDB 和读取本地存储的数据,而面对如此庞大的数据,浏览器内存暴涨,最后崩溃,避免过度依赖 IndexedDB,无脑写入数据而不做定期清理。


总结

这篇分享主要总结了我们在 Web 应用,可能会遇到的一些情况和注意的事情。很多时候只要我们在编码的时候多加注意,可以避免很多问题。


链接: https://fly63.com/article/detial/4428

JavaScript 内存管理和垃圾回收

JavaScript 的内存管理和垃圾回收,是个略生僻的话题,因为在JavaScript 中不显式执行内存操作,不过最好了解它如何工作。

js常见的内存泄漏及解决方法总汇

js具有自动回收垃圾的机制,即执行环境会负责管理程序执行中使用的内存。在C和C++等其他语言中,开发者的需要手动跟踪管理内存的使用情况。在编写js代码时候,开发人员不用再关心内存使用的问题,所需内存的分配 以及无用的回收完全实现了自动管理。

浅谈javaScript内存机制

javaScript内存空间并不是一个经常被提及的概念,想要对JS的理解更加深刻,就必须对内存空间有一个清晰的认:栈与堆、复杂数据类型与基本数据类型、引用数据类型与堆内存

js 把一个对象赋值给另一个对象会指向同一个内存地址

实际上并不是新建一个和原对象(数组也是对象)完全一样的对象,而是把原对象的内存地址直接复制给了另一个对象,也就是说两个对象都是指向同一个内存地址,所以实际上它们就是同一个对象。

php底层原理之垃圾回收机制

php垃圾回收机制,对于PHPer来说是一个不陌生但是又不是很熟悉的内容。那么php是怎么实现对不需要的内存进行回收的呢?首先还是需要了解下基础知识,便于垃圾回收原理内容的理解。

js变量、作用域和内存问题

JavaScript变量可以用来保存两种类型的值:基本类性值和引用类性值。所有变量(包括基本类型和引用类型)都存在于一个执行环境(也称为作用域)当中,具有自动垃圾收集机制的编程语言,开发人员不必关心内存分配和回收问题

php中的内存管理

计算机的内存由操作系统进行管理,所以普通应用程序是无法直接对内存进行访问的。应用程序只能向操作系统申请内存,通常的应用也是这么做的,在需要的时候通过类似malloc之类的库函数 向操作系统申请内存。

原生JS与Jquery删除iframe并释放内存-IE

当项目以tab页签方式打开多个iframe窗口时,关闭tab页签同时也需要关闭iframe并释放内存资源,主要是针对IE浏览器。

闭包真的会导致内存泄漏?

今天遇到一个很有争议的问题,在这里分享一下,我相信对于即将面试前端的小伙伴会有帮助的。主要内容是围绕下边的问题展开的,文章涉及到的其他方面的知识点不展开叙述。

Js内存泄露

用户一般不会在一个 Web 页面停留比较久,即使有一点内存泄漏,重载页面内存也会跟着释放。而且浏览器也有自动回收内存的机制,所以我们前端其实并没有像 C、C++ 这类语言一样,特别关注内存泄漏的问题。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!