隨著項目的日漸迭代,項目整體的代碼量也會越來越多,從而導致項目體積越來越大;在Webpack時代,很多人會對歷史項目(巨型項目)感到頭疼,因為往往巨型項目在本地開發調試的時候會因為本地代碼的修改觸發HMR熱更新重載頁面,然而這一過程在Webpack的運行機制中顯得很慢,並且是隨著項目越大,熱更新的速 ...
隨著項目的日漸迭代,項目整體的代碼量也會越來越多,從而導致項目體積越來越大;在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/ 本文版權歸作者和博客園共有,歡迎轉載,但必須給出原文鏈接,並保留此段聲明,否則保留追究法律責任的權利。