14个JavaScript代码优化技巧

云栖号资讯:【点击查看更多行业资讯】
在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来!

JavaScript 已经成为有史以来最受欢迎的编程语言之一。根据 W3Tech 的数据,全世界将近 96%的网站都在使用它。关于 Web 有一个关键的事实是,你无法控制访问网站的用户所用设备的硬件规格。最终用户访问你的网站时,使用的可能是高端设备也可能是低端设备,网络连接条件也有好有差。这意味着你必须尽可能优化自己的网站,以满足任何用户的需求。

这篇文章列举了一些技巧,可帮助你写出更好的 JavaScript 代码,从而提高性能。

附带提一下,请共享和重用你的 JS 组件,以在高质量代码(写起来需要花费时间)和合理的交付时间之间保持适当的平衡。你可以使用 Bit 等流行工具将任何项目中的组件(普通 JS、TS、React、Vue 等)共享到 Bit 的组件中心,用不了多大功夫。

1、删除未使用的代码和功能
你的应用程序包含的代码越多,就需要将更多的数据传输到客户端。浏览器也需要更多时间来分析和解释代码。
有时,你可能打包了很多根本用不到的功能。最好只在开发环境中保留这些额外的代码,而不要将其推送到生产环境中,以免给客户端的浏览器增加负担。

要不断问自己,某个功能或代码段是否是必要的。
你可以手动移除未使用的代码,也可以使用 Uglify 或谷歌的 Closure Compiler 之类的工具删除它们。你甚至可以使用一种称为摇树优化的技术从应用程序中删除未使用的代码。Webpack 这类打包软件提供了这种技术,详情可以参考这里。如果要删除未使用的npm 软件包,可以使用命令npm prune,详细信息参考 NPM 文档。

2、尽可能缓存
缓存可以减少延迟和网络流量,从而减少了显示资源表示所需的时间,以提高网站的速度和性能。缓存可以借助 Cache API 或 HTTP caching 来实现。你可能想知道内容更改时会发生什么。当满足某些条件(例如发布新内容)时,上述缓存机制能够处理和重新生成缓存。

3、避免内存泄漏
作为一种高级语言,JS 会负责一些底层管理工作,例如内存管理。垃圾回收是大多数编程语言共有的过程。用外行术语来说,垃圾收集就是收集并释放已分配给对象,但目前尚未在程序的任何部分中使用的内存。在 C 这样的编程语言中,开发人员必须使用 malloc() 和 dealloc() 函数来处理内存分配和释放操作。

虽然在 JavaScript 中垃圾回收是自动执行的,但在某些情况下它也不是完美的。在 JavaScript ES6 中,引入了 Map 和 Set 及其“weaker”的同级对象。被称为 WeakMap 和 WeakSet 的“较弱”对应项持有对对象的“弱”引用。它们使未引用的值能够被垃圾回收,从而防止内存泄漏。你可以在此处阅读有关 WeakMaps 的更多信息。

4、尽早打破循环
超大循环肯定会消耗很多宝贵的时间,所以你应该尽早打破它们。你可以用 break 关键字和 continue 关键字来做这件事。编写最高效的代码是你的责任。
在下面的示例中,如果你没有从循环中 break,则你的代码将循环运行 1000000000 次,显然会过载的。

let arr = new Array(1000000000).fill('----');
arr[970] = 'found';
for (let i = 0; i < arr.length; i++) {if (arr[i] === 'found') {console.log("Found");break;}
}

在下面的示例中,如果你在循环不符合你的条件时没​​有 continue,则你仍将运行该函数 1000000000 次。我们仅在数组元素处于偶数位置时处理它。这将循环执行减少了近一半。

let arr = new Array(1000000000).fill('----');
arr[970] = 'found';
for (let i = 0; i < arr.length; i++) {if(i%2!=0){continue;};process(arr[i]);
}

你可以在此处详细了解循环和性能的关系。

