It recorded the optimization practice of my blog from 8 and 9 seconds loading time to 985ms with caching disabled, and 138ms access speed with caching enabled. The preview address is www.cooldream.fun
My personal blog usesVue-cli4.1.2 + typescript
build
The project directory structure is as follows
├ ─ SRC / / master file │ ├ ─ API/interface/folder | | | - config. Js / / backend interface address configuration, separate test, development, production | | └ ─ user. Js / / interface file, configure the token request header, Specific interface according to the demand change │ ├ ─ assets / / resource file │ ├ ─ components / / utility components │ ├ ─ directive / / vue custom command | ├ ─ filters/store/filter file, with his hand immediately encryption, mobile phone number formatting, Time date processing | ├ ─ interceptors / / deposit axios interceptor configuration, written into the interface call load and loading HTTP status code error intercept | ├ ─ interceptors / / place public interfaces, To limit the types of data | ├ ─ layout / / file layout, implementation, zi lu by rendering specific HTML layout according to the demand change | ├ ─ mixins / / mixed with files, configured with a method of smooth scrolling | ├ ─ plugins / / external plugins folder, Configured with on-demand element - the introduction of the UI | ├ ─ reg / / deposit regular and check folder | | | - reg. Ts / / deposit regular expression, bringing the fax, E-mail, qq, phone number, bank card number, fixed telephone, Password strength check regular | | └ ─ the validator. Ts / / storage element - the UI custom check, bringing the fax, E-mail, qq, phone number, bank card number, fixed telephone, Password strength custom check | ├ ─ the router / / routing file | ├ ─ store / / vuex global variable file | | | - index. Ts / / store master file | | └ ─ the module/store/modules folder | | | └ ─ User. The store ts / / the user related global variable | ├ ─ stylus / / CSS preprocessor folder | | | - reset. Styl / / style initialization file, bring the non-standard box, a label to remove the underline, inner and outer margin, Banned images such as drag effect | | └ ─ color. Styl / / color variable file | ├ ─ utils / / public methods folder | | | - area. Ts / / store three provinces, a regional data | | | - array. Ts / / storage array related public methods, Swap places, comes with two elements move back one, element placed at the top or at the end, to heavy, delete the specified element operation | | └ ─ object. The ts / / stored objects related public methods, Bring the object to empty all values way | ├ ─ page views / / folder | ├ ─ main. Ts / / the main configuration file | ├ ─ Babel. Config. Js / / Babel configuration file, Written into the element - UI on-demand loaded configuration | ├ ─ package. The json / / NPM package management file | ├ ─ tsconfig. Json / / ts configuration file | ├ ─ vue. Config. Js / / vue configuration fileCopy the code
1. Close the productionSourceMap
First, thanks to the latest version of scaffoldingNo built-in configuration file
Let’s create a new one in the root directoryvue.config.js
File, closeproductionSourceMap
In thevue.config.js
Is displayed with the following content
module.exports = {
productionSourceMap: false
}
Copy the code
2. Enable Gzip compression
Installing a plug-incompression-webpack-plugin
, open code compression,npm install --save-dev compression-webpack-plugin
And now thevue.config.js
The code is as follows, but it is important to note that gzip must also be enabled on nginx on the server to take effect
// Whether the environment is production
constisProduction = process.env.NODE_ENV ! = ='development';
/ / gzip compression
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
productionSourceMap: false.configureWebpack: config= > {
// Configure the production environment
if (isProduction) {
/ / gzip compression
const productionGzipExtensions = ['html'.'js'.'css']
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]'.algorithm: 'gzip'.test: new RegExp(
'\ \. (' + productionGzipExtensions.join('|') + '$'
),
threshold: 10240.// Only resources larger than this value will be processed
minRatio: 0.8.// Only resources whose compression ratio is less than this value will be processed
deleteOriginalAssets: false // Delete the original file}))}}Copy the code
Open thenginx
Under foldernginx.conf
File,http
Module to write the following
Gzip on; Gzip_min_length: gzip_min_length: 1k; gzip_min_length: 1k; # gzip compression level,1-9The larger the number, the better the compression, and the more CPU time it takes. More on this later2; # Type of file to compress. Javascript comes in many forms, Gzip_types text/plain application/javascript application/ X-javascript text/ CSS application/ XML text/javascript application/x-httpd-php image/jpeg image/gif image/png; # Add Vary: accept-encoding to the HTTP header. It is recommended to enable gzip_vary on. Set gzip_buffers as required for compression4 16k;
Copy the code
And then you type in the commandnginx -s reload
Restart the Nginx service
If the back-end NGINx has gzip enabled, you can start fromnetwork
In theContent-Encoding
seegzip
3. Enable CDN acceleration (optional, although CDN is fast, it is less stable than local packaging)
The plug-in to be used is linked using CDN and configuredwebpack
Will use theCDN
Plugins are not packaged, and don’t forget to repackageindex.html
The introduction ofjs
As well ascss
// Whether the environment is production
constisProduction = process.env.NODE_ENV ! = ='development';
// Whether to use the CDN in the local environment
const devNeedCdn = false
/ / the CDN links
const cdn = {
// CDN: module name and module scope name (corresponding to the variable name mounted in window)
externals: {
vue: 'Vue'.vuex: 'Vuex'.'vue-router': 'VueRouter'.'marked': 'marked'.'highlight.js': 'hljs'.'nprogress': 'NProgress'.'axios': 'axios'
},
// CDN CSS link
css: [
'https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css'].// CDN js link
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.min.js'.'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js'.'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js'.'https://cdn.bootcss.com/marked/0.8.0/marked.min.js'.'https://cdn.bootcss.com/highlight.js/9.18.1/highlight.min.js'.'https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js'.'https://cdn.bootcss.com/axios/0.19.2/axios.min.js']}module.exports = {
chainWebpack: config= > {
// ============ To inject CDN start============
config.plugin('html').tap(args= > {
// Inject the CDN only when the production environment or local environment requires the CDN
if (isProduction || devNeedCdn) args[0].cdn = cdn
return args
})
// ============ To inject CDN start============
},
configureWebpack: config= > {
// If CDN is used, the related resources should be ignored during construction
if (isProduction || devNeedCdn) config.externals = cdn.externals
}
}
Copy the code
Next, in theindex.html
Is introduced into theCDN
A link to the
<! DOCTYPEhtml>
<html lang="en" style="width: 100%; height: 100%;">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="Width = device - width, initial - scale = 1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<! -- use CDN CSS file -->
<% for (var i in htmlWebpackPlugin.options.cdn &&
htmlWebpackPlugin.options.cdn.css) { %>
<link
href="<%= htmlWebpackPlugin.options.cdn.css[i] %>"
rel="stylesheet"
/>The < %} % ><! -- use CDN CSS file -->
<title>CoolDream</title>
</head>
<body style="width: 100%; height: 100%;">
<noscript>
<strong>We're sorry but blog doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<! -- built files will be auto injected -->
<! -- use CDN JS file -->
<% for (var i in htmlWebpackPlugin.options.cdn &&
htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>The < %} % ><! -- use CDN JS file -->
</body>
</html>
Copy the code
Package and throw to the server, open developer tools network, if you seehttp
requestcdn
, the configuration is successful, as shown in the figure
4. Code compression
Install the plug-in firstnpm i -D uglifyjs-webpack-plugin
And then you introduce dependencies at the top
// Code compression
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
Copy the code
inconfigureWebpack
Code compression is introduced in the module
// Code compression
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
// The production environment automatically deletes the console
compress: {
drop_debugger: true.drop_console: true.pure_funcs: ['console.log']}},sourceMap: false.parallel: true}))Copy the code
5. Remove the common code and write it inconfigureWebpack
In the module
// Public code extraction
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all'.test: /node_modules/,
name: 'vendor'.minChunks: 1.maxInitialRequests: 5.minSize: 0.priority: 100
},
common: {
chunks: 'all'.test: /[\\/]src[\\/]js[\\/]/,
name: 'common'.minChunks: 2.maxInitialRequests: 5.minSize: 0.priority: 60
},
styles: {
name: 'styles'.test: /\.(sa|sc|c)ss$/,
chunks: 'all'.enforce: true
},
runtimeChunk: {
name: 'manifest'}}}}Copy the code
6. Image compression ()
1. Use the image compression plugin
-
Install the plug-in first
npm install image-webpack-loader --save-dev
-
in
chainWebpack
Add the following code in the
// ============ Compressed picture start============
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({ bypassOnDebug: true })
.end()
// ============ Compressed image end============
Copy the code
2. Store static resources in the cloud, personal Qiniu Cloud, object storage for file storage, usecdn
Acceleration makes the static resource access to the storage faster.(Recommended, the speed can be much faster)
-
I personally applied for Qiniuyun, the real name authentication has 10G space available, there is 10G of free traffic every month, but not bound to the domain name only 30 days of experience opportunity, I am bound to my domain name for DNS resolution transfer, the specific operation can refer to this blog.www.cnblogs.com/mazhichu/p/…
7. First screen skeleton screen optimization (optional, depending on their actual needs)
1. Install the plug-in
npm install vue-skeleton-webpack-plugin --save
Copy the code
2. Create a skeleton screen file
Create a Skeleton folder under SRC, create index.js and index.vue, and write the following contents in it. The index.vue page style of the Skeleton screen should be edited by yourself
//index.js
import Vue from 'vue'
// Create skeleton screen Vue instance
import skeleton from './index.vue';
export default new Vue({
components: {
skeleton
},
template: '<skeleton />'
});
Copy the code
//index.vue
<template>
<div class="skeleton-box">
loading
</div>
</template>
<script lang="ts">
import {Vue,Component} from "vue-property-decorator";
@Component({
name:'Skeleton'
})
export default class Skeleton extends Vue{}</script>
<style lang="stylus" scoped>
.skeleton-box{
font-size 24px
display flex
align-items center
justify-content center
width 100vh
height 100vh
}
</style>
Copy the code
In 3.vue.config.js
To configure the skeleton screen
Write the following to vue.config.js
// Skeleton screen rendering
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
/ / path
const path = require('path')
// Write to the configureWebpack module
// Skeleton screen rendering
config.plugins.push(
new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: path.join(__dirname,'./src/components/Skeleton/index.js')}}}))Copy the code
8. Close the preloaded module
Vue-cli enables prefetch (preloaded module) by default to obtain content that users may access in the future
If you just want to render the first screen as quickly as possible, regardless of the speed of subsequent pages, you can remove this module
config.plugins.delete('prefetch')
Copy the code
So, the final configuration file is as follows (close the pre-loaded module has been commented and can be unsealed if needed)
// Whether the environment is production
constisProduction = process.env.NODE_ENV ! = ='development';
// Code compression
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
/ / gzip compression
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// Skeleton screen rendering
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin')
/ / path
const path = require('path')
// Whether to use the CDN in the local environment
const devNeedCdn = false
/ / the CDN links
const cdn = {
// CDN: module name and module scope name (corresponding to the variable name mounted in window)
externals: {
vue: 'Vue'.vuex: 'Vuex'.'vue-router': 'VueRouter'.'marked': 'marked'.'highlight.js': 'hljs'.'nprogress': 'NProgress'.'axios': 'axios'
},
// CDN CSS link
css: [
'https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.css'].// CDN js link
js: [
'https://cdn.bootcss.com/vue/2.6.10/vue.min.js'.'https://cdn.bootcss.com/vuex/3.1.2/vuex.min.js'.'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js'.'https://cdn.bootcss.com/marked/0.8.0/marked.min.js'.'https://cdn.bootcss.com/highlight.js/9.18.1/highlight.min.js'.'https://cdn.bootcss.com/nprogress/0.2.0/nprogress.min.js'.'https://cdn.bootcss.com/axios/0.19.2/axios.min.js']}module.exports = {
productionSourceMap: false.chainWebpack: config= > {
// ============ Preloading the module closes ============
// config.plugins.delete('prefetch')
// ============ Preloading the module closes ============
// ============ To inject CDN start============
config.plugin('html').tap(args= > {
// Inject the CDN only when the production environment or local environment requires the CDN
if (isProduction || devNeedCdn) args[0].cdn = cdn
return args
})
// ============ To inject CDN start============
// ============ Compressed picture start============
config.module
.rule('images')
.use('image-webpack-loader')
.loader('image-webpack-loader')
.options({ bypassOnDebug: true })
.end()
// ============ Compressed image end============
},
configureWebpack: config= > {
// If CDN is used, the related resources should be ignored during construction
if (isProduction || devNeedCdn) config.externals = cdn.externals
// Configure the production environment
if (isProduction) {
/ / gzip compression
const productionGzipExtensions = ['html'.'js'.'css']
config.plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]'.algorithm: 'gzip'.test: new RegExp(
'\ \. (' + productionGzipExtensions.join('|') + '$'
),
threshold: 10240.// Only resources larger than this value will be processed
minRatio: 0.8.// Only resources whose compression ratio is less than this value will be processed
deleteOriginalAssets: false // Delete the original file}))// Code compression
config.plugins.push(
new UglifyJsPlugin({
uglifyOptions: {
// The production environment automatically deletes the console
compress: {
drop_debugger: true.drop_console: true.pure_funcs: ['console.log']}},sourceMap: false.parallel: true}}))// Skeleton screen rendering
config.plugins.push(
new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: path.join(__dirname,'./src/components/Skeleton/index.js')}}}))// Public code extraction
config.optimization = {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all'.test: /node_modules/,
name: 'vendor'.minChunks: 1.maxInitialRequests: 5.minSize: 0.priority: 100
},
common: {
chunks: 'all'.test: /[\\/]src[\\/]js[\\/]/,
name: 'common'.minChunks: 2.maxInitialRequests: 5.minSize: 0.priority: 60
},
styles: {
name: 'styles'.test: /\.(sa|sc|c)ss$/,
chunks: 'all'.enforce: true
},
runtimeChunk: {
name: 'manifest'
}
}
}
}
}
}
Copy the code
8. Configure cache on nginx
It can also increase the speed of the site (although this is a bit of a departure from the front end packaging theme, it is still very useful for developing the front end of your own personal blog site!) Write the following to the HTTP module of nginx.conf
Set the cache path and use a maximum of 100 MB of shared memory for the file index on the disk, including the file name and the number of requests per file1If inactive (no request) within days, it will be eliminated from the hard disk, the maximum hard disk cache is 10G, when full, it will be automatically cleared according to the LRU algorithm. proxy_cache_path /var/cache/nginx/cache levels=1:2 keys_zone=imgcache:100m inactive=1d max_size=10g;
Copy the code
Then write to the serve module of nginx.conf to save the configuration.nginx -s reload
Restart the service to see the effect
location ~* ^.+\.(css|js|ico|gif|jpg|jpeg|png)$ { log_not_found off; Access_log off; # Cache time7Day 7 d expires; # source server proxy_pass HTTP://localhost:8888;Proxy_cache imgcache; # Cache expiration management proxy_cache_valid200 302 1d;
proxy_cache_valid 404 10m;
proxy_cache_valid any 1h;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
}
Copy the code