Dieses Mal werde ich Ihnen die Schritte zur Codeaufteilung zur Optimierung der Vue-Verpackung ausführlich erläutern. Was sind die Vorsichtsmaßnahmen für die Codeaufteilung zur Optimierung der Vue-Verpackung? .
Im Zeitalter von http1 besteht eine der häufigsten Leistungsoptimierungen darin, die Anzahl der http-Anfragen zusammenzuführen. Normalerweise führen wir viele JS-Codes zusammen, aber wenn ein JS-Paket besonders groß ist In der Größe wäre es für die Leistungsverbesserung etwas übertrieben. Und wenn wir den gesamten Code sinnvoll aufteilen, den Erstbildschirm- und Nicht-Erstbildschirm-Code abziehen, den Geschäftscode und den Basisbibliothekscode aufteilen und dann bei Bedarf einen bestimmten Teil des Codes laden, wenn Sie das nächste Mal möchten Wenn Sie es erneut verwenden müssen, können Sie es aus dem Cache lesen. Zweitens kann es die Ladegeschwindigkeit des ersten Bildschirms verbessern, was die Benutzererfahrung erheblich verbessert.
Kernidee
Trennung von Geschäftscode und Basisbibliothek
Dies ist eigentlich leicht zu verstehen. Geschäftscode wird normalerweise häufig aktualisiert und iteriert Basisbibliotheken Normalerweise sind Aktualisierungen langsam. Wenn Sie sie hier aufteilen, können Sie den Browser-Cache vollständig nutzen, um den Basisbibliothekscode zu laden.
Asynchrones Laden bei Bedarf
Dies löst hauptsächlich das Problem der ersten Bildschirmanforderungsgröße. Beim Zugriff auf den ersten Bildschirm müssen wir nur die dafür erforderliche Logik laden erster Bildschirm und nicht der Code, der alle Routen lädt.
Praktischer Kampf
Vor kurzem habe ich vuetify verwendet, um ein internes System zu transformieren. Zu Beginn habe ich die am häufigsten verwendete Webpack-Konfiguration verwendet. Aber als ich es verpackte, stellte ich fest, dass der Effekt nicht sehr offensichtlich ist.
Hier sehen wir uns die Verpackungsverteilung an Hier wird vue und vuetify deutlich gesehen. Es gibt Fälle, in denen Module wiederholt gepackt werden.
Hier werden wir zuerst die Konfiguration veröffentlichen und sie später zur Analyse verwenden:
const path = require('path') const webpack = require('webpack') const CleanWebpackPlugin = require('clean-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; const generateHtml = new HtmlWebpackPlugin({ title: '逍遥系统', template: './src/index.html', minify: { removeComments: true } }) module.exports = { entry: { vendor: ['vue', 'vue-router', 'vuetify'], app: './src/main.js' }, output: { path: path.resolve(dirname, './dist'), filename: '[name].[hash].js', chunkFilename:'[id].[name].[chunkhash].js' }, resolve: { extensions: ['.js', '.vue'], alias: { 'vue$': 'vue/dist/vue.esm.js', 'public': path.resolve(dirname, './public') } }, module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { } // other vue-loader options go here } }, { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { test: /\.(png|jpg|gif|svg)$/, loader: 'file-loader', options: { objectAssign: 'Object.assign' } }, { test: /\.css$/, loader: ['style-loader', 'css-loader'] }, { test: /\.styl$/, loader: ['style-loader', 'css-loader', 'stylus-loader'] } ] }, devServer: { historyApiFallback: true, noInfo: true }, performance: { hints: false }, devtool: '#eval-source-map', plugins: [ new BundleAnalyzerPlugin(), new CleanWebpackPlugin(['dist']), generateHtml, new webpack.optimize.CommonsChunkPlugin({ name: 'ventor' }), ] } if (process.env.NODE_ENV === 'production') { module.exports.devtool = '#source-map' // http://vue-loader.vuejs.org/en/workflow/production.html module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }), new webpack.optimize.UglifyJsPlugin({ sourceMap: true, compress: { warnings: false } }), new webpack.LoaderOptionsPlugin({ minimize: true }) ]) }
CommonChunkPlugin
ventor Eintrag Hier stellen wir fest, dass alle Module unter dem referenzierten node_module, wie z. B. axios, nicht herausgefiltert werden, also werden sie in app.js gepackt. Hier führen wir die Trennung durch
entry: { vendor: ['vue', 'vue-router', 'vuetify', 'axios'], app: './src/main.js' },
Dann gibt es hier ein weiteres Problem, Ich weiß nicht, dass Sie das Modul zu diesem Zeitpunkt möglicherweise manuell eingeben müssen. Hier müssen wir minChunks einführen. In der Konfiguration können wir die unter mode_module referenzierten Module wie folgt packen und ändern
entry: { //vendor: ['vue', 'vue-router', 'vuetify', 'axios'], //删除 app: './src/main.js' } new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: ({ resource }) => ( resource && resource.indexOf('node_modules') >= 0 && resource.match(/\.js$/) ) }),
// const dbmanage = () => import(/* webpackChunkName: "dbmanage" */'../views/dbmanage.vue') // const system = () => import(/* webpackChunkName: "system" */'../views/system.vue') import dbmanage from '../views/dbmanage.vue' import system from '../views/system.vue'
Zu diesem Zeitpunkt stellen wir beim Umpacken fest, dass Codemirror verpackt wurde. Die Frage ist also: Ist das gut?
asynchron上面的问题答案是肯定的,不可以的,很明显ventor是我们的入口代码即首屏,我们完全没有必要去加载这个codemirror组件,我们先把刚才的路由修改恢复回去,但是这时又有了新问题,我们的codemirror被同时打包进了两个单页面,并且还有些自己封装的components,例如MTable或是MDataTable等也出现了重复打包。并且codemirror特别大,同时加载到两个单页面也会造成很大的性能问题,简单说就是,我们在访问第一个单页面加载了codemirror之后,在第二个页面其实就不应该再加载了。 要解决这个问题,这里我们可以使用 CommonsChunkPlugin 的 async 并在 minChunnks 里的count方法来判断数量,只要是 重用次数 超过两个包括两个的异步加载模块(即 import () 产生的chunk )我们都认为是 可以 打成公共的 ,这里我们增加一项配置。 再次打包,我们发现所有服用的组件被重新打到了 0.used-twice-app.js中了,这样各个单页面大小也有所下降,平均小了近10k左右 可是,这里我们发现vuetify.js和vuetify.css实在太庞大了,导致我们的打包的代码很大,这里,我们考虑把它提取出来,这里为了避免重复打包,需要使用external,并将vue以及vuetify的代码采用cdn读取的方式,首先修改index.html 再修改webpack配置,新增externals 再重新打包,可以看到vue相关的代码已经没有了,目前也只有used-twice-app.js比较大了,app.js缩小了近200kb。 但是新问题又来了,codemirror很大,而used-twice又是首屏需要的,这个打包在首屏肯定不是很好,这里我们要将system和dbmanage页面的codemirror组件改为异步加载,单独打包,修改如下: 重新打包下,可以看到 codemirror被抽离了,首屏代码进一步得到了减少,used-twice-app.js代码缩小了近150k。 做了上面这么多的优化之后,业务测的js基本都被拆到了50kb一下(忽略map文件),算是优化成功了。 总结 可能会有朋友会问,单独分拆vue和vuetify会导致请求数增加,这里我想补充下,我们的业务现在已经切换成http2了,由于多路复用,并且加上浏览器缓存,我们分拆出的请求数其实也算是控制在合理的范畴内。 这里最后贴一下优化后的webpack配置,大家一起交流学习下哈。 相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章! 推荐阅读:new webpack.optimize.CommonsChunkPlugin({
async: 'used-twice',
minChunks: (module, count) => (
count >= 2
),
})
//css引入
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
<link href="https://unpkg.com/vuetify/dist/vuetify.min.css" rel="external nofollow" rel="stylesheet">
//js引入
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuetify/dist/vuetify.js"></script>
//去掉main.js中之前对vuetifycss的引入
//import 'vuetify/dist/vuetify.css'
externals: {
'vue':'Vue',
"vuetify":"Vuetify"
}
// import MCode from "../component/MCode.vue"; //注释掉
components: {
MDialog,
MCode: () => import(/* webpackChunkName: "MCode" */'../component/MCode.vue')
},
const path = require('path')
const webpack = require('webpack')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const generateHtml = new HtmlWebpackPlugin({
title: '逍遥系统',
template: './src/index.html',
minify: {
removeComments: true
}
})
module.exports = {
entry: {
app: './src/main.js'
},
output: {
path: path.resolve(dirname, './dist'),
filename: '[name].[hash].js',
chunkFilename:'[id].[name].[chunkhash].js'
},
resolve: {
extensions: ['.js', '.vue'],
alias: {
'vue$': 'vue/dist/vue.esm.js',
'public': path.resolve(dirname, './public')
}
},
externals: {
'vue':'Vue',
"vuetify":"Vuetify"
},
module: {
rules: [
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
}
// other vue-loader options go here
}
},
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
objectAssign: 'Object.assign'
}
},
{
test: /\.css$/,
loader: ['style-loader', 'css-loader']
},
{
test: /\.styl$/,
loader: ['style-loader', 'css-loader', 'stylus-loader']
}
]
},
devServer: {
historyApiFallback: true,
noInfo: true
},
performance: {
hints: false
},
devtool: '#eval-source-map',
plugins: [
new CleanWebpackPlugin(['dist']),
generateHtml
]
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
module.exports.plugins = (module.exports.plugins || []).concat([
new BundleAnalyzerPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'ventor',
minChunks: ({ resource }) => (
resource &&
resource.indexOf('node_modules') >= 0 &&
resource.match(/\.js$/)
)
}),
new webpack.optimize.CommonsChunkPlugin({
async: 'used-twice',
minChunks: (module, count) => (
count >= 2
),
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung der Codeaufteilung zur Optimierung der Vue-Paketierungsschritte. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!