成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript 性能優(yōu)化技巧分享

shixinzhang / 1342人閱讀

摘要:即使這些動(dòng)畫(huà)庫(kù)使用轉(zhuǎn)換,合成屬性和,但是它們?nèi)匀贿\(yùn)行在的主線程上。另一方面,動(dòng)畫(huà)和轉(zhuǎn)換會(huì)在主線程中運(yùn)行,如果能夠高效執(zhí)行,則能避免重新布局重排的情況出現(xiàn)。是一個(gè)即將到來(lái)的功能集,它能夠脫離主線程執(zhí)行高性能的動(dòng)畫(huà)。

JavaScript 作為當(dāng)前最為常見(jiàn)的直譯式腳本語(yǔ)言,已經(jīng)廣泛應(yīng)用于 Web 應(yīng)用開(kāi)發(fā)中。為了提高Web應(yīng)用的性能,從 JavaScript 的性能優(yōu)化方向入手,會(huì)是一個(gè)很好的選擇。

本文從加載、上下文、解析、編譯、執(zhí)行和捆綁等多個(gè)方面來(lái)講解 JavaScript 的性能優(yōu)化技巧,以便讓更多的前端開(kāi)發(fā)人員掌握這方面知識(shí)。

什么是高性能的 JavaScript 代碼?

盡管目前沒(méi)有高性能代碼的絕對(duì)定義,但卻存在一個(gè)以用戶為中心的性能模型,可以用作參考:RAIL模型。

響應(yīng)

如果你的應(yīng)用程序能在100毫秒內(nèi)響應(yīng)用戶的操作,那么用戶會(huì)認(rèn)為該響應(yīng)為即時(shí)的。這適用于可點(diǎn)擊的元素,不適用于滾動(dòng)或拖動(dòng)操作。

動(dòng)畫(huà)

在60Hz的顯示器上,我們希望動(dòng)畫(huà)和滾動(dòng)時(shí)每秒有60幀,這種情況下每幀大約為16ms。在這16ms的時(shí)間內(nèi),實(shí)際上只有8-10ms來(lái)完成所有工作,其余時(shí)間則由瀏覽器的內(nèi)部和其它差異占據(jù)。

空閑工作

如果你有一個(gè)耗時(shí)很久,需要持續(xù)運(yùn)行的任務(wù)時(shí),請(qǐng)確保把它分成很小的塊,以便允許主線程對(duì)用戶的輸入操作做出反應(yīng)。不應(yīng)該出現(xiàn)一個(gè)任務(wù)延遲超過(guò)50ms的用戶輸入。

加載

頁(yè)面加載應(yīng)該在1000毫秒內(nèi)完成。在移動(dòng)設(shè)備上,這是一個(gè)很難達(dá)到的目標(biāo),因?yàn)樗婕暗巾?yè)面的互動(dòng),而不僅僅是在屏幕上渲染和滾動(dòng)。

讓我們來(lái)看看一些統(tǒng)計(jì)數(shù)據(jù):

如果移動(dòng)網(wǎng)站的加載時(shí)間超過(guò)三秒,則會(huì)有53%的用戶放棄訪問(wèn)

50%的用戶希望在不到2秒的時(shí)間內(nèi)完成頁(yè)面加載

77%的移動(dòng)網(wǎng)站需要10秒以上的時(shí)間來(lái)加載3G網(wǎng)絡(luò)

19秒是3G網(wǎng)絡(luò)上移動(dòng)站點(diǎn)的平均加載時(shí)間

代碼內(nèi)容

你可能已經(jīng)注意到了,最大的瓶頸是加載網(wǎng)站所需的時(shí)間。具體來(lái)說(shuō)就是 JavaScript 的下載、解析、編譯和執(zhí)行時(shí)間。除了加載更少的 JavaScript 文件或者加載的更加靈活以外,看起來(lái)沒(méi)有其它辦法。

除去啟動(dòng)網(wǎng)站之外,JavaScript 代碼又是如何實(shí)際工作的呢?

在進(jìn)行代碼優(yōu)化之前,請(qǐng)考慮你當(dāng)前正在構(gòu)建的內(nèi)容。你正在建立的是一個(gè)框架還是一個(gè) VDOM 庫(kù)?你的代碼是否需要每秒執(zhí)行數(shù)千次操作?你是否正在做一個(gè)對(duì)時(shí)間要求較為嚴(yán)格的庫(kù)來(lái)處理用戶輸入和/或動(dòng)畫(huà)?如果沒(méi)有,你需要把時(shí)間和精力轉(zhuǎn)移到更有影響力的地方。

