最近著手重構優化一個Vue的專案,最明顯的問題就是首屏加載緩慢,我們都知道請求一個資源快慢無非兩個要素:帶寬(網速)+ 檔案大小,作為一個開發我們只能從檔案體積方面進行深入優化:壓縮代碼,壓縮圖片,小圖片轉base64,開啟Tree-sharking優化去除無用代碼,資源分割打包拆分如Vue,JQuery等分離出來單獨打包成一個檔案,有條件可放在CDN上,
一,基礎環境搭建
1.安裝node.js,在官網下載相應版本進行安裝,安裝完成后在命令列模式下輸入node -v查看是否安裝成功,
2.安裝淘寶npm(cnpm):npm install -g cnpm --registry=https://registry.npm.taobao.org npm是國外服務下載,下載速度較慢,
3.安裝全域webpack(-g代表全域安裝): cnpm install webpack@5 webpack-cli@4 webpack-dev-server@3 -g
(@5表示安裝5的版本)這里我把安裝webpack-dev-server也一并安裝了,我選用了webpack-dev-server3的版本,因為有些版本與webpack5不兼容,
4.切換到專案目錄,安裝本地webpack:cnpm install webpack@5 webpack-cli@4 webpack-dev-server@3 --save-dev
在專案目錄中安裝webpack,其中,--save-dev會在 devDependencies 里記錄,只是開發和打包時會用到的,但實際上線并不需要;--save會在 dependencies 里記錄,除了開發需要,實際上線的時候也需要的
5.初始化package.json檔案:npm init -y
二、手寫webpack組態檔——webpack.config.js
這里我就不過多介紹什么了,所使用的配置基本上我都標明了注釋,這里所展示的僅是我個人所需的一些loader和plugin的配置,有些我沒有用到的比如:cache-loader、thread-loader之類的需要的可以自己補充,直接上代碼:
/**
* @author zhangshuo
* @date 2021/9/26 13:09
*
* webpack5 優化打包處理配置
**/
const MiniCssExtractPlugin=require("mini-css-extract-plugin");//css提取插件
const CssMinimizerWebpackPlugin=require("css-minimizer-webpack-plugin");//css壓縮插件
const HtmlWebpackPlugin=require("html-webpack-plugin");//html處理
const VueLoaderPlugin = require("vue-loader/lib/plugin");
const path = require('path');
module.exports={
//production or development
//webpack4之后,指定使用 production mode 時,默認會啟用各種性能優化的功能,包括構建結果優化以及 webpack 運行性能優化
//包括代碼壓縮,tree-sharking:Tree-shaking的本質是消除無用的js代碼(包括第三方庫例如jquery、vue等,只打包用到的方法,只支持函式式編程)
mode: "development",
//入口
entry: {
app:"./src/main.js",//app為name
},
//出口
output: {
path: __dirname+"/out/",//path:輸出路徑,__dirname:node.js內置變數,代表當前專案絕對路徑
filename: "js/[name].[chunkhash].js",//[name]取入口name值,[hash]用來解決瀏覽器快取檔案問題,chunkhash是根據具體模塊檔案的內容計算所得的hash值,所以某個檔案的改動只會影響本模塊的hash值
//clean: true,//清除輸出目錄,dev模式下開啟會影響熱更新,prd模式下可開啟使用
environment: {
arrowFunction: false //不使用箭頭函式
}
},
devtool: 'source-map', //除錯工具
//在webpack5版本中使用默認或者'web'引數時,hot熱部署是有效的,但是編譯的runtime代碼IE瀏覽器不識別,語法不支持
//使用target: ['web','es5'],可以使編譯的代碼使用es5的特性,能正常在IE中使用,但是熱更新失效
//webpack5熱更新失效問題只能等待官方新版本中會得到優化解決,暫時建議在開發模式中使用target: 'web',在生產模式中使用target: ['web','es5']
target: 'web',//熱啟動生效,IE無法識別runtime代碼
/*target: ['web','es5'],*/ //熱啟動失效,IE可以正常使用
//vue有兩種形式的代碼 compiler(模板)模式和runtime模式(運行時),vue模塊的package.json的main欄位默認為runtime模式, 指向了"dist/vue.runtime.common.js"位置,
//也就是說,import Vue from ‘vue’ 這行代碼被決議為 import Vue from ‘vue/dist/vue.esm.js’,直接指定了檔案的位置,沒有使用main欄位默認的檔案位置
resolve: {
alias: {//別名
'vue$': 'vue/dist/vue.esm.js',
'@': '/src',
},
extensions: ['.js', '.vue','.json']//指定后綴
},
//把第三方庫單獨提取打包,例如:vue jquery等
//多頁面應用:主要業務代碼->頁面公用模塊+第三方庫vender
//單頁面應用: 主要業務代碼->異步加載js+第三方庫vender
optimization: {
splitChunks: {
// 模塊加載的方式:異步的還是同步的 all, initial, async
chunks: 'all',
// 需要打包的最小尺寸,如果模塊的大小小于這個值,就不單獨打包
minSize: 1024*1000,
// 需要單獨打包的模塊需要按照這個尺寸再次拆包, 0不拆包
maxSize: 1024*1024*10,
// 單個模塊被參考的次數,超過這個值的時候才會單獨打包
minChunks: 1,
// 表示index.html頁面上可以引入的.js檔案最大個數
maxInitialRequests: 6,
name:"chunk",
cacheGroups: {
vendors: {
// 模塊載入路徑的匹配
test: /[\\/]node_modules[\\/]/,
// 同時滿足多個test匹配的時候,priority值越大,越優先
priority: -10,
name: "vendor"
},
jquery: {
test: /jquery/,
priority: 10,
name: "jquery"
},
}
}
},
//開發模式->打包->打包內容給到webpack-dev-server->dev-server拿到打包內容,開啟node服務->node服務加載打包內容->呈現頁面
//安裝webpack-dev-server,需要全域和本地都安裝:cnpm install webpack-dev-server@3 -g/cnpm install webpack-dev-server@3 --save
//開發模式提供:熱更新和自動替換 代理轉發(自動替換作用于js)
devServer: {
contentBase: path.join(__dirname, "out"),//指定運行的根路徑
hot: true,//熱更新,只作用于css
hotOnly:false,// 頁面構建失敗不重繪頁面
port: 3000, //埠號
host: "localhost",
compress: true,//采用gzip壓縮
inline:true,//行內方式打開
progress:true,//開啟進度條
open:true, //啟動后直接打開瀏覽器
proxy:{//代理轉發,匹配到/api/test——>http://localhost:8000/test/
"/api":"http://localhost:8000/"
},
},
//loader:處理某種資源檔案
module: {
//test:匹配一個正則,定義這個loader處理哪種型別的檔案
rules: [
//處理css:1,引入style-loader和css-loader 2,定義style-loader和css-loader來處理css型別 3,mini-css-extract-plugin提取出來
//cnpm install style-loader css-loader --save
//cnpm install mini-css-extract-plugin --save
{
test:/\.css$/,
use: [//定義多個loader,從后往前執行
{
loader: MiniCssExtractPlugin.loader
},
{
loader:"css-loader"
},
]
},
//es6-->es5 使用bable 將es6語法編譯成es5語法
//cnpm install babel-loader @babel/core --save
//cnpm install @babel/preset-env --save
{
test: /\.js$/,
use: [
{
loader: "babel-loader",
options: {
presets:[
[
"@babel/preset-env",{
targets:{
browsers:[">1%","ie>=7"]//市場使用率大于1%的瀏覽器,大于等于ie7的瀏覽器
}
}
]
],
cacheDirectory: true // 自動babel快取
}
}
]
},
//處理圖片 url-loader:cnpm intsall file-loader url-loader --save
//壓縮大圖片 使用安裝 image-webpack-loader 依賴:image-loader imagemin imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant
{
test:/\.(jpg|png|jpeg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit:5000,//5kb以下小圖片轉成Base64
name: '[name].[ext]',//圖片名稱及后綴
outputPath: './img',//負責輸出目錄
publicPath: '/img',//對頁面引入資源的補充
esModule: false //esModule默認為true會導致打包圖片檔案時路徑錯誤輸出為[object-module]
}
},
{
loader: "image-webpack-loader",//使用就默認壓縮
//可根據引數調整壓縮程度
options: {
mozjpeg:{//jpeg圖片壓縮
quality:65 //1-100 壓縮程度,值越小壓縮越多
},
pngquant:{//png圖片壓縮
speed:4 //1-11
},
gifsicle:{//gif圖片壓縮
level:3 //1-3
}
}
}
]
},
//讓webpack識別vue模板,cnpm install vue vue-loader --save,cnpm install vue-template-compiler --save
{
test:/.vue$/,
loader:'vue-loader'
}
]
},
//plugins:插件,提供一些webpack沒有的功能
plugins: [
new CssMinimizerWebpackPlugin(),//壓縮css: cnpm install css-minimizer-webpack-plugin --save
new MiniCssExtractPlugin({
filename: "css/[name].[contenthash].css"//contenthash是針對檔案內容級別的,只有你自己的內容變了,那么hash值才改變
}),
//處理html,安裝插件cnpm install html-webpack-plugin --save
new HtmlWebpackPlugin({
template:"./index.html",//指定模板檔案
filename: "index.html",//檔案名
minify:{
removeComments:true,//清理html中的注釋
collapseWhitespace:true,//清理html中的空格、換行符
}
}),
new VueLoaderPlugin(),
]
}
三、補充說明
1.在package.json檔案中配置scripts 運行和打包命令
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bulid": "webpack --config webpack.config.js",
"dev": "webpack serve --config webpack.config.js"
},
webpack是打包命令,webpack5的運行命令是webpack serve,--config 指定組態檔的位置,與package.josn同級目錄可以默認不寫,
2.本文中用到的一些loader和plugin匯總
cnpm install html-webpack-plugin --save-dev
cnpm install css-minimizer-webpack-plugin --save-dev
cnpm install style-loader css-loader --save-dev
cnpm install mini-css-extract-plugin --save-dev
cnpm install babel-loader @babel/core --save-dev
cnpm install @babel/preset-env --save-dev
cnpm intsall file-loader url-loader --save-dev
cnpm install image-webpack-loader --save-dev
cnpm insatll image-loader imagemin imagemin-gifsicle imagemin-mozjpeg imagemin-pngquant --save-dev
cnpm install vue-loader --save-dev
cnpm install vue-template-compiler --save-dev
cnpm install babel-plugin-component --save-dev
cnpm install vue --save
cnpm install element-ui --save
cnpm install vue-router --save

