優化
- 一、知識點和目的
- 1、打包優化的目的
- 2、性能優化的主要方向
- 二、打包優化
- 1.去除.map檔案
- 2.開啟CDN加速
- 3.代碼壓縮
- 4.圖片壓縮
- 5.公共代碼抽離,寫在configureWebpack模塊中
- 6.骨架屏
- 7.開啟Gzip壓縮
- 全部代碼
點擊跳轉博主博客
一、知識點和目的
1、打包優化的目的
1、專案啟動速度,和性能
2、必要的清理資料
3、減少打包后的體積
第一點是核心,第二點呢其實主要是清理console
2、性能優化的主要方向
1、去重.map檔案
2、開啟CDN加速
3、代碼壓縮
4、圖片壓縮
5、公共代碼抽離,寫在configureWebpack模塊中
6、首屏骨架屏優化
7、開啟Gzip壓縮
二、打包優化
1.去除.map檔案
在vue.config.js中添加
productionSourceMap: false, //不輸出map檔案
2.開啟CDN加速
快速查找對應cdn
// 是否為生產環境
const isProduction = process.env.NODE_ENV !== 'development';
// 本地環境是否需要使用cdn
const devNeedCdn = false
// cdn鏈接
const cdn = {
// cdn:模塊名稱和模塊作用域命名(對應window里面掛載的變數名稱)
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
'marked': 'marked',
'highlight.js': 'hljs',
'nprogress': 'NProgress',
'axios': 'axios'
},
// cdn的css鏈接
css: [
],
// cdn的js鏈接
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js',
'https://cdn.bootcss.com/axios/0.19.2/axios.min.js'
]
}
module.exports = {
chainWebpack: config => {
// ============注入cdn start============
config.plugin('html').tap(args => {
// 生產環境或本地需要cdn時,才注入cdn
if (isProduction || devNeedCdn) args[0].cdn = cdn
return args
})
// ============注入cdn start============
},
configureWebpack: config => {
// 用cdn方式引入,則構建時要忽略相關資源
if (isProduction || devNeedCdn) config.externals = cdn.externals
}
}
<!-- 使用CDN的CSS檔案 -->
<% for (var i in htmlWebpackPlugin.options.cdn &&
htmlWebpackPlugin.options.cdn.css) { %>
<link
href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"
rel="stylesheet"
/>
<% } %>
<!-- 使用CDN的CSS檔案 -->
<!-- 使用CDN的JS檔案 -->
<% for (var i in htmlWebpackPlugin.options.cdn &&
htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- 使用CDN的JS檔案 -->
3.代碼壓縮
安裝插件 npm i -D uglifyjs-webpack-plugin
// 代碼壓縮
//在configureWebpack中加入
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// 代碼壓縮
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
//生產環境自動洗掉console
compress: {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
}
},
sourceMap: false,
parallel: true
})
)
4.圖片壓縮
安裝插件 npm install image-webpack-loader --save-dev
在chainWebpack中新增以下代碼
// ============壓縮圖片 start============
config.plugins.delete('prefetch')
config.module.rule('images')
.test(/\.(png|jpe?g|gif|svg)(\?.*)?$/)
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({ bypassOnDebug: true })
// ============壓縮圖片 end============
圖片生成在線地址
5.公共代碼抽離,寫在configureWebpack模塊中
// 公共代碼抽離
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'common',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 60
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
6.骨架屏
安裝插件 npm install vue-skeleton-webpack-plugin
在src下新建Skeleton檔案夾,其中新建index.js以及index.vue,在其中寫入以下內容,其中,骨架屏的index.vue頁面樣式請自行編輯
index.js
import Vue from 'vue'
import home from './index.vue'
import list from './a.vue'
export default new Vue({
components: {
home,
list
},
template: `
<div>
<home id="home" style="display:none"/>
<list id="list" style="display:none"/>
</div>
`
})
骨架屏頁面
<template>
<div class="skeleton-wrapper">
<header class="skeleton-header"></header>
<section class="skeleton-block">
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg==">
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMTA4MCAyNjEiPjxkZWZzPjxwYXRoIGlkPSJiIiBkPSJNMCAwaDEwODB2MjYwSDB6Ii8+PGZpbHRlciBpZD0iYSIgd2lkdGg9IjIwMCUiIGhlaWdodD0iMjAwJSIgeD0iLTUwJSIgeT0iLTUwJSIgZmlsdGVyVW5pdHM9Im9iamVjdEJvdW5kaW5nQm94Ij48ZmVPZmZzZXQgZHk9Ii0xIiBpbj0iU291cmNlQWxwaGEiIHJlc3VsdD0ic2hhZG93T2Zmc2V0T3V0ZXIxIi8+PGZlQ29sb3JNYXRyaXggaW49InNoYWRvd09mZnNldE91dGVyMSIgdmFsdWVzPSIwIDAgMCAwIDAuOTMzMzMzMzMzIDAgMCAwIDAgMC45MzMzMzMzMzMgMCAwIDAgMCAwLjkzMzMzMzMzMyAwIDAgMCAxIDAiLz48L2ZpbHRlcj48L2RlZnM+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIDEpIj48dXNlIGZpbGw9IiMwMDAiIGZpbHRlcj0idXJsKCNhKSIgeGxpbms6aHJlZj0iI2IiLz48dXNlIGZpbGw9IiNGRkYiIHhsaW5rOmhyZWY9IiNiIi8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCA0NGg1MzN2NDZIMjMweiIvPjxyZWN0IHdpZHRoPSIxNzIiIGhlaWdodD0iMTcyIiB4PSIzMCIgeT0iNDQiIGZpbGw9IiNGNkY2RjYiIHJ4PSI0Ii8+PHBhdGggZmlsbD0iI0Y2RjZGNiIgZD0iTTIzMCAxMThoMzY5djMwSDIzMHpNMjMwIDE4MmgzMjN2MzBIMjMwek04MTIgMTE1aDIzOHYzOUg4MTJ6TTgwOCAxODRoMjQydjMwSDgwOHpNOTE3IDQ4aDEzM3YzN0g5MTd6Ii8+PC9nPjwvc3ZnPg==">
</section>
</div>
</template>
<script>
export default {
name: 'skeleton'
}
</script>
<style scoped>
.skeleton-header {
height: 40px;
background: #1976d2;
padding:0;
margin: 0;
width: 100%;
}
.skeleton-block {
display: flex;
flex-direction: column;
padding-top: 8px;
}
</style>
vue.config.js
//骨架屏渲染
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
//path引入
const path = require('path')
//configureWebpack模塊中寫入內容
// 骨架屏渲染
config.plugins.push(new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: path.join(__dirname, './src/Skeleton/index.js'),
},
},
minimize: true,
quiet: true,
// 如果不設定那么所有的路由都會共享這個骨架屏組件
router: {
mode: 'hash',
// 給對應的路由設定對應的骨架屏組件,skeletonId的值根據組件設定的id
routes: [
{ path: '/list', skeletonId: 'home' },
{ path: '/kc', skeletonId: 'list' },
]
}))
7.開啟Gzip壓縮
`注意的是,服務器上nginx也必須開啟gzip才能生效`
// 是否為生產環境
const isProduction = process.env.NODE_ENV !== 'development';
// gzip壓縮
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
productionSourceMap: false,
configureWebpack: config => {
// 生產環境相關配置
if (isProduction) {
//gzip壓縮
const productionGzipExtensions = ['html', 'js', 'css']
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' + productionGzipExtensions.join('|') + ')$'
),
threshold: 10240, // 只有大小大于該值的資源會被處理 10240
minRatio: 0.8, // 只有壓縮率小于這個值的資源才會被處理
deleteOriginalAssets: false // 洗掉原檔案
})
)
}
}
}
nginx中
# 開啟gzip
gzip on;
# 啟用gzip壓縮的最小檔案,小于設定值的檔案將不會壓縮
gzip_min_length 1k;
# gzip 壓縮級別,1-9,數字越大壓縮的越好,也越占用CPU時間,后面會有詳細說明
gzip_comp_level 2;
# 進行壓縮的檔案型別,javascript有多種形式,后面的圖片壓縮不需要的可以自行洗掉
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
# 是否在http header中添加Vary: Accept-Encoding,建議開啟
gzip_vary on;
# 設定壓縮所需要的緩沖區大小
gzip_buffers 4 16k;
全部代碼
// vue.config.js
//骨架屏渲染
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
//path引入
const path = require('path')
// 是否為生產環境
const isProduction = process.env.NODE_ENV !== 'development';
// 代碼壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
// 本地環境是否需要使用cdn
const devNeedCdn = false
// cdn鏈接
const cdn = {
// cdn:模塊名稱和模塊作用域命名(對應window里面掛載的變數名稱)
externals: {
vue: 'Vue',
vuex: 'Vuex',
'vue-router': 'VueRouter',
'axios': 'axios',
'element-ui': 'ELEMENT',
'vant':'vant'
},
// cdn的css鏈接
css: [
'https://unpkg.com/element-ui/lib/theme-chalk/index.css',
'https://cdn.jsdelivr.net/npm/vant@2.12/lib/index.css',
],
// cdn的js鏈接
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',
'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js',
'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js',
'https://cdn.bootcss.com/axios/0.19.2/axios.min.js',
'https://unpkg.com/element-ui/lib/index.js',
'https://cdn.jsdelivr.net/npm/vant@2.12/lib/vant.min.js'
]
}
module.exports = {
lintOnSave: false,
publicPath: './',
css: {
loaderOptions: {
postcss: {
plugins: [
require('postcss-plugin-px2rem')({
rootValue:35, //換算基數, 默認100 ,這樣的話把根標簽的字體規定為1rem為50px,這樣就可以從設計稿上量出多少個px直接在代碼中寫多上px了,
// unitPrecision: 5, //允許REM單位增長到的十進制數字,
//propWhiteList: [], //默認值是一個空陣列,這意味著禁用白名單并啟用所有屬性,
// propBlackList: [], //黑名單
// exclude: /(page_pc)/i, //默認false,可以(reg)利用正則運算式排除某些檔案夾的方法,例如/(node_module)/ ,如果想把前端UI框架內的px也轉換成rem,請把此屬性設為默認值
exclude: /node_modules/i,
// selectorBlackList: ['van-'], //要忽略并保留為px的選擇器,我們一般不轉換vantui中的大小
// ignoreIdentifier: false, //(boolean/string)忽略單個屬性的方法,啟用ignoreidentifier后,replace將自動設定為true,
// replace: true, // (布林值)替換包含REM的規則,而不是添加回退,
mediaQuery: false, //(布林值)允許在媒體查詢中轉換px,
minPixelValue: 3 //設定要替換的最小像素值(3px會被轉rem), 默認 0
}),
]
}
}
},
productionSourceMap: false, //不輸出map檔案
chainWebpack: config => {
// ============注入cdn start============
config.plugin('html').tap(args => {
// 生產環境或本地需要cdn時,才注入cdn
if (isProduction || devNeedCdn) args[0].cdn = cdn
return args
})
// ============注入cdn start============
// ============壓縮圖片 start============
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({bypassOnDebug: true
})
.end()
// ============壓縮圖片 end============
},
configureWebpack: config => {
if (isProduction || devNeedCdn) config.externals = cdn.externals
config.plugins.push(new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: path.join(__dirname, './src/Skeleton/entry-skeleton.js'),
},
},
minimize: true,
quiet: true,
router: {
mode: 'hash',
// 給對應的路由設定對應的骨架屏組件,skeletonId的值根據組件設定的id
routes: [
{ path: '/list', skeletonId: 'skeleton' }
]
}
}))
// 用cdn方式引入,則構建時要忽略相關資源
// if (isProduction || devNeedCdn) config.externals = cdn.externals
// 公共代碼抽離
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /node_modules/,
name: 'vendor',
minChunks: 1,
maxInitialRequests: 5,
minSize: 0,
priority: 100
},
common: {
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/,
name: 'common',
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 60
},
styles: {
name: 'styles',
test: /\.(sa|sc|c)ss$/,
chunks: 'all',
enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
// 代碼壓縮
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
//生產環境自動洗掉console
compress: {
drop_debugger: true,
drop_console: true,
pure_funcs: ['console.log']
}
},
sourceMap: false,
parallel: true
})
)
},
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/246865.html
標籤:其他
上一篇:關于在Gitee上部署Hexo出現的常見問題及解決辦法
下一篇:PHP實作簡單的網站訪客統計
