前言
隨著前端應用日益龐大,單頁應用(SPA)在初次載入時常面臨 JavaScript 檔案過大、載入時間過久的問題,導致使用者等待時間過長、效能下降。為了解決這個問題,React 與現代建構工具(如 Webpack、Vite)提供了 Code Splitting(程式碼分割)與 Lazy Loading(延遲載入)兩種策略,協助開發者更有效地管理與優化應用程式的載入流程。
程式碼分割(Code Splitting)和惰性載入(Lazy Loading)都是用來優化網頁效能的方法,它們都旨在減少初始加載時間,但實現方式和目標略有不同。 程式碼分割是將程式碼分割成多個較小的塊,而惰性載入則是在需要時才加載這些塊。
一、程式碼分割(Code Splitting)
概念:
程式碼分割是將一個大型的 JavaScript 應用程式分割成多個較小的、獨立的塊,每個塊包含應用程式的一部分程式碼。 這些塊通常是根據路由、元件或功能來分割的。
目標:
主要目標是減少應用程式的初始加載時間,通過只加載使用者當前需要的程式碼塊,而不是一次性加載所有程式碼。
實現方式:
程式碼分割通常使用打包工具(如 Webpack、Rollup 等)和動態import()
語法來實現。
使用時機:
在編譯時(build time)就進行分割。
二、惰性載入(Lazy Loading)
概念:
惰性載入是指在需要的時候才加載程式碼,而不是在應用程式初始化時就加載所有程式碼。
目標:
減少應用程式的初始加載時間,特別是對於大型應用程式或元件。
實現方式:
惰性載入通常使用 React.lazy 和
使用時機:
在執行時(runtime)才加載,通常是當使用者訪問某個路由、觸發某個事件或需要顯示某個元件時。
差異總結
特性 | 程式碼分割(Code Splitting) | 惰性載入(Lazy Loading) |
---|---|---|
概念 | 將程式碼分割成多個塊 | 在需要時才加載程式碼 |
目標 | 減少初始加載時間,優化效能 | 減少初始加載時間,優化效能 |
實現方式 | 打包工具,dynamic import() | React.lazy, |
時機 | 編譯時 | 執行時 |
關聯性 | 程式碼分割是惰性載入的基礎,惰性載入可以利用程式碼分割的結果。 | — |
重點摘要
Code Splitting(程式碼分割)
- 是一種將整個應用程式切割成多個檔案的技術
- 通常由 Webpack、Rollup 等建構工具自動處理
- 可應用於 route-based 分割、component-based 分割等情境
- 不代表一定是延遲載入,僅是結構上的切割
Lazy Loading(延遲載入)
- 是一種執行時載入程式碼的策略
- 常與
import()
搭配,直到實際使用時才載入 - 通常透過
React.lazy
、Suspense
實現元件的懶載入 - 是 Code Splitting 的使用方式之一
兩者關係
- Code Splitting 是靜態建構階段的優化策略
- Lazy Loading 是執行階段的載入行為
- Lazy Loading 必須建立在已做 Code Splitting 的前提上
效益
- 減少主程式 bundle 的大小
- 提升首次載入速度(First Contentful Paint)
- 延遲不必要的資源載入,節省頻寬與記憶體
實際範例
範例一:傳統未分割的情況(單一 bundle)
// App.js |
這樣寫會導致 HomePage 和 Dashboard 在應用一開始就被載入,無論使用者有沒有看到這些元件。
範例二:使用 React.lazy 實現 Lazy Loading 與 Code Splitting
// App.js |
使用
React.lazy()
搭配import()
會讓 Webpack 將這些元件建立為獨立的 chunk。
真正渲染時(如使用者切換頁面),才會觸發載入行為,減少初始 bundle 體積。
範例三:Route-based Code Splitting(React Router)
// AppRouter.js |
使用路由為單位切割頁面元件,是最常見的 Code Splitting 實務做法。
範例四:動態 import 實作非元件的延遲載入
// utils.js |
// App.js |
在某些不需要立即執行的邏輯或大型工具函式庫,也可以透過
import()
動態載入來延遲其成本。
常見問題與補充
Q1:Code Splitting 是自動的嗎?
- 大部分情況下需要手動設計入口點(如
React.lazy
或import()
),Webpack 才會建立分離的 chunk。
Q2:只有使用 React.lazy
才能 Lazy Load 嗎?
- 不一定,
import()
是底層機制,也可配合其他框架(Vue、Svelte)或工具(React Loadable)使用。
Q3:懶載入的元件可以預載嗎?
- 可以,透過
import().then()
觸發一次即可放進瀏覽器快取,達到「預熱」效果。
總結
在前端應用越來越大型化的今天,掌握 Code Splitting 與 Lazy Loading 的差異與使用場景,已成為每位前端工程師的必備技能。Code Splitting 解決的是「結構上的模組分離」,Lazy Loading 則是「載入時機的延後」。兩者密不可分,但用法與思考層次不同。
實務上可先針對頁面級路由進行分割,再進一步優化元件級的載入、工具模組載入時機,逐步降低初始 bundle 體積,提升網站效能與使用者體驗。