5、最小化变量计算的次数
为了减少计算变量的次数,可以使用闭包。通俗来说,JavaScript 中的闭包使你可以从内部函数访问外部函数作用域。每次创建函数(不调用)时都会创建闭包。内部函数将有权访问外部作用域的变量,即使在返回外部函数之后也是如此。
我们来看两个例子。这些示例均来自 Bret 的博客。

function findCustomerCity(name) {const texasCustomers = ['John', 'Ludwig', 'Kate']; const californiaCustomers = ['Wade', 'Lucie','Kylie'];return texasCustomers.includes(name) ? 'Texas' : californiaCustomers.includes(name) ? 'California' : 'Unknown';
};

如果你多次调用上面的函数,那么每次都会创建一个新对象。每次调用时,变量 texasCustomers 和 californiaCustomers 都会导致不必要的内存重分配。

function findCustomerCity() {const texasCustomers = ['John', 'Ludwig', 'Kate']; const californiaCustomers = ['Wade', 'Lucie','Kylie'];return name => texasCustomers.includes(name) ? 'Texas' : californiaCustomers.includes(name) ? 'California' : 'Unknown';
};
let cityOfCustomer = findCustomerCity();
cityOfCustomer('John');//Texas
cityOfCustomer('Wade');//California
cityOfCustomer('Max');//Unknown

在上面的示例中,借助于闭包,返回到变量 cityOfCustomer 的内部函数可以访问外部函数 findCustomerCity() 的常量。而且,每当以传递的名称作为参数调用内部函数时,都无需再次实例化常量。要了解关于闭包的更多信息,建议你阅读 Prashant 的博客文章。

6、尽量减少 DOM 访问
与其他 JavaScript 语句相比,访问 DOM 的速度很慢。如果你对 DOM 进行更改,触发了布局的重新绘制,那么就得等好一阵子了。
为了减少访问 DOM 元素的次数,请先访问一次,然后将其用作局部变量。完成需求后,请一定将其设置为 null 来移除该变量的值。这将防止内存泄漏,因为这会触发垃圾回收过程。

7、压缩文件
通过压缩方法(例如 Gzip)可以减小 JavaScript 文件的大小。较小的文件会提升你的网站性能,因为浏览器只需下载较小的资产即可。
这类压缩手段最多可以减少 80%的文件大小。在此处阅读有关压缩的更多信息。

8、缩小最终代码
有人认为缩小和压缩是相同的,其实不然。在压缩中,我们使用特殊算法来改变文件的输出大小;在缩小时,我们需要删除 JavaScript 文件中的注释和多余的空格。可以在网上找到许多工具和软件包来帮助完成这一过程。缩小已成为页面优化的标准做法,也是前端优化的主要步骤之一。
缩小可以让文件大小最多减少 60%。你可以在此处阅读有关缩小的更多信息。

9、使用 Throttle(节流)和 Debounce(防抖)
我们可以使用这两种技术来严格控制代码需要处理事件的次数。
节流是指定函数可以超时的最大次数。例如,“每 1000 毫秒最多执行一次 onkeyup 事件函数”。也就是说哪怕你每秒敲 20 个键,该事件每秒也只会触发一次。这将减少代码的负担。
另一方面,防抖是指定自上次执行相同函数以来再次运行该函数的最短持续时间。换句话说,“上次调用函数后过最少 600 毫秒才执行此函数”。要了解有关节流和防抖的更多信息,这里有一篇快速入门。
你可以实现自己的防抖和节流函数,也可以从Lodash 和Underscore 之类的库中导入它们。

10、避免使用 Delete 关键字
delete 关键字用于从对象中删除属性。这个关键字的性能表现不怎么好,预计它将在未来的更新中修复。
或者,你可以简单地将不需要的属性设置为 undefined。

const object = {name:"Jane Doe", age:43};
object.age = undefined;

你还可以使用 Map 对象,Bret 认为它的 delete 方法会更快。

