最佳化啟動效能

提高應用程式的啟動效能通常是具有最高價值的效能最佳化之一。您的應用程式需要多長時間才能啟動?在應用程式載入時,它是否會鎖定裝置或使用者的瀏覽器?這會讓使用者擔心您的應用程式已崩潰,或者其他地方出了問題。良好的使用者體驗包括確保您的應用程式能夠快速載入。本文提供了有關編寫新應用程式和將其他平臺的應用程式移植到 Web 的效能技巧和建議。

快速非同步載入

無論平臺如何,儘快啟動始終是一個好主意。既然這是一個普遍的問題,我們在這裡不會過多關注它。相反,我們將關注構建 Web 應用程式時一個更重要的問題:儘可能地非同步啟動。這意味著不要在應用程式主執行緒的單個事件處理程式中執行所有啟動程式碼。

相反,建立一個 Web Worker,該 Worker 在後臺執行緒中儘可能多地完成工作(例如,獲取和處理資料)。將任務分配給 Web Worker 可以將主執行緒釋放出來處理需要它的任務,例如使用者事件和渲染 UI。反過來,主執行緒事件應包含許多小任務,也稱為 微任務,而不是更大、更耗時的任務。

非同步載入有助於防止頁面和使用者介面看起來(或實際上成為)無響應。透過最小化任何單個載入任務所需的時間,應用程式的 事件迴圈將在啟動時繼續迴圈。這將防止應用程式、瀏覽器和/或裝置看起來像是凍結了。

在最壞的情況下,阻塞主執行緒可能導致使用者解除安裝您的應用程式;例如,如果有人錯誤地啟動了您的應用程式,並且他們無法阻止關閉該應用程式,他們可能希望採取措施以防止這種情況再次發生。

有志者事竟成……

一開始就以“正確的方式”編寫一切,比事後補救以提高效能(和可訪問性)要容易得多。當您從頭開始時,將適當的程式碼塊非同步化意味著無需事後補救。所有純啟動計算都應在後臺執行緒中執行,同時保持主執行緒事件的執行時間儘可能短。不要包含進度指示器來告知使用者正在發生什麼以及他們需要等待多長時間,而是讓進度條變得不必要。

另一方面,將現有應用程式移植到 Web 可能具有挑戰性。原生應用程式不需要以非同步方式編寫,因為作業系統通常會為您處理載入。源應用程式可能有一個主迴圈,可以輕鬆地使其非同步執行(透過單獨執行每個主迴圈迭代);啟動通常只是一個連續的、整體的過程,可能會定期更新進度計。

雖然您可以使用 Web Worker 來非同步執行甚至非常大、耗時很長的 JavaScript 程式碼塊,但有一個巨大的警告:Web Worker 不能直接操作 DOM,並且對 Window 物件的方法和屬性的訪問許可權有限,包括無法訪問 WebGL。所有這些都意味著,除非您可以輕鬆地將啟動過程中的“純計算”塊提取到 worker 中,否則您最終將不得不在主執行緒上執行大部分或全部啟動程式碼。

但是,即使是這樣的程式碼,透過一些努力也可以使其非同步。

實現非同步

以下是一些關於如何使您的啟動過程儘可能非同步化的建議(無論是新應用程式還是移植應用程式)

  • 在 Web 應用程式所需的指令碼標籤上使用 deferasync 屬性。這允許 HTML 解析器繼續處理文件,而不必等到指令碼下載並執行後才能繼續。
  • 如果您需要解碼資原始檔(例如,解碼 JPEG 檔案並將其轉換為原始紋理資料供 WebGL 後續使用),那麼在 worker 中進行這項工作非常出色。
  • 在處理瀏覽器支援的資料時(例如,解碼影像資料),請使用瀏覽器或裝置內建的解碼器,而不是自己編寫或使用原始程式碼庫中的解碼器。提供的解碼器幾乎肯定會快得多,並且還可以減小您的應用程式大小。此外,瀏覽器可能會自動並行化這些解碼器。
  • 任何可以並行處理的資料都應該並行處理。不要一次處理一塊資料,而是在可能的情況下一次性處理所有資料!
  • 不要在啟動 HTML 檔案中包含不參與 關鍵渲染路徑 的指令碼或樣式表。僅在需要時載入它們。
  • 減小 JavaScript 檔案的大小。嘗試將檔案的最小化版本傳送到瀏覽器,並使用 Gzip 或 Brotli 等壓縮技術。
  • 儘可能利用資源提示(例如 preconnect 或 preload),向瀏覽器指示哪些檔案對您的應用程式更關鍵。

您可以非同步處理的事情越多,您的應用程式就能越好地利用多核處理器。

移植問題

一旦初始載入完成並且應用程式的主程式碼開始執行,您的應用程式可能必須是單執行緒的,特別是如果它是移植的。為幫助主程式碼的啟動過程,最重要的事情是重構程式碼以分成小的片段。然後,這些片段可以在應用程式的主迴圈的多個呼叫之間穿插執行(這樣主執行緒就可以處理輸入等)。

Emscripten 提供了一個 API 來幫助進行這種重構;例如,您可以使用 emscripten_push_main_loop_blocker() 來建立一個在主執行緒繼續執行之前執行的函式。透過建立一個要按順序呼叫的函式佇列,您可以更輕鬆地管理程式碼片段的執行,而不會阻塞主執行緒。

然而,這仍然存在必須重構現有程式碼以實際按此方式工作的難題。這可能需要一些時間。

我應該有多非同步?

您的網站首次變得可用並且對使用者輸入的響應越快,它的感知就會越好。通常認為需要 1 到 2 秒才能顯示內容的網站是快速的;如果您習慣了需要 3 到 4 秒的網站,那麼 7 到 8 秒就會感覺很長。

在響應能力方面,使用者不會注意到 50ms 或更短的延遲。任何超過 200ms 的延遲,使用者都會覺得您的網站反應遲鈍。在改進應用程式的載入和響應能力時,請記住,您的許多使用者可能擁有比您更舊、更慢的計算機,他們可能會遇到比您更長的延遲!

其他建議

除了非同步化之外,還有其他方法可以幫助您提高應用程式的啟動時間。以下是其中一些:

下載時間

請記住使用者下載應用程式資料所需的時間。如果您的應用程式非常受歡迎,或者需要頻繁重新下載內容,您應該儘量擁有儘可能快的託管伺服器。始終 壓縮您的資料,使其儘可能小。

資料大小

盡最大努力最佳化資料大小;較小的關卡檔案將比較大的檔案下載和處理得更快。

主觀因素

您可以做的任何有助於在啟動過程中讓使用者保持參與的事情,都可以幫助縮短感覺上的時間。顯示模擬的啟動螢幕可以提高 感知效能。對於大型網站,任何可以幫助使用者感覺您的應用程式正在執行某些操作而不是靜默等待的事情都有幫助。

另見