簡體   English   中英

如何優化服務和加載JavaScript文件?

[英]How to optimally serve and load JavaScript files?

我希望有更多全球規模網絡應用程序經驗的人可以澄清一些問題,假設和可能的誤解。

讓我們來看一個假想的網站(大量的客戶端/動態組件),它在全球擁有數十萬用戶,並且來自一個地方(比如中歐)。

  1. 如果應用程序依賴於流行的JavaScript庫,那么從Google CDN中獲取它並將其編譯成一個簡化的JS文件(以及所有特定於應用程序的JavaScript)或者將其與Google CDN分開加載會更好嗎?
  2. Assetic VS headjs :加載一個JS文件或並行加載所有腳本(按依賴順序執行)更有意義嗎?

我的假設 (請糾正我):

將所有特定於應用程序的/本地JS代碼編譯到一個文件中,使用像Google這樣的流行庫等CDN,但是通過headjs並行加載所有這些代碼似乎是最佳的,但我不確定。 服務器端將第三方JS和特定於應用程序的JS編譯到一個文件中似乎幾乎打敗了使用CDN的目的,因為無論如何庫都可能緩存在用戶的某個位置。

除了緩存之外,從Google的CDN下載第三方庫可能比托管應用程序的中央服務器更快。

如果一個流行的JS庫的新版本發布並帶來了很大的性能提升,那么就可以使用該應用程序進行測試,然后實現:

  • 如果所有JS都編譯成一個文件,那么即使應用程序代碼沒有改變,每個用戶也必須重新下載該文件。
  • 如果從CDN加載第三方腳本,則用戶僅從CDN(或從某處的緩存)下載新版本。

在描述的情況下,是否存在以下任何合理的擔憂?

  • 某些用戶(或瀏覽器)一次只能與一個主機名建立一定數量的連接,因此從第三方CDN檢索某些腳本將導致整體加載時間更快。
  • 某些用戶可能在受限制的環境中使用該應用程序,因此該應用程序的域可能是白名單但不是CDN的域。 (如果這可能是現實問題,是否可以嘗試從CDN加載並在發生故障時從中央服務器加載?)

將所有特定於應用程序的/本地JS代碼編譯到一個文件中

由於我們的一些關鍵目標是減少HTTP請求的數量最小化請求開銷 ,因此這是一種非常廣泛采用的最佳實踐。

我們可能認為不這樣做的主要情況是頻繁緩存失效的可能性很大,即當我們對代碼進行更改時。 這里總會有權衡:提供單個文件很可能會增加緩存失效率,而提供許多單獨的文件可能會導致緩存為空的用戶啟動較慢。

出於這個原因,偶爾插入一些特定於頁面的JavaScript並不像有些人說的那么邪惡。 一般來說,將JS連接和縮小為一個文件是一個很好的第一步。

使用像谷歌這樣的CDN用於流行的圖書館等。

如果我們討論的是我們正在使用的代碼是相當不可變的庫,即不太可能受到高速緩存失效的影響,我可能會更傾向於通過將它們包裝到單片本地JS文件中來保存HTTP請求。 對於大量基於例如特定jQuery版本的大型代碼庫來說尤其如此。 在這樣的情況下,庫版本幾乎肯定會涉及對客戶端應用程序代碼的重大更改,否定將它們分開的優勢。

盡管如此, 混合請求域是一個重要的勝利 ,因為我們不希望被每個域名上限的最大連接過度限制。 當然,子域名也可以用於此,但Google的域名具有無cookie的優勢,並且可能已經在客戶端的DNS緩存中。

但通過headjs並行加載所有這些似乎是最佳的

雖然新興的JavaScript“加載器”主機有優勢,但我們應該記住,使用它們會對頁面啟動產生負面影響,因為瀏覽器需要在加載器請求其余資產之前獲取加載器。 換句話說,對於具有空緩存的用戶,在開始任何實際加載之前需要到服務器的完整往返。 同樣,“編譯”步驟可以解決 - 請參閱require.js以獲得出色的混合實現。

確保腳本不阻止UI繪制的最佳方法仍然是將它們放在HTML的末尾。 如果您寧願將它們放在別處,那么asyncdefer屬性現在可以為您提供靈活性。 所有現代瀏覽器並行請求資產,因此除非您需要支持特定版本的舊客戶端,否則這不應該是主要考慮因素。 Browserscope網絡表是這類事物的絕佳參考。 IE8可以預見為主要攻擊者,在加載腳本之前仍會阻止圖像和iFrame請求。 即使回到3.6, Firefox也完全並行化了iFrames。

某些用戶可能在受限制的環境中使用該應用程序,因此該應用程序的域可能是白名單但不是CDN的域。 (如果這可能是現實問題,是否可以嘗試從CDN加載並在發生故障時從中央服務器加載?)

如果客戶端計算機可以訪問遠程主機,則總是會導致嚴重的性能損失,因為我們必須等待它才能加載我們的保留副本之前無法連接。 我更傾向於在本地托管這些資產。

  1. 由於許多原因(包括更改/依賴性/要求),許多小js文件比少數大文件更好。
  2. 任何當前的Web服務器(Apache / IIS和許多其他服務器)都可以非常有效地處理JavaScript / css / html和任何其他靜態內容,大多數情況下,一個Web服務器能夠滿足100s和1000s請求/秒的速度。無論如何,這個靜態內容很可能會緩存在客戶端和服務器之間的某個位置。
  3. 使用任何外部(不受你控制)存儲庫來獲取你想在生產環境中使用的代碼是NO-NO(對於我和許多其他人),你不希望整個站點發生突然的,災難性的和不可恢復的故障JavaScript功能只是因為有人在沒有思考或檢查的情況下按下提交。

將所有特定於應用程序的/本地JS代碼編譯到一個文件中,使用像谷歌這樣的CDN用於流行的庫等,但通過headjs並行加載所有這些代碼似乎是最佳的......

我說這基本上是正確的。 不要將多個外部庫組合到一個文件中,因為 - 正如您所知道的那樣 - 這將否定用戶瀏覽器已經緩存(個別)資源的大部分情況。

對於您自己的特定於應用程序的JS代碼,您可能想要考慮的一個因素是更新它的頻率。 例如,如果有一個功能核心不經常更改,但一些較小的組件可能會定期更改,那么只有編譯(我認為你的意思是縮小/壓縮)核心成為一個文件,同時繼續為其提供服務可能是有意義的。零碎的小零件。

您的決定還應考慮您的JS資產的大小。 如果 - 並且這不太可能,但可能 - 你正在服務大量的JavaScript,將它們連接成一個文件可能會適得其反,因為一些客戶端(例如移動設備)對它們將緩存的內容有非常嚴格的限制。 在這種情況下,您最好還是提供一些較小的資產。

這些只是隨機花絮,你要注意。 我想說的主要觀點是你的第一直覺(如上所述)可能是正確的方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM