preface
I had some Element-UI for the project and had time to think about how to reduce the size and speed of the package file. To demonstrate the experiment, I used vue-CLI to generate the initial project, which was optimized only for the Element-UI theme and components.
vue init webpack vuecli
Copy the code
A complete introduction
Fully introduce UI and styles.
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Copy the code
Simply use 2 components on the page and see what happens.
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="User Management" name="first">User management</el-tab-pane>
<el-tab-pane label="Configuration Management" name="second">Configuration management</el-tab-pane>
<el-tab-pane label="Role Management" name="third">Role management</el-tab-pane>
<el-tab-pane label="Timed task compensation" name="fourth">Timed task compensation</el-tab-pane>
</el-tabs>
<el-steps :active="2" align-center>
<el-step title="Step 1" description="This is a long, long, long descriptive text."></el-step>
<el-step title="Step 2" description="This is a long, long, long descriptive text."></el-step>
<el-step title="Step 3" description="This is a long, long, long descriptive text."></el-step>
<el-step title="4" description="This is a long, long, long descriptive text."></el-step
></el-steps>
Copy the code
Take a look at the size of the packaged resource NPM run build –report.
Hash: 40db03677fe41f7369f6
Version: webpack 3.12. 0
Time: 20874ms
Asset Size Chunks Chunk Names
static/css/app.cb8131545d15085cee647fe45f1d5561.css 234 kB 1 [emitted] app
static/fonts/element-icons.732389d.ttf 56 kB [emitted]
static/js/vendor.a753ce0919c8d42e4488.js 824 kB 0 [emitted] [big] vendor
static/js/app.8c4c97edfce9c9069ea3.js 3.56 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest
static/fonts/element-icons.535877f.woff 28.2 kB [emitted]
static/css/app.cb8131545d15085cee647fe45f1d5561.css.map 332 kB [emitted]
static/js/vendor.a753ce0919c8d42e4488.js.map 3.26 MB 0 [emitted] vendor
static/js/app.8c4c97edfce9c9069ea3.js.map 16.6 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [emitted] manifest
index.html 506 bytes [emitted]
Copy the code
The public module static/js/vendor.js was found to be 824KB after being packed
Take a look at the occupation of each module:
It found the largest occupation of Elcalculator ui.common.js. All module resources are 642KB in total. How can I reduce the size of the package? It’s easy to think that with the UI and style introduction, we only use three components, but the whole thing is packaged, and we can just introduce those three components here.
Introduce component styles as needed
Create a new element-variable. SCSS file.
/*icon font path variable */
$--font-path: "~element-ui/lib/theme-chalk/fonts";
/* Import as needed the SCSS files and base SCSS files of the used components */
@import "~element-ui/packages/theme-chalk/src/base.scss";
@import "~element-ui/packages/theme-chalk/src/rate.scss";
@import "~element-ui/packages/theme-chalk/src/button.scss";
@import "~element-ui/packages/theme-chalk/src/row.scss";
Copy the code
Import components as needed
Create a new element-config.js file to introduce the Element components used for the project.
import { Tabs, TabPane, Steps, Step } from 'element-ui'
export default {
install(V) {
V.use(Tabs)
V.use(TabPane)
V.use(Steps)
V.use(Step)
}
}
Copy the code
Package analysis after the first optimization
Add the above element-variable. SCSS and element-config.js to main.js.
import ElementUI from '@/assets/js/element-config'
import '@/assets/css/element-variables.scss'
Vue.use(ElementUI)
Copy the code
It seems that everything above is logical, the size will be reduced when packed.
Hash: 2ef987c23a5d612e00e1
Version: webpack 3.12. 0
Time: 17430ms
Asset Size Chunks Chunk Names
static/css/app.3c70d8d75c176393318b232a345e3f0f.css 38.8 kB 1 [emitted] app
static/fonts/element-icons.732389d.ttf 56 kB [emitted]
static/js/vendor.caa5978bb1eb0a15b097.js 824 kB 0 [emitted] [big] vendor
static/js/app.5ebb19489355acc3167b.js 3.64 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest
static/fonts/element-icons.535877f.woff 28.2 kB [emitted]
static/css/app.3c70d8d75c176393318b232a345e3f0f.css.map 53.9 kB [emitted]
static/js/vendor.caa5978bb1eb0a15b097.js.map 3.26 MB 0 [emitted] vendor
static/js/app.5ebb19489355acc3167b.js.map 17 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [emitted] manifest
index.html 506 bytes [emitted]
Copy the code
Static /js/vendor.js is 824KB!
Take a look at the occupation of each module:
WHAT? Even modules are not changed, is not a basket of water, backfire.
Try packaging optimization again
Issues# 6362. Originally, it only introduced the required element-ui component, but webpack still packaged the whole UI library and style. A webPack Babel plug-in, babel-plugin-Component, is needed to truly introduce packaging on demand. This is actually written to the official document to change the configuration of the custom theme.
So NPM I babel-pugin- Componet -d after installation, in addition to the.babelrc file plug-in configuration
{
"presets": [["env", {
"modules": false."targets": {
"browsers": ["1%" >."last 2 versions"."not ie <= 8"]}}],"stage-2"]."plugins": [
"transform-vue-jsx"."transform-runtime"["component",
{
"libraryName": "element-ui"."styleLibraryName": "theme-chalk"}}]]Copy the code
The page is working fine and is packaged again.
Hash: f182f70cb4ceee63b5d5
Version: webpack 3.12. 0
Time: 10912ms
Asset Size Chunks Chunk Names
static/css/app.95c94c90ab11fdd4dfb413718f444d0c.css 39.9 kB 1 [emitted] app
static/fonts/element-icons.732389d.ttf 56 kB [emitted]
static/js/vendor.befb0a8962f74af4b7e2.js 157 kB 0 [emitted] vendor
static/js/app.5343843cc20a78e80469.js 3.86 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest
static/fonts/element-icons.535877f.woff 28.2 kB [emitted]
static/css/app.95c94c90ab11fdd4dfb413718f444d0c.css.map 93.5 kB [emitted]
static/js/vendor.befb0a8962f74af4b7e2.js.map 776 kB 0 [emitted] vendor
static/js/app.5343843cc20a78e80469.js.map 17.1 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [emitted] manifest
index.html 506 bytes [emitted]
Copy the code
Static /js/vendor.js is indeed smaller, 157kB. Let’s look at the analysis diagram of each module.
The modules total 157.93KB, 5 times less!
Change the theme – overlay style
The element-UI theme-chalk is written using SCSS. If you use SCSS in your own project, you can change the style variable directly within the project. The new element-variable. SCSS file can therefore be overwritten with the new theme color variable.
/** * overwrites the theme color */
/* Theme color variable */
$--color-primary: #f0f;
/*icon font path variable */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
/* Introducing all default styles introduces unused component styles */
// @import '~element-ui/packages/theme-chalk/src/index';
/* Import as needed the SCSS files and base SCSS files of the used components */
@import '~element-ui/packages/theme-chalk/src/base.scss';
@import '~element-ui/packages/theme-chalk/src/rate.scss';
@import '~element-ui/packages/theme-chalk/src/button.scss';
@import '~element-ui/packages/theme-chalk/src/row.scss';
Copy the code
Now our theme becomes the desired effect
As you may have noticed, it is recommended to introduce the component styles used separately, rather than all the default styles, as this would result in the introduction of unused component styles. For example, we do not use the ColorPicker component in the current case, and the component style does exist in the packaged output CSS file.
Change theme – Pure style
Through the above optimization, you can package the used components as needed, eliminate the unused components, and reduce the package size. However, there is a minor flaw: a used component style is packaged twice, once for the default style and once for the overridden style.
The problem arises because we introduce styles in two places. One is to introduce the element-UI component and its default style on demand in the.babelrc file via the babel-plugin-Component plug-in. One is to override custom styles generated by default styles in the element-variable. SCSS file.
So how do you combine the two, the babel-plugin-Component plug-in that introduces component styles on demand with user-defined styles, to achieve the goal of pure styling? Use the Element-UI theme tool for deeper theme customization.
Theme and theme tool installation
First install the theme tool, element-theme, either globally or in the project directory. It is recommended to install the clone project in the item directory, so that others can directly install dependencies and start the project.
npm i element-theme -D
Copy the code
Then install the Chalk theme, either from NPM or by pulling the latest code from GitHub.
#From the NPM
npm i element-theme-chalk -D
#out
npm i https://github.com/ElementUI/theme-chalk -D
Copy the code
Subject to build
Element-theme supports Node APIS and CLI builds.
Using the CLI
If the global installation can call the tool from the command line through et, if the installation is in the current directory, you need to access the command through node_modules/.bin/et. Execute -i (–init) to initialize the variable file. The default output is to elemental-variable. SCSS, although you can specify the file output directory by passing the parameter. If you want to enable watch mode, compile themes in real time, add the -w (–watch) parameter; If you specify a custom variable file at initialization, add the -c (–config) parameter and include your variable file name. By default, the compiled theme directory is placed under./theme. You can specify the packing directory with the -o (–out) argument.
#Initialize the variable file
et --init [file path]
#Real-time compilation
et --watch [--config variable file path] [--out theme path]
#compile
et [--config variable file path] [--out theme path] [--minimize]
Copy the code
Build through the Node API
Introduce an element-theme built through the Node API
var et = require('element-theme')
// Real-time compilation mode
et.watch({
config: 'variables/path'.out: 'output/path'
})
/ / compile
et.run({
config: 'variables/path'.// The configuration parameter file path defaults to './ element-variable.css '
out: 'output/path'.// The output directory defaults to './theme '
minimize: false.// Compress the file
browsers: ['ie > 9'.'last 2 versions'].// Browser support
components: ['button'.'input'] // Select the component to build a custom theme
})
Copy the code
Use the Node API to build custom themes
Here, to make theme construction more intuitive and shared by the project, use the Node API to build, and create a new theme.js file in the project root directory.
const et = require('element-theme')
// The first step is to generate the style variable file
// et.init('./src/theme.scss')
// Step 2 Modify the file as required
// ...
// The third step is to compile a custom theme style file from the variable file
et.run({
config: './src/theme.scss'.out: './src/theme'
})
Copy the code
Add the scripts directive to package.json
{
"scripts": {
"theme": "node theme.js"}}Copy the code
This allows you to compile the theme with the NPM run theme directive. Compilation process:
- Run this instruction to initialize the topic variable file
theme.scss
. - Modify the theme styles in this file as needed.
- Then run the command to compile the output custom theme style file put in
theme
Directory.
This completes the construction of all custom theme styles. To introduce these custom styles as needed along with the component, The babel-plugin-component parameter styleLibraryName needs to be imported as needed from the.babelrc file from the original elder-ui default style directory to the custom ~ SRC /theme directory.
"plugins": [
"transform-vue-jsx"."transform-runtime"["component",
{
"libraryName": "element-ui"."styleLibraryName": "~src/theme"}]]Copy the code
When everything is ready, the project is packaged, and the CSS file is packed with only custom styles. There are no default styles and no styles that have not been introduced into the component, so we have the pure custom styles we expected!
Hash: c442bcf9d471bddfdccf
Version: webpack 3.12. 0
Time: 10174ms
Asset Size Chunks Chunk Names
static/css/app.52d411d0c1b344066ec1f456355aa7b9.css 38.8 kB 1 [emitted] app
static/fonts/element-icons.535877f.woff 28.2 kB [emitted]
static/js/vendor.befb0a8962f74af4b7e2.js 157 kB 0 [emitted] vendor
static/js/app.43c09c1f16b24d371e07.js 3.82 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js 857 bytes 2 [emitted] manifest
static/fonts/element-icons.732389d.ttf 56 kB [emitted]
static/css/app.52d411d0c1b344066ec1f456355aa7b9.css.map 81.3 kB [emitted]
static/js/vendor.befb0a8962f74af4b7e2.js.map 776 kB 0 [emitted] vendor
static/js/app.43c09c1f16b24d371e07.js.map 17.1 kB 1 [emitted] app
static/js/manifest.2ae2e69a05c33dfc65f8.js.map 4.97 kB 2 [emitted] manifest
index.html 506 bytes [emitted]
Copy the code
Since the style is pure, the CSS file size is 38.8KB instead of 234KB, which was fully introduced, further reducing the package size.
conclusion
Based on the above experimental analysis, we can see that in order for Element-UI to achieve on-demand and pure theme style:
- First of all by
babel-plugin-component
Plug-ins are imported on demand. - Then use
element-theme
The tool generates sample variable files. - The custom styles are then modified according to the project requirements, and all styles are generated from this file build.
- Finally, styles will be introduced as needed
styleLibraryName
Point to the custom styles directory.
If the style extraction requirements are not high, you can directly take the form of variable override (with the default style). Still not clear can poke here to view the case source code, give person star, hand has lingering fragrance.
End ~ PS: My opinion is limited, welcome correction.