淺談vite和webpack的性能優(yōu)化和區(qū)別
性能優(yōu)化概述
1.分包策略
Vite和Webpack都支持性能優(yōu)化-分包策略,下面簡要介紹一下它們的實現(xiàn)方法:
Vite分包策略
Vite是一款基于ESM的構(gòu)建工具,Vite的分包策略主要通過動態(tài)引入實現(xiàn),可以自動進行代碼拆分,實現(xiàn)按需加載和運行時優(yōu)化。在Javascript中,可以使用ES6的import()語法來實現(xiàn)動態(tài)引入:
const module = import('./module.js');
Vite還支持使用預構(gòu)建Chunk來優(yōu)化加載速度,可以在vite.config.js文件中設置rollupOptions項來實現(xiàn)預構(gòu)建Chunk:
module.exports = { build: { rollupOptions: { output: { manualChunks: { react: ['react', 'react-dom'] } } } } };
除了動態(tài)引入和預構(gòu)建Chunk,Vite還支持手動配置Chunk,以實現(xiàn)更細粒度的控制??梢允褂?nbsp;import.meta.glob() 函數(shù)來匹配文件對 Chunk 進行手動配置。
import.meta.glob('../components/*.js').then(modules => { Promise.all(modules.values()).then(components => { // ... }) })
Webpack分包策略
Webpack可以使用以下方式實現(xiàn)分包策略:
- 使用代碼分割插件(Model Splitting)
通過代碼分割插件在構(gòu)建過程中實現(xiàn)自動化的代碼分割。
const path = require('path'); module.exports = { ? entry: { ? ? app: './src/app.js' ? }, ? output: { ? ? path: path.resolve(__dirname, 'dist'), ? ? filename: '[name].bundle.js' ? }, ? optimization: { ? ? splitChunks: { ? ? ? chunks: 'all' ? ? } ? } };
- 使用動態(tài)導入(Dynamic Imports)
通過動態(tài)導入將代碼拆分成多個小塊,按需加載。
import('./module.js') .then((module) => { // ... }) .catch((err) => { // ... });
Webpack還支持使用webpackPrefetch和webpackPreload來實現(xiàn)預加載預取的功能,提高用戶體驗。
// webpackPreload const Component = () => import(/* webpackPreload: true */ './Component.js'); // webpackPrefetch const Component = () => import(/* webpackPrefetch: true */ './Component.js');
以上就是Vite和Webpack的分包策略實現(xiàn)方法和代碼示例。
2.gzip壓縮
Vite和Webpack都提供了Gzip壓縮的功能,以便在前端性能優(yōu)化中使用。
在Vite中,可以通過在vite.config.js中設置compress參數(shù)來開啟Gzip壓縮:
// vite.config.js export default { ? server: { ? ? compress: true ? } }
在Webpack中,可以通過在webpack.config.js中配置CompressionPlugin插件來開啟Gzip壓縮:
const CompressionPlugin = require('compression-webpack-plugin'); module.exports = { ? plugins: [ ? ? new CompressionPlugin({ ? ? ? algorithm: 'gzip' ? ? }) ? ] };
這些配置將為我們自動壓縮生成的文件,并在傳輸?shù)娇蛻舳藭r解壓文件以提高性能。
值得注意的是,由于Gzip壓縮需要花費一些CPU時間,建議在服務器端啟用壓縮。如果你正在使用CDN,你也可以在CDN端配置Gzip壓縮。
3.動態(tài)引入
Webpack和Vite都支持使用動態(tài)引入來提高前端性能。動態(tài)引入的主要作用是延遲加載,只在需要的時候才加載相關的模塊,減少了首次加載時的負擔。
在Vite中,可以實現(xiàn)動態(tài)引入的幾種方式:
使用ES6動態(tài)導入語法
import('./path/to/module').then(result => { // do something with the module }).catch(error => { // handle error });
這將以異步方式加載模塊,可以在需要時動態(tài)引入。
在組件的setup函數(shù)中使用異步加載
import { defineComponent, ref, onMounted } from 'vue'; export default defineComponent({ ? setup() { ? ? const moduleRef = ref(null); ? ? onMounted(async () => { ? ? ? const result = await import('./path/to/module'); ? ? ? moduleRef.value = result; ? ? }); ? ? return { ? ? ? moduleRef, ? ? }; ? }, });
這種方式使用了Vue 3中的setup函數(shù),使用Promise來異步加載模塊,并將結(jié)果存儲在ref中。
使用異步組件
const AsyncComponent = defineAsyncComponent(() => import('./path/to/module')); export default defineComponent({ ? components: { ? ? AsyncComponent, ? }, ? template: `<AsyncComponent />`, });
這里使用了Vue 3中的defineAsyncComponent函數(shù),通過傳入異步加載模塊的路徑來創(chuàng)建異步組件。這樣組件的加載過程將會被延遲到當組件被使用時再進行。
需要注意的是,為了使動態(tài)引入能夠真正發(fā)揮作用,還需要配置Vite的按需動態(tài)導入功能。在vite.config.js文件中,可以通過設置rollupOptions參數(shù)來開啟此功能:
// vite.config.js export default { ? rollupOptions: { ? ? output: { ? ? ? manualChunks: {}, ? ? }, ? }, };
此配置將分離每個動態(tài)導入的文件,并生成一個獨立的代碼塊。這樣可以按需加載模塊,從而提高性能。
在Webpack中,可以實現(xiàn)動態(tài)引入的幾種方式:
使用ES6動態(tài)導入語法
import('./path/to/module').then(result => { // do something with the module }).catch(error => { // handle error });
這將以異步方式加載模塊,可以在需要時動態(tài)引入。
在React懶加載組件中使用
const MyComponent = lazy(() => import('./path/to/module'));
使用了React.lazy()函數(shù)來實現(xiàn)懶加載。此函數(shù)接受一個返回動態(tài)加載模塊的import()函數(shù)的參數(shù)。
使用webpack的內(nèi)置require.ensure()
require.ensure(['./path/to/module'], function (require) { var result = require('./path/to/module'); // do something with the module });
這種方式使用了webpack的內(nèi)置函數(shù)require.ensure(),可以將塊(chunk)分離出來并延遲加載模塊。
在使用動態(tài)引入時,還可以通過配置webpack的output.publicPath屬性,將異步塊的基礎路徑設置為CDN地址,以加快異步加載速度。例如:
output: { path: path.resolve(__dirname, 'dist'), filename: 'bundle.js', publicPath: 'https://cdn.example.com/' }
需要注意的是,在使用動態(tài)引入時,還需要配置webpack的代碼分離和優(yōu)化功能??梢酝ㄟ^在webpack.config.js文件中設置optimization.splitChunks來實現(xiàn)此目的:
optimization: { splitChunks: { chunks: 'async', minSize: 20000, maxSize: 0, minChunks: 1, maxAsyncRequests: 30, maxInitialRequests: 30, enforceSizeThreshold: 50000, cacheGroups: { defaultVendors: { test: /[\/]node_modules[\/]/, priority: -10, reuseExistingChunk: true, }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true, }, }, }, },
這樣,webpack會自動分離出符合條件的模塊,生成獨立的代碼塊,在需要時進行加載。
值得注意的是,動態(tài)引入雖然可以優(yōu)化首次加載時間,但在使用多個包時可能會導致過多的HTTP請求,這可能導致首屏渲染延遲。因此,需要根據(jù)實際情況選擇何時使用動態(tài)引入。
補充:
為了避免這些問題,并且進一步提高性能,可以采用以下一些方法:
預加載和預取。在Webpack中,可以使用webpackPrefetch和webpackPreload注釋,以啟用自動預取和/或預加載。例如:
import(/* webpackPrefetch: true */ './path/to/module');
這將告訴瀏覽器提前下載此模塊,以便在需要時立即加載。
按用戶需求加載。如果你有一些模塊是高頻訪問的,那么可以在頁面加載時先加載這些模塊,而將其他模塊延遲加載。這樣可以防止不必要的HTTP請求,并加快頁面響應速度。
避免過多的動態(tài)引入。雖然動態(tài)引入可以解決代碼分離的問題,但是如果不加以控制,也可能導致模塊的數(shù)量過于龐大,進而導致過多的HTTP請求和降低性能的可能。因此,在使用動態(tài)引入時,必須注意模塊數(shù)量的把握,避免過度動態(tài)引入。
4.CDN加速
Vite和Webpack都支持使用CDN加速來優(yōu)化前端性能。使用CDN可以將靜態(tài)資源放置在離用戶更近、更容易訪問的地方,這樣可以減少網(wǎng)絡延遲,加快資源加載速度。
在Vite中,可以通過以下方式來使用CDN資源加速:
在 vite.config.js 文件中設置 base 屬性
export default { base: 'https://cdn.example.com/', // ... }
設置 base 屬性后,資源的 baseURL 將會被設置為此處的值,JavaScript、CSS、圖片等靜態(tài)資源都將從這個地址加載。
在 index.html 文件中手動引入 CDN 資源
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My App</title> <link rel="stylesheet" rel="external nofollow" > </head> <body> <div id="app"></div> <script type="module" src="/src/main.js"></script> </body> </html>
這種方式可以手動指定要加載的靜態(tài)資源,并從CDN加載,但需要注意的是,這種方式可能會增加HTML文件的大小和復雜度。
在 vite.config.js 文件中使用 CDN 插件
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { VitePluginCdn } from 'vite-plugin-cdn'; export default defineConfig({ ? plugins: [ ? ? vue(), ? ? VitePluginCdn({ ? ? ? ? modules:[ ? ? ? ? ? ? { ? ? ? ? ? ? ? ? name: 'vue', ? ? ? ? ? ? ? ? var: 'Vue', ? ? ? ? ? ? ? ? path: 'vue/dist/vue.min.js' ? ? ? ? ? ? }, ? ? ? ? ? ? { ? ? ? ? ? ? ? ? name: 'vue-router', ? ? ? ? ? ? ? ? var: 'VueRouter', ? ? ? ? ? ? ? ? path: 'vue-router/dist/vue-router.min.js' ? ? ? ? ? ? }, ? ? ? ? ? ? { ? ? ? ? ? ? ? ? name: 'chart.js', ? ? ? ? ? ? ? ? var: 'Chart', ? ? ? ? ? ? ? ? path: 'chart.js/dist/Chart.min.js' ? ? ? ? ? ? } ? ? ? ? ], ? ? ? ? prodUrl: 'https://cdn.example.com/{{module}}/{{version}}/{{path}}', ? ? ? ? // 以下配置可以是 CDN 來加速引入的資源。 ? ? ? ? // 必須是數(shù)組形式,且選項都必須包含 `test` 和 `method` 屬性。 ? ? ? ? // 具體可選項請參考 `preload-webpack-plugin` 的 `include` 參數(shù)。 ? ? ? ? allowList: [ ? ? ? ? ? ? { ? ? ? ? ? ? ? test: /bootstrap-vue/(.*?).(js|css|woff|woff2|ttf|svg|png|jpe?g|gif)$/, ? ? ? ? ? ? ? method: 'GET', ? ? ? ? ? ? ? //可選的擴展加載,vue使用 ? ? ? ? ? ? ? ext: 'js' ? ? ? ? ? ? } ? ? ? ? ] ? ? }) ? ] })
使用 vite-plugin-cdn 插件可以方便地自動將指定的模塊從CDN加載。需要注意的是,這個插件需要按照指定規(guī)則的方式來定義模塊和版本。具體用法可以參考 vite-plugin-cdn 的官方文檔。
以上這些方法都可以實現(xiàn)CDN資源加速,根據(jù)實際使用場景可以靈活選擇。
在Webpack中,可以通過以下方式來使用CDN資源加速:
使用 HtmlWebpackPlugin 插件
在 webpack.config.js 文件中使用 HtmlWebpackPlugin 插件,在 template 配置中引入CDN地址
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { ? // ... ? plugins: [ ? ? new HtmlWebpackPlugin({ ? ? ? template: 'public/index.html', ? ? ? cdn: { ? ? ? ? js: [ ? ? ? ? ? 'https://cdn.example.com/jquery.min.js', ? ? ? ? ? 'https://cdn.example.com/bootstrap.min.js' ? ? ? ? ], ? ? ? ? css: [ ? ? ? ? ? 'https://cdn.example.com/bootstrap.min.css' ? ? ? ? ] ? ? ? } ? ? }) ? ], ? // ... };
在 HTML 模板文件中,將 js 和 css 鏈接插入到模板中:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My App</title> <% for (var i in htmlWebpackPlugin.options.cdn.css) { %> <link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="external nofollow" rel="stylesheet"> <% } %> </head> <body> <div id="app"></div> <% for (var i in htmlWebpackPlugin.options.cdn.js) { %> <script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script> <% } %> </body> </html>
這種方式可以將靜態(tài)資源鏈接插入到運行 HTML 模板源文件中,以指定CDN地址加載。
在 output.publicPath 中設置 CDN 地址
在 webpack.config.js 文件中設置 output.publicPath 屬性:
module.exports = { output: { publicPath: 'https://cdn.example.com/', }, // ... }
這樣設置后,通過Webpack打包后的靜態(tài)資源將從指定的CDN地址加載,比如JS、CSS、圖片等靜態(tài)資源。
以上這些方法都可以實現(xiàn)CDN資源加速,根據(jù)實際使用場景可以靈活選擇。
vite和webpack的區(qū)別
1. 開發(fā)模式下的運行方式不同
Vite在開發(fā)模式下使用 Rollup 進行打包,并提供了一個內(nèi)置的 HTTP 服務器來提供服務。它使用 ES modules 作為默認的模塊系統(tǒng),可以快速地進行熱更新和快速構(gòu)建。
Webpack在開發(fā)模式下使用自己的開發(fā)服務器進行工作,支持熱更新,但通常需要使用一些插件來實現(xiàn)一些高級功能,如HMR(熱模塊替換)。
以下是一個使用Vite的示例代碼,index.html 文件中直接引用模塊,瀏覽器通過 Vite 內(nèi)置的 HTTP 服務器加載模塊:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>My App</title> </head> <body> <div id="app"></div> <script type="module" src="/src/main.js"></script> </body> </html>
以下是一個使用Webpack的示例代碼,webpack-dev-server通過監(jiān)聽文件變化來觸發(fā)熱更新:
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { ? mode: 'development', ? entry: './src/index.js', ? output: { ? ? path: path.resolve(__dirname, 'dist'), ? ? filename: 'main.js', ? }, ? devServer: { ? ? contentBase: './dist', ? ? hot: true, ? }, ? plugins: [ ? ? new HtmlWebpackPlugin({ ? ? ? title: 'My App', ? ? }), ? ], };
2. 構(gòu)建方式和性能
Vite在開發(fā)模式下使用Rollup進行構(gòu)建,支持按需編譯和充分利用現(xiàn)代瀏覽器的原生ES模塊,所以它的速度更快,比如熱刷新延時更短、構(gòu)建速度更快等。但在實際項目中,如需要自定義構(gòu)建方式和高級功能的話,需要對Rollup的運行機制有一定的了解。
Webpack基于模塊化思想和依賴分析,在生產(chǎn)模式下可以更好地實現(xiàn)代碼壓縮、分離、圖片壓縮等復雜的構(gòu)建操作。同時Webpack還內(nèi)置了一些優(yōu)化策略,如啟用多線程并發(fā)構(gòu)建、使用Tree shaking技術等,因此Webpack在處理大型項目時更具優(yōu)勢。
以下是一個使用Vite的示例代碼,build 命令會通過 Rollup 進行構(gòu)建:
// vite.config.js export default { ? build: { ? ? outDir: 'dist', ? ? assetsDir: 'assets', ? ? rollupOptions: { ? ? ? input: 'src/main.js', ? ? }, ? }, }
以下是一個使用Webpack的示例代碼,npm run build 命令會通過 Webpack 進行構(gòu)建:
// webpack.config.js const path = require('path'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { ? mode: 'production', ? entry: './src/index.js', ? output: { ? ? filename: 'main.js', ? ? path: path.resolve(__dirname, 'dist'), ? }, ? plugins: [ ? ? new CleanWebpackPlugin(), ? ? new HtmlWebpackPlugin({ ? ? ? title: 'My App', ? ? }), ? ], };
3. 配置方式
Vite使用ES modules進行導入和導出,而配置文件也是一個ES module,可以直接使用ES6語法,簡易直觀。此外,Vite還提供了一個內(nèi)置的插件管理系統(tǒng)和一些現(xiàn)成的插件,方便用戶管理和使用。
Webpack使用CommonJS方式來導入和導出模塊,配置文件是一個CommonJS模塊,使用的是Node.js的API,需要一定的配置經(jīng)驗,但也更加靈活,可以滿足
4. 支持的語言
Vite除了支持JavaScript和CSS,還支持以.vue文件為代表的單文件組件,這種組件可以將HTML、CSS和JavaScript打包到一個文件中。Vue.js等框架也積極支持Vite,稱其是其未來的構(gòu)建工具。
Webpack雖然可以支持JavaScript和CSS,但是它的打包方式更加靈活,支持Sass、Less等CSS預處理器,同時也可以使用Babel來支持ES6以上的JavaScript語法。
以下是一個使用Vite的示例代碼,.vue文件包含HTML、CSS和JavaScript等三種代碼:
<template> ? <div> ? ? <h1>{{ msg }}</h1> ? </div> </template> <script> export default { ? name: 'HelloWorld', ? data() { ? ? return { ? ? ? msg: 'Welcome to Your Vue.js App - Vite', ? ? } ? }, } </script> <style> h1 { ? color: #00f; } </style>
以下是一個使用Webpack的示例代碼,.scss文件包含CSS代碼和變量:
$primary-color: #00f; body { ? background-color: lighten($primary-color, 50%); ? color: darken($primary-color, 30%); }
5. 插件生態(tài)和拓展性
Webpack的插件生態(tài)很豐富,提供了很多社區(qū)開發(fā)的插件,可以滿足各種需求,可以針對性的選擇安裝,非常方便。同時Webpack還支持自定義插件,可以非常靈活地拓展其功能。
Vite的插件生態(tài)相對較少,但其特有的打包方式和內(nèi)置的插件系統(tǒng)可以對項目開發(fā)提供很好的支持。Vite的開發(fā)團隊也計劃在未來增加更多的插件,支持更多瀏覽器和應用場景。
到此這篇關于淺談vite和webpack的性能優(yōu)化和區(qū)別的文章就介紹到這了,更多相關vite和webpack區(qū)別內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
vite結(jié)合electron構(gòu)建前端桌面應用程序
本文主要介紹了vite結(jié)合electron構(gòu)建前端桌面應用程序,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2023-05-05vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法
這篇文章主要介紹了vue使用map代替Aarry數(shù)組循環(huán)遍歷的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-04-04Vue中addEventListener()?監(jiān)聽事件案例講解
這篇文章主要介紹了Vue中addEventListener()?監(jiān)聽事件案例講解,包括語法講解和事件冒泡或事件捕獲的相關知識,本文結(jié)合示例代碼給大家講解的非常詳細,需要的朋友可以參考下2022-12-12