3.路由組件懶加載和element-ui組件按需加載
路由懶加載:像vue這種單頁面應用,如果沒有懶加載,當打包構建應用時,JavaScript 包會變得非常大,影響頁面加載,如果我們能把不同路由對應的組件分割成不同的代碼塊,然后當路由被訪問的時候才加載對應組件,這樣就更加高效了,
import Vue from 'vue'
import Router from 'vue-router'
/*import HelloWorld from '/src/components/HelloWorld.vue'*/
const HelloWorld = () => import('/src/components/HelloWorld.vue') //路由懶加載
Vue.use(Router)
const router=new Router({
routes: [
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
//導航守衛
router.beforeEach((to, from, next) => {
console.log(to.path)
next()
})
export default router
element-ui組件按需加載:專案中使用的element-ui組件只要不是特別多或者是全部都用到都可以只引入我們所需要的組件,這樣可以減少專案體積,
/**
* @author zhangshuo
* @date 2021/9/29 16:27
* 匯入自己需要的element-UI組件,按需加載
**/
import {Input, Dialog, Button} from 'element-ui'
const element = {
install: function (Vue) {
Vue.use(Input)
Vue.use(Dialog)
Vue.use(Button)
}
}
export default element
在main.js中引入:
import element from './util/element.js' Vue.use(element)
想要使用element-ui按需加載就需要安裝babel-plugin-component,安裝命令在上面匯總中,然后要在根目錄下創建babel.config.js檔案,寫上以下配置:
module.exports = {
plugins: [
[
'component',
{
libraryName: 'element-ui',
styleLibraryName: 'theme-chalk'
}
]
]
}
4.最后截一張專案下目錄結構圖給大家,以上內容僅供參考,如果只是做vue專案,還是建議大家使用vue-cli的方式更方便,我這里用的webpack5,所以自己手寫的配置,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/305712.html
標籤:其他
上一篇:深入理解 JavaScript Runtime Event Loop
下一篇:手寫一個簡易的ajax,進行封裝
