Why optimize packaging?
- The larger the project, the more dependent packages, the package file is too large
- The blank screen on the homepage of a single-page application lasts for a long time, resulting in poor user experience
Our purpose
- Reduce the size of the packaged file
- The home page introduces files on demand
- Optimize WebPack packaging time
Optimize the way
1. Load on demand
1.1 Load routing Components as required
const router = [
{
path: '/index'.component: resolve= > require.ensure([], () => resolve(require('@/components/index')))}, {path: '/about'.component: resolve= > require.ensure([], () => resolve(require('@/components/about')))}]Copy the code
1.2 Third-party Components and Plug-ins. Load on demand Import third-party components
// Import all components
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)
// Import components as needed
import { Button } from 'element-ui'
Vue.component(Button.name, Button)
Copy the code
1.3 For some plug-ins, if only used in individual components, can not be introduced in main.js, but in the component on demand
// in main.js
import Vue from vue
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)
// Component by component on demand
import { Vuelidate } from 'vuelidate'
Copy the code
2. Optimize loader configuration
- Optimized regular matching
- Enable caching with the cacheDirectory option
- Reduce the number of files to be processed by include and exclude.
module: {
rules: [{test: /\.js$/.loader: 'babel-loader? cacheDirectory'.include: [resolve('src')]}}]Copy the code
3. Optimize file paths — save time searching for files
- After the extension configuration, you don’t need to add file extensions to require or import.
- After mainFiles is configured, the system does not add file names. The system tries to match the added file names
- Alias enables WebPack to find modules faster by configuring an alias.
resolve: {
extensions: ['.js'.'.vue'.'.json'].alias: {
'vue$': 'vue/dist/vue.esm.js'.The '@': resolve('src'),}},Copy the code
4. Shut down sourceMap in production environment
- SourceMap is essentially a mapping relationship where the code in the packaged JS file can be mapped to the specific location of the code file. This mapping relationship helps us find errors directly in the source code.
- Packaging slows down and production files get bigger, so the development environment uses sourceMap and the production environment shuts down.
5. Code compression
- UglifyJS: Vue-CLI default code compression method, it uses single-threaded compression code, packaging time is slow
- ParallelUglifyPlugin: Enable multiple sub-processes to compress files for multiple sub-processes
Two methods are used as follows:
plugins: [
new UglifyJsPlugin({
uglifyOptions: {
compress: {
warnings: false}},sourceMap: true.parallel: true
}),
new ParallelUglifyPlugin({
// Cache the compressed result. The next time the same input is encountered, fetch the compressed result directly from the cache and return it.
//cacheDir Is used to configure the directory path where the cache is stored.
cacheDir: '.cache/'.sourceMap: true.uglifyJS: {
output: {
comments: false
},
compress: {
warnings: false}}})]Copy the code
Compare the speed of packing with the size of the file after packing
methods | The file size | Packing speed |
---|---|---|
No plug-in | 14.6 M | 32s |
UglifyJsPlugin | 12.9 M | 33s |
ParallelUglifyPlugi | 7.98 M | 17s |
Extract common code
- The same resources are loaded repeatedly, wasting user traffic and increasing server costs.
- Too many resources need to be loaded on each page. As a result, the first screen of a web page loads slowly, affecting user experience.
Webpack3 using CommonsChunkPlugin implementation:
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor'.minChunks: function(module, count) {
console.log(module.resource, 'times of citation${count}`)
//" there is a file in process "+" This file is.js suffix "+" this file is in node_modules"
return module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, './node_modules'= = =))0}}),new webpack.optimize.CommonsChunkPlugin({
name: 'common'.chunks: 'initial'.minChunks: 2})]Copy the code
Webpack4 uses splitChunks:
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
priority: 1.// Add weights
test: /node_modules/.// Extract the libraries in this directory that meet the following criteria
chunks: 'initial'.// Start by pulling away
minChunks: 2 // It needs to be removed when used twice
},
common: {
// Public module
chunks: 'initial'.minChunks: 2
}
}
}
}
}
Copy the code
7. CDN optimization
- As the project grows, it relies on more and more third-party NPM packages, and the files it builds become larger and larger.
- Coupled with single-page applications, this can lead to long periods of blank screens on slow Internet speeds or with limited server bandwidth.
1. Change vUE, VUE-Router, vuex, Element-UI and AXIos libraries to CDN links and insert corresponding links in index. HTML.
<head>
<link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.0.7/theme-chalk/index.css" />
</head>
<body>
<div id="app"></div>
<script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
<script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
<script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script>
<script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
<script src="https://cdn.bootcss.com/element-ui/2.6.1/index.js"></script>
<! -- built files will be auto injected -->
</body>
Copy the code
2. In the webpack.config.js configuration file
module.exports = {··· externals: {'vue': 'Vue'.'vuex': 'Vuex'.'vue-router': 'VueRouter'.'element-ui': 'ELEMENT'.'Axios':'axios'}},Copy the code
3, uninstall the dependent NPM package, NPM uninstall AXIos element-UI vue vuex
4, modify the main. Js file before the package way
// import Vue from 'vue'
// import ElementUI from 'element-ui'
// import 'element-ui/lib/theme-chalk/index.css'
// import VueRouter from 'vue-router'
import App from './App.vue'
import routes from './router'
import utils from './utils/Utils'
Vue.use(ELEMENT)
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'hash'.// The routing mode
routes
})
new Vue({
router,
el: '#app'.render: h= > h(App)
})
Copy the code
8. Use HappyPack to parse and process files
- Since Webpack running on Node.js is a single-threaded model, the things that Webpack needs to handle need to be done one at a time, not all at once.
- HappyPack allows Webpack to split tasks into multiple sub-processes for concurrent execution, which then send the results to the main process.
- HappyPack is not friendly to file-loader and URl-loader. Therefore, you are not advised to use this loader.
The usage method is as follows:
- NPM i-D HappyPack
- Module.rules is configured in the webpack.base.conf.js file
module: {
rules: [{test: /\.js$/.use: ['happypack/loader? id=babel'].include: [resolve('src'), resolve('test')].exclude: path.resolve(__dirname, 'node_modules')}, {test: /\.vue$/.use: ['happypack/loader? id=vue']]}}Copy the code
- This configuration is performed in the webpack.prod.conf.js file in the production environment
const HappyPack = require('happypack')
// Create a shared process pool containing 5 child processes
const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })
plugins: [
new HappyPack({
// Use a unique identifier id to indicate that the current HappyPack is used to process a specific class of files
id: 'babel'.// How to handle.js files, which are used in the same way as in Loader configuration
loaders: ['babel-loader? cacheDirectory'].threadPool: HappyPackThreadPool
}),
new HappyPack({
id: 'vue'.// Use a unique identifier id to indicate that the current HappyPack is used to process a specific class of files
loaders: [
{
loader: 'vue-loader'.options: vueLoaderConfig
}
],
threadPool: HappyPackThreadPool
})
]
Copy the code
conclusion
- Practical methods: load on demand, optimize loader configuration, close production environment sourceMap, CDN optimization.
- Vue-cli optimization: code compression, extraction of common code, not much room for further optimization.
- According to the actual needs of the project and their own development level to choose the optimization method, must avoid the optimization of bugs.