自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JavaScript優(yōu)化技巧

開發(fā) 前端
嘗試訪問對象的屬性時,不僅會在對象上搜索該屬性,還會在對象的原型,原型的原型等上搜索該屬性,直到找到匹配屬性名或原型鏈的末端。

 作為開發(fā)人員,我們一直在尋找讓我們的代碼更快更好的方法。但在此之前,編寫高性能代碼需要做三件事:

  • 了解語言及其工作原理
  • 基于用例進(jìn)行設(shè)計
  • 調(diào)試!修復(fù)!重復(fù)

記住這一點

任何傻瓜都可以編寫計算機(jī)可以理解的代碼,優(yōu)秀的程序員編寫人類可以理解的代碼。- 丁·福勒

我們來看看如何使 JavaScript代碼運行得更快。

延遲

延遲算法將計算延遲到需要執(zhí)行時才執(zhí)行,然后生成結(jié)果。

  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. // 現(xiàn)在,如果有需要在執(zhí)行 
  10. t.map((x) => t()) 

最快的代碼是未執(zhí)行的代碼,所以盡量延遲執(zhí)行。

JavaScript 使用原型繼承,JS 中所有對象都是Object的實例。

MDN說:

嘗試訪問對象的屬性時,不僅會在對象上搜索該屬性,還會在對象的原型,原型的原型等上搜索該屬性,直到找到匹配屬性名或原型鏈的末端。

對于每個屬性,JavaScript引擎都必須遍歷整個對象鏈,直到找到匹配項。如果使用不當(dāng),這會占用大量資源,并影響應(yīng)用程序的性能。

所以不要這樣:

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

而是這樣做:

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

使用臨時變量來保存鏈接的屬性,而不是遍歷訪問整條鏈。

使用轉(zhuǎn)譯器之前要三思

在上述情況下,userResponse可能不是對象,如果是對象,它的屬性 user 也可能不是對象。所以,在獲取值時要進(jìn)行檢查:

  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 就越明顯。我們能把它縮小嗎?當(dāng)然,可以使用 JS 中可選的鏈接、解構(gòu)賦值來優(yōu)化它。

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

是不是很靈活地,簡短?不要使用這個要注意,Babel 會按照以下方式進(jìn)行轉(zhuǎn)換:

  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 

當(dāng)使用轉(zhuǎn)譯時,確保你選擇了一個更適合你的用例的。

了解SMI和堆號

數(shù)字很奇怪,ECMAScript將數(shù)字標(biāo)準(zhǔn)化為64位浮點值,也稱為雙精度浮點或Float64表示形式。

如果 JS 引擎以Float64表示形式存儲數(shù)字,則將導(dǎo)致巨大的性能低下。JS 引擎對數(shù)字進(jìn)行抽象,使其行為與Float64完全匹配。與float64運算相比,JS 引擎執(zhí)行整數(shù)運算的速度要快得多。

有時,我們認(rèn)為像下面這樣寫法可讀比較好:

  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函數(shù)被多次調(diào)用,那么每次調(diào)用它時都會計算它的值。上面的計算并不是什么大問題,因此我們不會注意到任何性能影響。

但是總的來說,運行時的求值的數(shù)量越少,性能就越好。

  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 <UserList /> 
  6.   } 
  7.  
  8.   return <EmptyUserList /> 

在這里,我們在沒有用戶時渲染否則渲染。有大部分人認(rèn)為,我們首先處理所有空的的情況,然后再處理有數(shù)據(jù)的情況。對于任何讀過它的人來說都更清楚,而且效率更高。也就是說,以下代碼比上一個代碼更有效。

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

當(dāng)然 users.length 一直有值的話,就使用第一種情況。

類型是你最好的朋友

JavaScript是解釋型和編譯型語言。為了產(chǎn)生更有效的二進(jìn)制文件,編譯器需要類型信息。但是,作為一種動態(tài)類型化的語言會使編譯器難以進(jìn)行。

編譯器在編譯熱代碼(多次執(zhí)行的代碼)時進(jìn)行一些假設(shè)并優(yōu)化代碼。編譯器花費一些時間來生成此優(yōu)化的代碼。當(dāng)這些假設(shè)失敗時,編譯器必須丟棄優(yōu)化的代碼,并退回到解釋的執(zhí)行方式。這是耗時且昂貴的。

作者:EthicalAds 譯者:前端小智 來源: sendilkumarn

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

本文轉(zhuǎn)載自微信公眾號「 大遷世界 」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系大遷世界公眾號。

 

責(zé)任編輯:武曉燕 來源: 大遷世界
相關(guān)推薦

2024-09-14 11:23:19

2022-07-04 08:51:43

條件語句JavaScript

2022-02-25 23:46:54

JavaScript網(wǎng)站開發(fā)

2011-09-29 09:50:44

JavaScript

2024-09-26 08:36:11

JavaScript性能優(yōu)化

2024-04-03 10:29:13

JavaScrip優(yōu)化技巧

2011-03-25 13:43:54

Cacti優(yōu)化

2020-06-10 08:37:21

JavaScript重構(gòu)技巧

2023-03-19 16:02:33

JavaScrip技巧編程語言

2011-07-01 16:05:22

SEO

2009-06-16 16:39:49

Hibernate性能

2011-03-09 10:55:33

LAMP優(yōu)化技巧

2011-03-10 10:09:33

LAMP優(yōu)化

2011-05-25 20:53:26

SEO

2023-02-07 08:15:45

PostgreSQLIO技巧

2020-09-29 08:14:46

JavaScript開發(fā)代碼

2021-08-26 05:04:53

JavaScript調(diào)試技巧

2019-01-14 08:06:37

JavaScript

2011-06-14 14:17:23

性能優(yōu)化系統(tǒng)層次

2011-07-11 15:26:49

性能優(yōu)化算法
點贊
收藏

51CTO技術(shù)棧公眾號