編寫(xiě)高性能代碼并不是那么重要,因?yàn)閷?duì)于宏觀計(jì)劃通常沒(méi)有什么影響。50k ops/s 聽(tīng)起來(lái)好于 1k ops/s,但在大多數(shù)情況下整體時(shí)間并不會(huì)有所改變。

解析、編譯和執(zhí)行

從根本上說(shuō),大多數(shù) JavaScript 的性能問(wèn)題,并不在于運(yùn)行代碼本身,而是在代碼開(kāi)始執(zhí)行之前必須采取的一系列步驟。

我們?cè)谶@里討論抽象層次的問(wèn)題。計(jì)算機(jī)上運(yùn)行的大多數(shù)代碼都是編譯后的二進(jìn)制格式。意思是說(shuō),除了所有的操作系??統(tǒng)級(jí)別的抽象外,代碼都可以在硬件上本地運(yùn)行,不需要準(zhǔn)備工作。

JavaScript 代碼不是預(yù)編譯的,它在瀏覽器上是可讀的。

JavaScript 代碼首先會(huì)被解析,也就是讀取并轉(zhuǎn)換成可用于編譯的計(jì)算機(jī)索引的結(jié)構(gòu),然后再被編譯成字節(jié)碼,最后被編譯成機(jī)器碼,用于設(shè)備/瀏覽器執(zhí)行。

另一個(gè)非常重要的方面是:JavaScript 是單線程的,并且在瀏覽器的主線程上運(yùn)行。這意味著一次只能運(yùn)行一個(gè)進(jìn)程。如果你的 DevTools 性能時(shí)間線充滿黃色峰值,同時(shí) CPU 占用率達(dá)到100%,則將出現(xiàn)丟幀的情況。這是滾動(dòng)操作常出現(xiàn)的,也是很討厭的一種情況。

在 JavaScript 代碼運(yùn)行之前,需要完成所有的這些解析、編譯和執(zhí)行工作。在 ChromeV8 引擎中,解析和編譯占 JavaScript 執(zhí)行總時(shí)間的50%左右。

所以在這部分中,應(yīng)該了解兩件事情:

雖然 JavaScript 解析的時(shí)間長(zhǎng)度和包的大小不是完全線性的,但是需要處理的 JavaScript 越少,則所花時(shí)間越少。

你使用的每一個(gè) JavaScript 框架(React,Vue,Angular,Preact ...)都是另一個(gè)抽象層次(除非它是一個(gè)預(yù)編譯的)。這不僅會(huì)增加你的包的大小,而且會(huì)讓你的代碼變慢,因?yàn)槟悴皇侵苯优c瀏覽器通信的。

有些方法可以緩解這種情況,比如使用 service workers 在后臺(tái)的另一個(gè)線程中執(zhí)行部分工作,或者使用 asm.js 編寫(xiě)更容易編譯機(jī)器指令的代碼。

我們所能做的,就是避免使用 JavaScript 動(dòng)畫(huà)庫(kù)。只有在使用常規(guī)的 CSS 轉(zhuǎn)換和動(dòng)畫(huà)完全無(wú)法實(shí)現(xiàn)時(shí),才去使用這些庫(kù)。

即使這些 JavaScript 動(dòng)畫(huà)庫(kù)使用 CSS 轉(zhuǎn)換,合成屬性和 requestAnimationFrame( ),但是它們?nèi)匀贿\(yùn)行在 JavaScript 的主線程上?;旧线@些庫(kù)會(huì)使用內(nèi)聯(lián)樣式每16ms訪問(wèn)一次 DOM。你需要確保所有的 JavaScript 都在每幀8ms以內(nèi)完成,才能保持動(dòng)畫(huà)的平滑性。

另一方面,CSS 動(dòng)畫(huà)和轉(zhuǎn)換會(huì)在主線程中運(yùn)行,如果能夠高效執(zhí)行,則能避免重新布局/重排的情況出現(xiàn)。

考慮到大多數(shù)動(dòng)畫(huà)都在加載或用戶交互的過(guò)程中運(yùn)行,這可以為你的 web 應(yīng)用程序提供非常重要的調(diào)整空間。

web Animations API 是一個(gè)即將到來(lái)的功能集,它能夠脫離主線程執(zhí)行高性能的 JavaScript 動(dòng)畫(huà)。但就目前而言,還需要繼續(xù)使用 CSS 轉(zhuǎn)換等技術(shù)。

捆綁尺寸非常重要

現(xiàn)在已經(jīng)不再是在 結(jié)束標(biāo)簽之前包含有多個(gè)

閱讀需要支付1元查看
<