提升JavaScript加載速度的10種方式
1. 懶加載
并不是所有的 JavaScript 都需要在用戶第一次打開網(wǎng)站時加載。例如,你可能在頁面底部有一個郵箱注冊功能。除非用戶瀏覽到這里,否則沒必要去加載。因此,許多 Web 開發(fā)人員使用了一種懶加載的技術(shù)。相對于一次性加載所有的 JavaScript,懶加載只會加載當(dāng)前會用到的部分 JavaScript。
懶加載有多種實(shí)現(xiàn)方式。例如,部分元素不需要立即就能交互,而是需要盡快的可以交互,你可以等到頁面加載完后使用 requestIdleCallback()
?;蛘呦裎覀冎罢f的那樣,如果有一個不許壓迫立即交互的元素在頁面底部,你可以使用 intersectionObserver
監(jiān)聽元素,等到用戶瀏覽到這個元素時再加載。
現(xiàn)在問題是:如何讓代碼懶加載?最好的方式是:動態(tài) import
,它是 ESM 的一部分。使用 import()
可以讓你在任何時候加載 JavaScript。例如,這將在瀏覽器空閑時加載一個 JavaScript:
requestIdleCallback(() => { import("/script.mjs"); });
另外一個實(shí)現(xiàn)懶加載的方式是:script
標(biāo)簽的 async
和 defer
屬性。這個技術(shù)沒有拓展性,但是它可以非常簡單的實(shí)現(xiàn)當(dāng) DOM 加載完后在加載 JavaScript。
2. 最小化
最小化是提高性能的一個簡單方法。它通常是通過Terser或ESBuild這樣的自動最小化工具完成的。這些工具通過刪除間距、長的變量名以及其他在開發(fā)中很有幫助但在生產(chǎn)中會增加腳本大小的東西來縮小你的代碼。例如,假設(shè)我用Terser對這段代碼進(jìn)行了縮減:
window.addEventListener("DOMContentLoaded", (event) => { const images = document.getElementsByTagName("img"); for (const image of images) { image.width = 50; image.height = 50; } });
最后的結(jié)果為:
window.addEventListener("DOMContentLoaded", (e) => { const t = document.getElementsByTagName("img"); for (const e of t) (e.width = 50), (e.height = 50); });
這就是減少了67個字節(jié),從203個字節(jié)減少到136個字節(jié)!這一點(diǎn)不會產(chǎn)生明顯的差異,但對于較大的腳本,最小化可以產(chǎn)生相當(dāng)大的影響。
3. Bundling
腳本大小不是唯一重要的事情。請求數(shù)也很重要,因?yàn)槊總€請求都會增加開銷?;旧希阆氚涯愕哪_本數(shù)量保持在最低限度。然而,拆分代碼通常是保持代碼清潔的一種代碼做法。幸運(yùn)的是,像minifiers一樣,有自動化的工具來解決這個問題。這些被稱為捆綁器。捆綁器分析你的代碼,查看哪些腳本在相互導(dǎo)入,并找出如何組合它們。最知名的捆綁器是Webpack、Rollup和Vite。
使用捆綁器的另一個好處是,大多數(shù)捆綁器也可以作為構(gòu)建工具,使其很容易進(jìn)行減化和TypeScript編譯等工作。關(guān)于捆綁器的更多信息,請查看我關(guān)于捆綁器的文章。
4. 代碼拆分
你可能會驚訝,這就在打包之后。"我打包我的代碼只是為了把它拆開?"不一定。事實(shí)上,這也是打包工具的一個特點(diǎn)。雖然減少請求數(shù)是很好的,但你不希望用戶不得不一次性加載你網(wǎng)站上的所有代碼。你可以通過為每個頁面創(chuàng)建一個新的完整的打包程序來解決這個問題,但這將否定緩存的一些好處(我們將在后面談及)。為了解決這個問題,我們有代碼拆分。代碼拆分結(jié)合了打包和懶惰加載的優(yōu)點(diǎn),同時確保不加載頁面的任何不必要的代碼。打包工具通過分析導(dǎo)入的地圖來執(zhí)行代碼分割,并找出哪些腳本需要放在自己的捆綁中。大多數(shù)打包工具都是自動完成的,盡管編寫更容易分析的代碼是有幫助的(例如,盡可能使用靜態(tài)導(dǎo)入)。
5. Tree Shaking
捆綁器的另一個共同特征是樹狀搖晃。你可能會導(dǎo)入一個庫的一部分,但不需要其他部分。然而,如果你在沒有樹狀搖動的情況下這樣做,最終用戶將最終加載整個庫,這可能會增加大量的JavaScript。樹狀搖動解決了這個問題;支持樹狀搖動的捆綁器會自動刪除庫中未使用的部分,從而大量減少你導(dǎo)入的代碼。例如,看看Lodash(具體來說是lodash-es),一個大型的JavaScript工具庫。整個模塊幾乎有100千字節(jié),但如果你只使用intersect()函數(shù),你將只導(dǎo)入2.7千字節(jié)的代碼。現(xiàn)在,在Lodash的情況下,有一些包只包含單個函數(shù),但如果你使用大量的函數(shù),這些包使用起來會比較麻煩,很多庫都不這樣做。
6. ES 模塊
為了使前面提到的許多功能發(fā)揮作用,ECMAScript Modules(ESM)是非常有用的,甚至是必不可少的。ESM是一個模塊規(guī)范,是為了規(guī)范不同文件之間的代碼共享方式而開發(fā)的。在ESM之前,有一些相互沖突的標(biāo)準(zhǔn),如CommonJS和UMD,它們甚至不被瀏覽器原生支持。ESM統(tǒng)一了這些標(biāo)準(zhǔn),并提供了有助于實(shí)現(xiàn)樹狀搖動等功能的語法(注意我在前面說的使用lodash-es而不是標(biāo)準(zhǔn)lodash)。此外,由于ESM在瀏覽器中被原生支持,你不需要一個沉重的polyfill就能使用ESM。
// ESM import { something } from "test"; export const something = "test"; // CJS const something = require("test").something; module.exports.something = "test";
7. CDN
在你自己的服務(wù)器上托管靜態(tài)文件是毫無意義的。使用一個完整的服務(wù)器進(jìn)行實(shí)際的服務(wù)器端計(jì)算會增加你的成本、開發(fā)的復(fù)雜性和網(wǎng)站的加載時間。相反,CDN是更好的解決方案。CDN(內(nèi)容交付網(wǎng)絡(luò))是一個服務(wù)器網(wǎng)絡(luò),旨在快速和廉價地提供靜態(tài)文件。你可以從幾十或幾百個服務(wù)器(取決于CDN)提供文件,而不是只從一個服務(wù)器提供服務(wù),這樣可以減少延遲,因?yàn)榉?wù)器離用戶更近。此外,CDN經(jīng)常為你配置緩存和壓縮等功能,節(jié)省時間。一些流行的CDN的例子是Cloudflare CDN和亞馬遜的 CloudFront。
8. 緩存
雖然首次加載體驗(yàn)是至關(guān)重要的,但你也需要考慮到網(wǎng)站重復(fù)訪問者的性能。使重復(fù)訪問明顯加快的一個方法是通過緩存。瀏覽器緩存的作用是保存網(wǎng)站資源的副本,并使用該副本而不是再次下載。這意味著重復(fù)訪問的感覺幾乎是即時的。要設(shè)置緩存,你需要在響應(yīng)中為你要緩存的資源設(shè)置Cache-Control頭。如果你使用的是CDN,這很可能是自動為你配置的。如果你沒有,設(shè)置起來也很簡單。
9. 壓縮
我相信你已經(jīng)遇到了.zip或.tag.gz文件。你可能也知道,在將目錄轉(zhuǎn)化為文件的同時,它們也減少了文件的大小。大小的減少是通過壓縮完成的。壓縮的工作原理是運(yùn)行一種算法,通過縮小重復(fù)的語句和做一些其他事情來使文件變小,這取決于使用的算法。有許多流行的壓縮算法,如deflate、lz4、Brotli和Zstandard。zip和gzipped文件使用的壓縮算法是deflate。
實(shí)現(xiàn)壓縮可能有點(diǎn)難,但也有簡單的方法。最簡單的方法是使用能自動壓縮文件的CDN,正如我們在第7條談到的。另一個實(shí)現(xiàn)壓縮的簡單方法是運(yùn)行一個支持壓縮的文件服務(wù)器。然而,如果你不能做到這兩點(diǎn),還有一些其他的解決方案。很多構(gòu)建工具/捆綁器都有自動生成壓縮形式的文件的插件,你可以將其提供給瀏覽器自動解壓。瀏覽器用Accept-Encoding頭告訴你它支持什么壓縮算法,而你的服務(wù)器用Content-Encoding頭告訴瀏覽器在響應(yīng)中使用什么壓縮算法。欲了解更多信息,請查看MDN關(guān)于HTTP壓縮的文章。
10. Lighthouse
Lighthouse是一個幫助你自動審核網(wǎng)站性能的工具,同時還包括其他一些類別,如搜索引擎優(yōu)化和可訪問性。它對于發(fā)現(xiàn)性能問題并提供解決這些問題的便捷途徑非常有幫助。如果你有Chrome或其他基于Chromium的瀏覽器,Lighthouse應(yīng)該是默認(rèn)可用的。如果你使用其他瀏覽器,你可以下載擴(kuò)展程序或使用PageSpeed Insights。PageSpeed Insights還提供了來自真實(shí)用戶的數(shù)據(jù),如果你想了解用戶的實(shí)際體驗(yàn),這將會很有幫助。
總結(jié)
有了這些提示,你應(yīng)該在你的網(wǎng)站上取得較大的性能收益,轉(zhuǎn)化為更多的保留和轉(zhuǎn)換。
以上就是提升JavaScript加載速度的10種方式的詳細(xì)內(nèi)容,更多關(guān)于提升JavaScript加載速度的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS實(shí)現(xiàn)可展開折疊層的鼠標(biāo)拖曳效果
這篇文章主要介紹了JS實(shí)現(xiàn)可展開折疊層的鼠標(biāo)拖曳效果,具有展開折疊層及實(shí)時顯示鼠標(biāo)坐標(biāo)位置的功能,具有一定參考借鑒價值,需要的朋友可以參考下2015-10-10web頁面和微信小程序頁面實(shí)現(xiàn)瀑布流效果
這篇文章主要介紹了web頁面和微信小程序頁面實(shí)現(xiàn)瀑布流效果,本文通過實(shí)例代碼圖文介紹,給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下2018-09-09JavaScript判斷是否為數(shù)字的幾種方式匯總(推薦!)
有時候需要根據(jù)輸入的內(nèi)容來進(jìn)行計(jì)算,這個時候就需要判斷輸入的內(nèi)容是否是數(shù)字,下面這篇文章主要給大家介紹了關(guān)于JavaScript判斷是否為數(shù)字的幾種方式,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06微信小程序使用checkbox顯示多項(xiàng)選擇框功能【附源碼下載】
這篇文章主要介紹了微信小程序使用checkbox顯示多項(xiàng)選擇框功能,涉及相關(guān)事件綁定與元素遍歷操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2017-12-12layui的select聯(lián)動實(shí)現(xiàn)代碼
今天小編就為大家分享一篇layui的select聯(lián)動實(shí)現(xiàn)代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09js window.onload 加載多個函數(shù)的方法
平時做項(xiàng)目 經(jīng)常需要使用window.onload,但window.onload 不能同時加載多個函數(shù)。2009-11-11表單元素值獲取方式j(luò)s及java方式的簡單實(shí)例
下面小編就為大家?guī)硪黄韱卧刂但@取方式j(luò)s及java方式的簡單實(shí)例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-10-10