11、使用异步代码防止线程阻塞
你应该知道 JavaScript 默认情况下是同步的和单线程的。但是在某些情况下,你的代码需要很大的计算量。代码本质上是同步的,意味着一段代码运行时将阻止其他代码语句运行,直到前者完成执行为止。这会降低整体性能。
但是我们可以通过异步代码来避免这种情况。异步代码以前以回调的形式编写,但是 ES6 引入了一种处理异步代码的新样式。这种新样式被称为 Promise。你可以在 MDN 的官方文档中了解有关回调和 Promise 的更多信息。
可是等等……
JavaScript 默认情况下是同步的,并且也是单线程的。
如何在单个线程上运行异步代码呢?这是很多人感到困惑的地方。做到这一点,主要依赖运行在浏览器后台的 JavaScript 引擎。JavaScript 引擎是执行 JavaScript 代码的计算机程序或解释器。JavaScript 引擎可以用多种语言编写。例如,支持 Chrome 浏览器的 V8 引擎是用 C++ 编写的,而支持 Firefox 浏览器的 SpiderMonkey 引擎是用 C 和 C++ 编写的。
这些 JavaScript 引擎可以在后台处理任务。根据 Brian 的说法,调用栈可以识别 Web API 的函数,并将其交给浏览器处理。浏览器完成这些任务后,它们将返回并作为回调被推上堆栈。
你可能想知道 Node.js 是怎么做这些工作的,毕竟它没有浏览器的帮助。实际上,支持 Chrome 的那个 V8 引擎也是 Node.js 背后的支撑。这里有 Salil 的一篇很棒的博客文章,解释了Node 生态系统中的这一过程。

12、使用代码拆分
如果你有使用 Google Light House 的经验,肯定会熟悉一种称为“first contentful paint”的指标。它是 Lighthouse 报告的 Performance 部分中跟踪的六个指标之一。
First Contentful Paint(FCP)衡量用户转到你的页面后浏览器渲染第一段 DOM 内容所花费的时间。页面上的图像、非白色元素和 SVG 被视为 DOM 内容;iframe 内部不包含任何内容。
获得更高的 FCP 分数的最佳方法之一是使用代码拆分。代码拆分是一种在传输开始时仅将必要的模块发送给用户的技术。通过减小最初发送的载荷大小,这将极大地影响 FCP 分数。
流行的模块打包器(例如 webpack)可为你提供代码拆分功能。你还可以利用原生 ES 模块来单独加载各个模块。你可以在此处详细了解有关原生 ES 模块的信息。

13、使用 async 和 defer
在现代网站中,脚本比 HTML 更为密集,其大小更大且消耗更多的处理时间。默认情况下,浏览器必须等待脚本下载和执行完毕后,再处理页面的其余部分。
于是笨重的脚本可能会阻止网页的加载。为了避免这种情况,JavaScript 为我们提供了两种分别称为 async 和 defer 的技术。你只需将这些属性添加到

14、使用 Web Workers 在后台运行 CPU 密集型任务
Web Worker 允许你在后台线程中运行脚本。如果你有一些高强度的任务,可以将它们分配给 Web Worker,这些 WebWorker 可以在不干扰用户界面的情况下运行它们。创建后,Web Worker 可以将消息发布到该代码指定的事件处理程序来与 JavaScript 代码通信,反之亦然。
要了解有关 Web Worker 的更多信息,建议你阅读 MDN 文档。

感谢阅读,欢迎评论,编程愉快!

【云栖号在线课堂】每天都有产品技术专家分享!
课程地址:https://yqh.aliyun.com/zhibo

立即加入社群,与专家面对面,及时了解课程最新动态!
【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK

原文发布时间:2020-07-21
本文作者:Mahdhi Rezvi
本文来自:“InfoQ”,了解相关信息可以关注“InfoQ”

原文链接

本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/515416.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云~安装Docker

文章目录1. 卸载旧版docker2. yum包更新到最新3. 安装依赖4. 设置yum源为阿里云5. 安装docker6. 安装后查看docker版本7. 阿里云镜像加速1. 卸载旧版docker sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logro…

