隨著專案的日漸迭代,專案整體的代碼量也會越來越多,從而導致專案體積越來越大;在Webpack時代,很多人會對歷史專案(巨型專案)感到頭疼,因為往往巨型專案在本地開發除錯的時候會因為本地代碼的修改觸發HMR熱更新多載頁面,然而這一程序在Webpack的運行機制中顯得很慢,并且是隨著專案越大,熱更新的速度也會越慢;
Webpack熱更新慢的問題可以通過 babel-plugin-dynamic-import-node 插件來得到明顯改善,或者通過手動實作動態按需加載(修改entry為當前專案中需要編譯的部分或模塊)亦可大幅提升熱更新速度;
熱更新構建主要流程

在Webpack中,我們的每一次ctrl+s操作,都會觸發熱更新;此時熱更新構建的一個程序應該是此時的終端顯示Compiling......執行重新構建并打包,并生成新的hash值,啟動Webpack-dev-server服務與瀏覽器通過WebSocket建立連接;此時的hash值會作為下一次編譯生成的檔案的前綴,以此類推;每次修改會觸發重新編譯,然后發出兩次請求;
首先看json檔案,發出請求回傳的結果中有一個c引數和一個h引數,c代表的是本次熱更新要對應的是c模塊,h代表的是本次熱更新重新編譯的程序中新生成的hash值,將作為下一次熱更新請求編譯后生成的檔案前綴使用;
js檔案,是修改之后重新編譯生成打包后的代碼,重新對檔案進行下載及網路資源加載;
Vite中熱更新構建程序也是類似,Vite是在本地啟動Vite Server服務,通過WebSocket與瀏覽器進行連接通信,并加入了WebSocket的定時心跳檢測機制,拿到已修改更新的檔案路徑以及時間戳標識,然后再次帶上這個時間戳作為引數去重新請求該檔案修改后的版本,防止快取;

熱更新邊界
熱更新邊界即熱更新邊緣,定義了處于極值或者特殊情況的時候該如何去處理熱更新;
正常來說我們Vue檔案會正常熱更新,因為Vue底層部分對熱更新進行了自定義邏輯處理,重新定義了熱更新的處理方式;但是當我們修改js檔案或者ts檔案,并且這個js或者ts檔案剛好被.vue檔案所參考,這個時候會怎么處理?
js或者ts檔案修改之后,Vite會去對這個vue檔案進行熱更新,并重新加載該組件;此時,.vue檔案就是熱更新邊界;
當js或者ts檔案被修改之后,會沿著依賴樹一直往上尋找依賴關系,直到查找到最近的一個可以熱更新的模塊,這個最近的一個熱更新模塊叫熱更新邊界;
但是又有一種特殊情況,比如我們修改main.ts或者main.js的時候,因為是入口檔案,找不到最近的可以熱更新的模塊,這個時候Vite就不知道如何去執行熱更新了,只能是通過重繪頁面來解決;
Vite熱更新為什么比Webpack熱更新快?
Webpack熱更新運行機制:
Webpack會遍歷你的應用程式中的所有檔案,并啟動一個開發服務器(Webpack-dev-server),然后將整個代碼渲染到開發環境中,從entry入口檔案開始,將其依賴的資源檔案通過loader打包成一個檔案夾,然后通過server傳遞到客戶端運行;也正是因為這樣的運行機制,也必將導致專案代碼量增多,應用體積增大之后,Webpack熱更新需要等待較久的時間才能反映到瀏覽器中;
Vite熱更新運行機制:
Vite會在本地啟動一個Vite Server服務,對于第三方依賴使用了速度更快的esbuild預構建,對于業務代碼使用原生的ESM,訪問這個服務,現代瀏覽器基本都已支持的import/export等語法可用來直接加載對應模塊的服務端資源,繞過了構建打包程序,對請求的模塊進行實時按需編譯,熱更新時僅需重新請求改動過的模塊即可,繞過了Webpack熱更新全域依賴與業務代碼全部重新編譯的程序;
使用keep-alive組件導致熱更新對ts檔案失效,如何解決?
使用keep-alive組件實作頁面級快取,會導致熱更新失效;個人理解是:因為vue框架底層原始碼部分對Vite熱更新有特殊處理邏輯(import.meta.hot.accept Api用于傳入一個回呼函式,來定義該模塊修改后,需要怎么去熱更新,此Api一般提供給框架或者工具庫的作者使用,業務代碼中可不用關注),而ts檔案是沒有熱更新邏輯的,所以會沿著依賴樹一直往上尋找,往上找到一個可以熱更新的模塊對其進行熱更新即可;keep-alive頁面快取和熱更新概念沖突,在開發環境中我們可以判斷舍棄掉keep-alive快取,而在生產環境中我們可以舍棄熱更新,達到解決問題的目的;
解決方案:
Vite劣勢:
有好必有壞,Vite目前的機制是會大幅提高熱更新的速度,解決Webpack機制中的巨型專案熱更新等待過久的問題,提高開發效率;但是同時也正是因為Vite的運行機制,直接瀏覽器按需向服務端請求資源,這就造成了Vite專案的首屏加載沒有Webpack快,因為Vite首屏的時候會發出大量的請求去拿到資源檔案從而渲染頁面,而Webpack不需要;同時懶加載性能方面,Vite也沒有Webpack好;但是首屏渲染這個問題只是第一次加載的時候會比較慢,Vite對第三方依賴做了快取處理,第二次之后的頁面加載速度提升很多;總體來說,Vite是優大于劣;
作者:有夢想的咸魚前端 出處:https://www.cnblogs.com/dengyao-blogs/ 本文著作權歸作者和博客園共有,歡迎轉載,但必須給出原文鏈接,并保留此段宣告,否則保留追究法律責任的權利,轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/508832.html
標籤:JavaScript
上一篇:前端像素鳥小游戲
