談談前端工程化 js載入
當年的 js 載入
在沒有 前端工程化之前,基本上是我們是程式碼一把梭,把所需要的庫和自己的程式碼堆砌在一起,然後自上往下的引用就可以了。
那個時代我們沒有公用的cdn,也沒有什麼特別好的方法來優化載入js的速度。最多用以下幾個方案。
可用的效能方案
- 可以在程式碼某些需要js的時候去使用 loadjs 來動態載入 js 庫。這樣就不會出現開始時候載入大量js檔案。
- 再大點的專案可能用一下 Nginxngx_http_concat_module 模組來合併多個檔案在一個響應報文中。也就是再載入多個小型 js 檔案時候合併為一個 js 檔案。
- BigPipe 技術也是可以對頁面分塊來進行優化的,但是因為與本文關係不大,方案也沒有通用化和規範化,加上本人其實沒有深入瞭解所不進行深入介紹,如果先了解可以參考新版賣家中心 Bigpipe 實踐(一) 以及新版賣家中心 Bigpipe 實踐(二) 。
當然那個時期的程式碼也沒有像現在的前端的程式碼量和複雜度那麼高。
Webpack 之後的js載入
與其說 Webpack 是一個模組打包器,倒不如說 Webpack 是一份前端規範。
需要庫沒有被大量使用情況
對於我們程式碼中所需要的程式碼庫沒有大量使用,比如說某種元件庫我們僅僅只使用了 2、3個元件的情況下。我們更多需要按需載入功能。
比方說在MATERIAL-UI 我們可以用
import TextField from '@material-ui/core/TextField'; import Popper from '@material-ui/core/Popper'; import Paper from '@material-ui/core/Paper'; import MenuItem from '@material-ui/core/MenuItem'; import Chip from '@material-ui/core/Chip';
代替
import { TextField, Popper, Paper, MenuItem, Chip } from '@material-ui'
這樣就實現了按需載入,而不是動輒需要整個元件庫。但是這樣的程式碼中這樣程式碼並不好書寫。我們就需要一個幫助我們轉換程式碼的庫。這可以參考Babel 外掛手冊 以及簡單實現專案程式碼按需載入 來實現我們的需求。
需要庫大量被使用情況
如果我們的庫被當前的專案大量使用了,按需載入其實就未必是最好的方法了,如果我們的伺服器不是特別好的情況下我們可以使用 Webpack 的 externals 配置來優化專案的js。就簡單的對 externals 配置簡單說明一下。externals其實是在全域性中的得到庫檔案。
// 頁面中使用 cdn,這樣的話,我們就會在 window 中得到 jQuery // 也就是 global.JQuery 瀏覽器中 global === window <script src="https://code.jquery.com/jquery-3.1.0.js" integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk=" crossorigin="anonymous"> </script> // 在專案中匯入 jquery 使用 import $ from 'jquery'; // 配置中 左邊是 配置的 jquery 告訴 Webpack 不需要匯入 // 配置中 右邊是 配置的 JQuery 告訴 Webpack 記載 jquery 時候使用 global.JQuery externals: { jquery: 'jQuery' }
但是使用 externals 曾遇到這樣的情況。我在使用 material-ui 元件庫時候發現該庫在全域性匯出的程式碼是 material-ui。
也就是:
externals: { '@material-ui/core': 'material-ui' }
此時會發生匯入錯誤,錯誤原因為: window.material-ui。
本來我是想要引入material-ui,卻 - 符號變為了減號。
本來想要利用用 ['material-ui'] 來替換,卻發現行不通: windows.['material-ui']
解決方法:
externals: { '@material-ui/core': "window['material-ui']" }
因為 window 物件有自己引用自己,所以 window === window.window.window。所以程式碼為 window.window['material-ui']。可以參考MDN Window.window
上文中的效能優化方案依然可用
loadjs 動態載入
在當前所需要 js 檔案不需要大量使用同時需要的 js 檔案是不需要開始時載入(如 React, React-Router 一類)的時候我們依然可以使用loadjs來載入(比如說 圖示庫一類,只在某一些頁面使用)。
合併多個小型 js
對於在 HTTP2 中合併多個 小js檔案未必好。因為在 HTTP2 中,HTTP 請求是廉價的,合併便不再顯得有優勢。
BigPipe 方案
當然了,BigPipe 方案不是針對單頁面應用程式。而且對於前後端的技術要求較高,所以對於專案未必是最有效的方案。
其他
現如今也可以使用一些其他的方法。例如 Service Worker,Wasm 等一系列方案。不知道還有什麼其他方法,也可以介紹給我。
參考文件
新版賣家中心 Bigpipe 實踐(一) 新版賣家中心 Bigpipe 實踐(二) Babel 外掛手冊 簡單實現專案程式碼按需載入 MDN Window.window