128核云原生新力作:Ampere® Altra® Max性能参数公布,提升50%!

安晟培半导体科技有限公司&#xff08;Ampere Computing&#xff09;于日前公布了云原生服务器处理器Ampere Altra Max样片的基准测试数据。Ampere Altra Max是Ampere继去年3月发布的80核Altra 处理器后即将推出的重磅新品&#xff0c;内核数量达到业界领先的128核&#xff0c;…

《从单体迈向 Serverless 的避坑指南》

简介&#xff1a; 用户需求和云的发展两条线推动了云原生技术的兴起、发展和大规模应用。本文将主要讨论什么是云原生应用&#xff0c;构成云原生应用的要素是什么&#xff0c;什么是 Serverless 计算&#xff0c;以及 Serverless 如何简化技术复杂度&#xff0c;帮助用户应对快…

腾讯云~Docker安装RabbitMQ

文章目录1. 测试2. 安装策略组3. 控制台1. 测试 docker run -d --name myRabbitMQ -e RABBITMQ_DEFAULT_USERimooc -e RABBITMQ_DEFAULT_PASS123456 -p 15672:15672 -p 5672:5672 rabbitmq:3.8.14-management企业内部使用参考&#xff1a;https://gblfy.blog.csdn.net/article…

定义下一代存储,打造全新一代数据基础设施

简介&#xff1a; 智能时代&#xff0c;阿里云正重新定义下一代存储&#xff0c;打造全新一代数据基础设施。在未来&#xff0c;数据势必呈爆发式地增长&#xff0c;那么对于存储的性能&#xff0c;必然会提出更高、更严苛的要求。此次直播阿里云将为大家带来7款存储产品新功能…

Docker私有镜像仓库是什么?

来源 | 无敌码农责编 | 寇雪芹头图 | 下载于视觉中国Docker镜像仓库概述镜像仓库作为Docker技术的核心组件之一&#xff0c;其主要作用就是负责镜像内容的存储和分发。Docker镜像仓库从使用范围来说分为“公有镜像仓库”和“私有镜像仓库”&#xff0c;公有镜像仓库是可以被任何…

《掌门1对1微服务体系 Solar | 阿里巴巴 Sentinel 落地实践》

简介&#xff1a; 前言 掌门1对1精耕在线教育领域&#xff0c;近几年业务得到了快速发展&#xff0c;但同时也遭遇了“成长的烦恼”。随着微服务数量不断增加&#xff0c;流量进一步暴增&#xff0c;硬件资源有点不堪重负&#xff0c;那么&#xff0c;如何实现更好的限流熔断…

腾讯云~Docker安装Redis6.2.6

文章目录1. 测试2. 安装策略组3. 远程连接1. 测试 无密码 docker run \ -d \ --name redis-my \ -v /app/redis/data:/data \ -p 16379:6379 \ redis:6.2.6有密码&#xff08;推荐&#xff09; docker run \ -d \ --name redis-my \ -v /app/redis/data:/data \ -p 16379:63…

中台,很多人理解的都不对

简介&#xff1a; 最近中台比较热&#xff0c;但业界内并没有对中台有统一认可清晰的定义&#xff0c;很多人会把中台与数据仓库、数据湖混为一谈。但需要提醒读者注意的是&#xff0c;数据中台并不是一个系统&#xff0c;它首先是一种组织架构。前言&#xff1a; -更多关于数智…

被“钱”困住的开源开发者们!

「Given enough eyeballs&#xff0c;all bugs are shallow.」&#xff08;只要有足够多的眼睛&#xff0c;就可以让所有 Bug 浮现&#xff09;1997 年&#xff0c;随着《大教堂与集市》的到来&#xff0c;开源新时代的号角正式吹响&#xff0c;也将 Linus 法则深深地烙印在开源…

盘点技术史:流量运营(PC 时代)

