文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

JavaScript优化技巧

2024-12-03 15:14

关注

记住这一点

任何傻瓜都可以编写计算机可以理解的代码,优秀的程序员编写人类可以理解的代码。- 丁·福勒

我们来看看如何使 JavaScript代码运行得更快。

延迟

延迟算法将计算延迟到需要执行时才执行,然后生成结果。

  1. const someFn = () => { 
  2.   doSomeOperation() 
  3.   return () => { 
  4.     doExpensiveOperation() 
  5.   } 
  6.  
  7. const t = someArray.filter((x) => checkSomeCondition(x)).map((x) => someFn(x)) 
  8.  
  9. // 现在,如果有需要在执行 
  10. t.map((x) => t()) 

最快的代码是未执行的代码,所以尽量延迟执行。

JavaScript 使用原型继承,JS 中所有对象都是Object的实例。

MDN说:

尝试访问对象的属性时,不仅会在对象上搜索该属性,还会在对象的原型,原型的原型等上搜索该属性,直到找到匹配属性名或原型链的末端。

对于每个属性,JavaScript引擎都必须遍历整个对象链,直到找到匹配项。如果使用不当,这会占用大量资源,并影响应用程序的性能。

所以不要这样:

  1. const name = userResponse.data.user.firstname + userResponse.data.user.lastname 

而是这样做:

  1. const user = userResponse.data.user 
  2. const name = user.firstname + user.lastname 

使用临时变量来保存链接的属性,而不是遍历访问整条链。

使用转译器之前要三思

在上述情况下,userResponse可能不是对象,如果是对象,它的属性 user 也可能不是对象。所以,在获取值时要进行检查:

  1. let name = '' 
  2. if (userResponse) { 
  3.   const data = userResponse.data 
  4.   if (data && data.user) { 
  5.     const user = data.user 
  6.     if (user.firstname) { 
  7.       name += user.firstname 
  8.     } 
  9.     if (user.lastname) { 
  10.       name += user.firstname 
  11.     } 
  12.   } 

这太啰嗦了。代码越多,bug 就越明显。我们能把它缩小吗?当然,可以使用 JS 中可选的链接、解构赋值来优化它。

  1. const user = userResponse?.data?.user 
  2. const { firstname = '', lastname = ''} = user 
  3. const name = firstname + lastname 

是不是很灵活地,简短?不要使用这个要注意,Babel 会按照以下方式进行转换:

  1. 'use strict' 
  2.  
  3. var _userResponse, _userResponse$data 
  4.  
  5. var user = 
  6.   (_userResponse = userResponse) === null || _userResponse === void 0 
  7.     ? void 0 
  8.     : (_userResponse$data = _userResponse.data) === null || 
  9.       _userResponse$data === void 0 
  10.     ? void 0 
  11.     : _userResponse$data.user 
  12. var _user$firstname = user.firstname, 
  13.   firstname = _user$firstname === void 0 ? '' : _user$firstname, 
  14.   _user$lastname = user.lastname, 
  15.   lastname = _user$lastname === void 0 ? '' : _user$lastname 
  16. var name = firstname + lastname 

当使用转译时,确保你选择了一个更适合你的用例的。

了解SMI和堆号

数字很奇怪,ECMAScript将数字标准化为64位浮点值,也称为双精度浮点或Float64表示形式。

如果 JS 引擎以Float64表示形式存储数字,则将导致巨大的性能低下。JS 引擎对数字进行抽象,使其行为与Float64完全匹配。与float64运算相比,JS 引擎执行整数运算的速度要快得多。

有时,我们认为像下面这样写法可读比较好:

  1. const maxWidth = '1000' 
  2. const minWidth = '100' 
  3. const margin = '10' 
  4. getWidth = () => ({ 
  5.   maxWidth: maxWidth - margin * 2, 
  6.   minWidth: minWidth - margin * 2, 
  7. }) 

评估局部变量

如果getWidth函数被多次调用,那么每次调用它时都会计算它的值。上面的计算并不是什么大问题,因此我们不会注意到任何性能影响。

但是总的来说,运行时的求值的数量越少,性能就越好。

  1. // maxWidth - (margin * 2) 
  2. const maxWidth = '980' 
  3. // minWidth - (margin * 2) 
  4. const minWidth = '80' 
  5. const margin = '10' 
  6. getWidth = () => ({ 
  7.   maxWidth, 
  8.   minWidth, 
  9. }) 

使用 Map 而不是 switch/if-else 条件

如果要检查多个条件时,可以使用Map代替 switch/if-else条件。在Map中查找元素的性能比对switch和if-else条件快得多。

  1. switch (day) { 
  2.   case 'monday'
  3.     return 'workday' 
  4.   case 'tuesday'
  5.     return 'workday' 
  6.   case 'wednesday'
  7.     return 'workday' 
  8.   case 'thursday'
  9.     return 'workday' 
  10.   case 'friday'
  11.     return 'workday' 
  12.   case 'saturday'
  13.     return 'funday' 
  14.   case 'sunday'
  15.     return 'funday' 
  16.  
  17. // or this 
  18.  
  19. if ( 
  20.   day === 'monday' || 
  21.   day === 'tuesday' || 
  22.   day === 'wednesday' || 
  23.   day === 'thursday' || 
  24.   day === 'friday' 
  25.   return 'workday' 
  26. else return 'funday' 

上面可以使用 Map 来代替

  1. const m = new Map([ 
  2.     ['monday','workday'], 
  3.     ['tuesday''workday'], 
  4.     ['wednesday''workday'], 
  5.     ['thursday''workday'], 
  6.     ['friday''workday'], 
  7.     ['saturday''funday'], 
  8.     ['sunday''funday'
  9. ]; 
  10.  
  11. return m.get(day); 

if-else 排序

在 React组件中,这种写法还是很常见的。

  1. export default function UserList(props) { 
  2.   const { users } = props 
  3.  
  4.   if (users.length) { 
  5.     return  
  6.   } 
  7.  
  8.   return  

在这里,我们在没有用户时渲染否则渲染。有大部分人认为,我们首先处理所有空的的情况,然后再处理有数据的情况。对于任何读过它的人来说都更清楚,而且效率更高。也就是说,以下代码比上一个代码更有效。

  1. export default function UserList(props) { 
  2.   const { users } = props 
  3.  
  4.   if (!users.length) { 
  5.     return  
  6.   } 
  7.  
  8.   // some resource intensive operation 
  9.   return  

当然 users.length 一直有值的话,就使用第一种情况。

类型是你最好的朋友

JavaScript是解释型和编译型语言。为了产生更有效的二进制文件,编译器需要类型信息。但是,作为一种动态类型化的语言会使编译器难以进行。

编译器在编译热代码(多次执行的代码)时进行一些假设并优化代码。编译器花费一些时间来生成此优化的代码。当这些假设失败时,编译器必须丢弃优化的代码,并退回到解释的执行方式。这是耗时且昂贵的。

作者:EthicalAds 译者:前端小智 来源: sendilkumarn

原文:https://sendilkumarn.com/blog/javascript-optimization/

本文转载自微信公众号「 大迁世界 」,可以通过以下二维码关注。转载本文请联系大迁世界公众号。

 

来源: 大迁世界内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