1.生产环境的Source Map:
为了在生产环境中避免暴露源代码,我们可以使用隐藏的Source Map。
module.exports = {
productionSourceMap: false, // 不生成Source Map
// 或者
productionSourceMap: 'hidden-source-map' // 生成隐藏的Source Map
};
2.Gzip压缩:
使用Gzip压缩可以减小传输文件的大小,提高加载速度。
const CompressionWebpackPlugin = require('compression-webpack-plugin');
module.exports = {
configureWebpack: {
plugins: [
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
['js', 'css'].join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
]
}
};
3.优化构建性能:
使用thread-loader
来并行处理Babel转换。
const ThreadLoader = require('thread-loader');
module.exports = {
configureWebpack: {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
},
{
loader: ThreadLoader,
options: {
// worker数量
workers: 3
}
}
]
}
]
}
}
};
4.分析构建包:
使用webpack-bundle-analyzer
插件来分析构建后的包大小,找出可能存在的优化点。
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
config
.plugin('webpack-bundle-analyzer')
.use(BundleAnalyzerPlugin, [{
analyzerMode: 'server'
}]);
}
}
};
5.公共路径和输出目录:
指定输出文件的公共路径和输出目录。
module.exports = {
publicPath: './', // 公共路径
outputDir: 'dist', // 输出目录
assetsDir: 'static', // 静态资源目录
indexPath: 'index.html', // 入口html文件
};
6.环境变量:
使用.env
文件来定义环境变量,在构建时注入到项目中。
// .env.production
VUE_APP_API_URL=https://api.example.com
// 在代码中
console.log(process.env.VUE_APP_API_URL);
7.优化CSS处理:
使用mini-css-extract-plugin
来提取CSS到单独的文件中。
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
css: {
extract: true,
loaderOptions: {
css: {
// 这里可以添加CSS预处理器(如sass)的选项
}
}
},
configureWebpack: {
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css',
})
]
}
};
8.优化图片和字体加载:
使用url-loader或file-loader。对于小图片和字体文件,可以使用url-loader
将它们转换为Base64编码,并直接嵌入到生成的JS或CSS文件中,避免额外的HTTP请求。对于大文件,则可以使用file-loader
将它们复制到输出目录中,并返回相对URL。
在vue.config.js
中配置url-loader
:
module.exports = {
chainWebpack: config => {
config.module
.rule('images')
.test(/\.(png|jpe?g|gif|webp)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: 8192, // 小于8kb的图片转换为Base64编码
name: 'img/[name].[hash:7].[ext]' // 输出到img目录,文件名包含hash值
});
config.module
.rule('fonts')
.test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/)
.use('url-loader')
.loader('url-loader')
.options({
limit: 10000, // 小于10kb的字体文件转换为Base64编码
name: 'fonts/[name].[hash:7].[ext]' // 输出到fonts目录,文件名包含hash值
});
}
};
懒加载图片:使用Vue的懒加载功能或第三方库如vue-lazyload来延迟加载非视口内的图片。
利用CDN加速:将静态资源托管到CDN上,以便更快地服务于全球用户。
9.利用代码分割和异步组件
代码分割是一种将代码拆分成多个小块的技术,以便按需加载。在Vue应用中,你可以利用Webpack的代码分割功能来分割你的代码,以便只加载用户当前需要的部分。这可以通过动态导入(dynamic imports)和异步组件(async components)来实现。
动态导入(Dynamic Imports)
使用import()
语法来动态导入模块。Webpack会自动识别这种语法,并将代码分割成单独的chunk。
const router = new Router({
routes: [
{ path: '/foo', component: () => import('./Foo.vue') },
{ path: '/bar', component: () => import('./Bar.vue') }
]
});
异步组件(Async Components)
Vue也提供了异步组件的功能,允许你定义一个返回一个Promise的工厂函数。这个Promise的解析值应该是一个Vue组件定义。
const AsyncComponent = () => ({
component: import('./MyComponent.vue'),
// 加载和错误状态
loading: LoadingComponent,
error: ErrorComponent,
// 延迟加载,例如1秒后加载组件
delay: 1000,
// 尝试加载组件的最大次数
timeout: 3000,
});
在vue.config.js
中,可以通过配置Webpack来进一步控制代码分割的行为。例如,你可以调整chunk的命名规则、输出路径等。
module.exports = {
configureWebpack: {
output: {
// 自定义chunk的输出名称
chunkFilename: 'js/[name].[contenthash].js',
},
optimization: {
// 调整代码分割的配置
splitChunks: {
chunks: 'all', // 可以是 'initial'、'async' 或 'all'
minSize: 20000, // 最小尺寸,默认0
maxSize: 0, // 最大尺寸,默认0
minChunks: 1, // 最小chunk数,默认1
maxAsyncRequests: 30, // 按需加载的最大并行请求数,默认30
maxInitialRequests: 30, // 一个入口点加载的最大并行请求数,默认30
automaticNameDelimiter: '~', // 用于命名缓存组的默认分隔符
cacheGroups: {
// 在这里可以配置额外的缓存组,例如针对vendor库或node_modules中的模块进行分割
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
reuseExistingChunk: true,
},
// ...其他缓存组配置
},
},
},
},
};
10.优化第三方库
-
按需加载库:只引入你实际需要的库的部分,而不是整个库。这可以通过使用库的按需加载功能或自定义构建来实现。
-
使用CDN加载库:对于大型的第三方库,可以考虑使用CDN(内容分发网络)来加载它们,以减少应用自身的构建大小。
在vue.config.js
中,你可以通过配置externals
选项来排除某些库,使它们通过CDN加载:
module.exports = {
configureWebpack: {
externals: {
// 将这些库排除在构建之外,通过CDN加载
'vue': 'Vue',
'axios': 'axios'
}
}
};
然后在你的HTML模板中,通过CDN引入这些库:
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
11.利用Tree Shaking和Scope Hoisting
Tree Shaking可以帮助你消除JavaScript上下文中的未引用代码,即“摇掉”树上的无用叶子。而Scope Hoisting则可以将多个模块的变量声明提升到单个作用域中,从而减少函数声明和内存消耗。
在vue.config.js
中,你可以通过配置Webpack来启用Tree Shaking和Scope Hoisting:
module.exports = {
configureWebpack: {
optimization: {
usedExports: true, // 启用Tree Shaking
concatenateModules: true, // 启用Scope Hoisting
},
},
};
12.监控和分析性能
使用性能监控工具(如Lighthouse、Webpagetest等)来分析和优化你的应用性能。这些工具可以提供关于加载时间、资源大小、请求数量等方面的详细报告,帮助你找到性能瓶颈并进行优化。
总结:
一、构建和打包优化
- 压缩输出资源:使用Gzip或Brotli等算法压缩构建的输出文件,减少传输时间。
- 优化Source Maps:根据需要生成Source Maps,权衡其实用性和构建大小。
- 优化第三方库:按需加载库,使用CDN加载大型库,减少应用自身的构建大小。
- 利用Tree Shaking和Scope Hoisting:消除未引用代码,减少函数声明和内存消耗。
二、图片和静态资源优化
- 压缩图片:使用工具压缩图片大小,减少带宽消耗。
- 选择适当的图片格式:根据内容选择JPEG、PNG或WebP等格式。
- 懒加载图片:延迟加载非视口内的图片,提升页面加载速度。
- 利用CDN加速:将静态资源托管到CDN,加快全球用户的访问速度。
三、路由和组件优化
- 预加载和预获取资源:优化资源加载顺序和时机,提高页面加载性能。
- 使用路由懒加载:按需加载路由对应的组件,减少初始加载时间。
四、性能监控和分析
- 监控和分析性能:使用性能监控工具分析应用的加载时间、资源大小等,找到性能瓶颈并进行优化。