简介&#xff1a; 流量分析只比互联网诞生晚几年&#xff0c;作为一个生态&#xff0c;互联网需要有人提供服务&#xff0c;同时也需要有人消费服务&#xff0c;而在互联网上经营服务跟在线下经营五金店一样&#xff0c;如果想要成功&#xff0c;需要时刻关注来访问的顾客的情况…

腾讯云~Docker安装Mariadb

文章目录1. 拉取mariadb镜像2. 创建数据目录3. 创建容器4. 安全策略组5. 远程连接1. 拉取mariadb镜像 docker pull mariadb2. 创建数据目录 创建mariadb容器跟物理机上目录的映射路径&#xff0c;根据实际情况自定义即可 mkdir -p /app/mariadb/data3. 创建容器 docker run…

IDEA打包war包并发布到服务器上

IDEA打包war包并发布到服务器上 1、首先修改pom.xml 1、添加打包方式&#xff0c;打包成war包&#xff0c;否则打包成jar包 <packaging>war</packaging>2、在spring-boot-starter-web添加tomcat <dependency><groupId>org.springframework.boot<…

阿里云荣获可信云容器安全能力先进级认证, ACK/ACR为企业级安全护航

阿里云关注企业级用户的Kubernetes生产落地痛点&#xff0c;结合企业生产环境的大量实践&#xff0c;全面帮助企业真正落地云原生架构。安全侧问题&#xff0c;是众多大中型或金融领域企业的核心关注点。 端到端云原生安全架构 早在2018年&#xff0c;阿里云容器服务团队率先…

Kubernetes 稳定性保障手册(极简版)

作者 | 悟鹏来源 | 阿里巴巴云原生头图 | 下载于视觉中国Kubernetes 在生产环境中的采用率越来越高&#xff0c;复杂度越来越高&#xff0c;由此带来的稳定性保障的挑战越来越大。对于基于 Kubernetes 的云产品&#xff0c;稳定性保障已成为基本诉求&#xff0c;稳定性缺陷会给…

腾讯云~Docker安装Nginx

文章目录一、入门试炼1. 创建挂载目录2. 赋予目录权限3. 临时容器4. 拷贝文件5. 删除临时容器6. 自定义配置启动7. 安全策略组二、 企业内部使用2.1. nacos 集群2.2. 多个域名公用80端口是实现反向代理和负载均衡一、入门试炼 1. 创建挂载目录 mkdir /app/nginx/conf/ /app/n…

1450. 在既定时间做作业的学生人数

在既定时间做作业的学生人数 题目描述 给你两个整数数组 startTime&#xff08;开始时间&#xff09;和 endTime&#xff08;结束时间&#xff09;&#xff0c;并指定一个整数 queryTime 作为查询时间。 已知&#xff0c;第 i 名学生在 startTime[i] 时开始写作业并于 endTim…

开放、普惠、高性能-SLS时序存储助力打造企业级全方位监控方案

无所不在的时序数据 时间带走一切&#xff0c;长年累月会把你的名字、外貌、性格、命运都改变。 ---柏拉图 随着时间的推移&#xff0c;万事万物都在不停的变化&#xff0c;而我们也会用各种数字去衡量这些变化信息&#xff0c;比如年龄、重量、速度、温度、金钱...在数字化时代…

一招上手!这样设计扛住亿级流量活动系统

作者 | 刘艳杰责编 | 伍杏玲出品 | CSDN云计算&#xff08;CSDNcloud)在企业里&#xff0c;做活动是一种十分常见的需求&#xff0c;有面向C端用户开展的活动&#xff0c;也有面向公司内部员工的活动。随着互联网技术的不断发展和疫情等方面的原因&#xff0c;线上开展的活动也…

域名解析到服务器

这本章主要讲购买的域名和服务器怎样进行域名解析。简单来说就是别人访问你的网站只需要在浏览器上输入你购买的域名&#xff0c;就可以访问你搭建的网站。 文章目录1. 解析2. 设置记录类型3. 绑定公网ip1. 解析 2. 设置记录类型 选择A类型 3. 绑定公网ip 效果图 备案 http…