8 个提高 JavaScript 性能的方法

在一些年以前性能问题,我们前端开发能做的还是很有限的;不过随着 JAVAScript 应用越来越复杂,优化 JavaScript 性能的重要性就越发的凸显出来了 。这里我分享 8 个提高 JavaScript 性能的方法 。
入题
1. 尽可能的缓存
我们知道缓存一些资源或者结果是为了减少再次获得这些资源所需要的时间,所以这是一条很常见的通识 。
有两种选择 。

  1. 第一种是使用 JavaScript Cache API,我们可以使用 service worker 。
  2. 第二种是使用 HTTP 协议缓存 。
通过把重复访问的对象存储在用户定义的变量中,以及在后续对该对象的引用中使用变量,可以立即实现性能的提升 。
2. 延迟不必要的 JS 首屏加载
我们希望页面的加载时间能不让用户焦虑,推迟不必要的 JS 首屏加载是一个很好地方法 。
程序中不是所有函数都需要在页面的初始加载时就要用到 。有很多是用户必须执行某个操作才能执行某个函数,那么你可以将该函数的加载推迟到初始页面加载之后 。
一些通用方法
  1. 使用 defer 和 async 属性
  2. 使用类似 getScript() 方法
  3. 动态创建 DOM 方式
  4. 使用延时器
function loadScript (src, onload) { var scriptTag = document.createElement("script"); scriptTag.src = https://www.isolves.com/it/cxkf/yy/js/2019-08-08/src; if (typeof onload === "function") {scriptTag.onload = onload;scriptTag.onreadystatechange = function () {if (scriptTag.readyState === 4) {onload();}} } document.body.AppendChild(scriptTag);}复制代码3. 删除未使用的 JavaScript
这个步骤是十分必要的,很多人在不使用某些代码的时候仅仅只是注释掉;因为他们生怕产品经理又反悔 。其实你删除这些代码,不仅会缩短传输时间,还会缩短浏览器分析和编译代码所需的时间 。
提供几点作为参考:
  1. 未使用的代码直接删掉,就算后期产品返回,你也可以在 git 历史中找回来 。
  2. 一些常用的方法不要在自己写一遍,团队一定要有一个常用方法的公共库;公用方法都应该写入这个公共库,而不是写在业务代码里面 。
  3. 不要因为一个小功能就引入一个第三方插件/库,你可以使用模块化的方式引入,或者自己写一个类似的方法放在项目的公共库中 。
4. 避免内存泄漏
如果内存正在泄漏,则加载的页面将保留越来越多的内存,并最终占用设备的所有可用内存并严重影响性能 。你可能见过此类故障(并且可能对此类故障感到懊恼),例如轮播 。
在 Chrome 开发者工具中,你可以通过在“Performance ”标签中记录时间线来分析你的网站是否存在内存泄漏 。
若内存占用基本平稳,就说明不存在内存泄漏,反之便是存在 。
几种常见的内存泄漏原因:
  1. 意外的全局变量
  2. 没有销毁的计时器
  3. 已经删除的 DOM 还是被引用,(删除 DOM 后将变量设值为 null 可以避免这个问题)
5. 避免使用全局变量 & 优先使用局部变量
这一点主要是想说定义变量的时候用最近原则,即可以在当前作用域定义的变量就一定不要定义在上一级,更不要一股脑的直接定义在全局 。也就是缩短作用域链的查找长度 。
我们知道 JS 查找变量是按照作用域链查找的,多查找一层势必会多一点处理时间 。定义在当前作用域可以加快代码的执行速度 。
当作用域丢失时,该作用域的变量将被销毁 。
6. 使用 web workers 处理需要大量执行时间的代码
web workers 使 Web 应用程序的主执行线程分开的后台线程中运行脚本操作成为可能 。这样做的好处是,可以在单独的线程中执行费力的处理,允许主线程(通常是UI)运行,而不会阻塞/减慢速度 。
web workers 的几个使用场景
  1. 预取数据 — 优化网站的加载时间,可用 web workers 来提前加载数据 。
  2. 轮询工作
7. 合理使用事件代理
我们知道事件代理可以合并类似的操作,可以直接降低与 DOM 的交互 。使用事件代理的优点就可想而知了:
  1. 节约内存空间,性能自然提升(合并的函数占用内存比优化前少多了)
  2. 减少 DOM 操作(优化性能,减少 DOM 操作一直很重要,这也是 Virtual Dom 流行的几个基本原因)
8. 将重复的代码一定抽象成函数
我们在写代码的时候,有一些代码会在很多模块中出现 。有些人会觉得不以为然,这样不会消耗太多的性能,也就没有抽象出来 。
其实这是必要的,这样做的目的是:


推荐阅读