图片压缩:使用图片图片压缩、优化工具TinyPNG、TinyJPG压缩图片,或者使用其Gulp 组件
gulp-tinypng
结合到自动化构件流程中;
图片格式转为base64: 使用webpack的
url-loader
,自动根据文件大小决定要不要做成内联 base64;
图片懒加载: vue.js可用使用
vue-lazyload
;
2、CDN优化
将依赖的静态资源如
vue
、
vue-router
、
vuex
等,全部改为通过CDN链接获取。
借助HtmlWebpackPlugin,可以方便的使用循环语法在index.html里插入js和css的CDN链接。推荐CDN使用
jsDelivr
提供的。
index.html
文件中
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
<% } %>
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
<% } %>
vue.config.js
下添加如下代码,这使得在使用CDN引入外部文件的情况下,依然可以在项目中使用import的语法来引入这些第三方库,也就意味着你不需要改动项目的代码
const externals = {
vue: 'Vue',
'vue-router': 'VueRouter',
vuex: 'Vuex',
axios: 'axios',
vant: 'vant',
'pdfjs-dist': 'pdfjs',
config.plugin('html').tap((args) => {
if (process.env.NODE_ENV === 'production') {
args[0].cdn = CDN.build;
return args;
复制代码
3、Prerender 预渲染
4、Gzip 优化
后台开启gzip
压缩,以nginx服务器为例
gzip on;
gzip_static on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 2;
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript application/x-httpd-php application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;
gzip_vary on;
gzip_disable "MSIE [1-6]\.";
前端gzip压缩
nginx
设置gzip_static on
,就会使用同名的.gz文件,不会占用服务器的CPU资源去压缩
const CompressionPlugin = require('compression-webpack-plugin');
configureWebpack: () => {
if (process.env.NODE_ENV === 'production') {
const compressionTest = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
return {
plugins: [
new CompressionPlugin({
test: compressionTest,
minRatio: 0.99,
复制代码
const path = require('path')
const chalk = require('chalk')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
const PrerenderSPAPlugin = require('prerender-spa-plugin')
const DIST_ROOT = 'dist'
const BASE_URL = '/my-app/'
const externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'element-ui': 'ELEMENT'
const cdn = {
dev: {
css: [
'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
js: []
build: {
css: [
'https://unpkg.com/element-ui/lib/theme-chalk/index.css'
js: [
'https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.min.js',
'https://cdn.jsdelivr.net/npm/vue-router@3.0.1/dist/vue-router.min.js',
'https://cdn.jsdelivr.net/npm/vuex@3.0.1/dist/vuex.min.js',
'https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js',
'https://unpkg.com/element-ui/lib/index.js'
const productionPrerender = true
const prerenderRoutes = ['/', '/contacts']
const productionGzip = true
const productionGzipExtensions = ['js', 'css']
module.exports = {
baseUrl: BASE_URL,
outputDir: DIST_ROOT + BASE_URL,
assetsDir: 'static',
productionSourceMap: false,
configureWebpack: config => {
const myConfig = {}
if (process.env.NODE_ENV === 'production') {
myConfig.externals = externals
myConfig.plugins = []
productionPrerender && myConfig.plugins.push(
new PrerenderSPAPlugin({
staticDir: path.resolve(__dirname, DIST_ROOT), // 作为express.static()中间件的路径
outputDir: path.resolve(__dirname, DIST_ROOT + BASE_URL),
indexPath: path.resolve(__dirname, DIST_ROOT + BASE_URL + 'index.html'),
routes: prerenderRoutes,
minify: {
collapseBooleanAttributes: true,
collapseWhitespace: true,
decodeEntities: true,
keepClosingSlash: true,
sortAttributes: true
postProcess (renderedRoute) {
* 懒加载模块会自动注入,无需直接通过script标签引入
* 而且预渲染的html注入的是modern版本的懒加载模块
* 这会导致在低版本浏览器出现报错,需要剔除
* 这并不是一个非常严谨的正则,不适用于使用了 webpackChunkName: "group-foo" 注释的懒加载
renderedRoute.html = renderedRoute.html.replace(
/<script[^<]*chunk-[a-z0-9]{8}\.[a-z0-9]{8}.js[^<]*><\/script>/g,
function (target) {
console.log(chalk.bgRed('\n\n剔除的懒加载标签:'), chalk.magenta(target))
return ''
return renderedRoute
productionGzip && myConfig.plugins.push(
new CompressionWebpackPlugin({
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 8192,
minRatio: 0.8
if (process.env.NODE_ENV === 'development') {
* 关闭host check,方便使用ngrok之类的内网转发工具
myConfig.devServer = {
disableHostCheck: true
return myConfig
chainWebpack: config => {
* 删除懒加载模块的prefetch,降低带宽压力
* https://cli.vuejs.org/zh/guide/html-and-static-assets.html#prefetch
* 而且预渲染时生成的prefetch标签是modern版本的,低版本浏览器是不需要的
config.plugins
.delete('prefetch')
* 添加CDN参数到htmlWebpackPlugin配置中
config
.plugin('html')
.tap(args => {
if (process.env.NODE_ENV === 'production') {
args[0].cdn = cdn.build
if (process.env.NODE_ENV === 'development') {
args[0].cdn = cdn.dev
return args
* 无需使用@import在每个scss文件中引入变量或者mixin,也可以避免大量@import导致build变慢
* sass-resources-loader 文档链接:https://github.com/shakacode/sass-resources-loader
const oneOfsMap = config.module.rule('scss').oneOfs.store
const sassResources = ['color.scss', 'mixin.scss', 'common.scss']
oneOfsMap.forEach(item => {
.use('sass-resources-loader')
.loader('sass-resources-loader')
.options({
resources: sassResources.map(file => path.resolve(__dirname, 'src/style/' + file))
.end()
复制代码