Vue发布过程中遇到坑,以及webpack打包优化
前言
- 这段时间,本人自己做了一个vue画面部署到自己的服务器上,发现运行速度慢的的惊人,虽然服务器很渣(本人没什么钱,只能租最差的服务器,主要是给自己学习用的),但是这样开发出来的网站简直不能用,所以就查阅各种资料和网站,一步一步把代码包优化。这篇文章主要是把我调优的过程记录下来。
- 项目的基础框架是通过TypeScript官网取得的。各种基础框架模版
- 项目的构成 vue + ant-design + mysql + TypeScript
- vue项目地址
- 最后,关于如何在vue里面实现按需加载,请自行查阅相关资料。以及,webpack的基础知识本文也不做介绍,可以参照我github的 学习笔记
- [原文地址](http://shenxf.top/2019/05/16/20190516-vueSpeedUp/)
调优过程
- 禁用webpack的devtools
- 打包出来的js文件非常大,每个js文件竟然达到了3~4Mbs,这样的体积对于我的服务带宽来说根本负担不起。打开画面必卡。
- 究其原因,是因为webpack里面启用了sourceMap,以便于调试。但是这在发布以后就完全没有用了。
- webpack配置,里面有这句话,把这句话注释掉。原本3~4Mbs的文件,变成了1Mbs文件。压缩了3倍以上。
// 启用sourceMap
devtool: '#source-map'
- 抽离css样式等
这个虽然对于改善效果不明显,但是好的分类对于发现问题的本质有很大的帮助。另外,css样式分离后要自己进行压缩。
// *************webpack需要引入的包*************************
// 抽离css样式
let MiniCssExtractPlugin = require('mini-css-extract-plugin');
// 用来压缩分离出来的css样式
let OptimizeCss = require('optimize-css-assets-webpack-plugin');
// 用来压缩js
let UglifyJsPlugin = require('uglifyjs-webpack-plugin'); // *************webpack相关配置部分*************************
module.exports = {
optimization: {
// 优化项
minimizer: [
new OptimizeCss(), // 压缩css
new UglifyJsPlugin({ // 压缩js
cache: true, // 是否用缓存
parallel: true, // 并发打包
sourceMap: false, // es6 -> es5 转换时会用到
}),
],
}
// 中间部分省略 // 抽离css样式
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css', // 抽离出来样式的名字
}),
],
}抽离之后,现在项目生成文件的大小是这样。
JS文件的大小
- 启用依赖关系可视化工具
完成上面工作之后,陷入了茫然,网站还是很卡,不知道还能怎么调优,在翻阅了很多网站资料以后,发现了一个依赖关系可视化工具,这对于我来说是一个重大的突破口
// 依赖关系可视化
// *************webpack需要引入的包*************************
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); // *************webpack相关配置部分*************************
module.exports = { // 启动依赖关系可视化窗口,绑定端口8919
plugins: [
new BundleAnalyzerPlugin({ analyzerPort: 8919 }),
],
}重新进行编译以后的效果图
JS文件的依赖关系图通过这个效果图可以很明显的看出js文件里面包含什么依赖,我就是通过这个线索来进行优化的。
- 抽离共通部分
为了方便我调查,我把共通的依赖部分都抽离出来了。而这个功能是webpack4自带的,如果是之前或者更早版本的webpack,需要引入第三方组件
CommonsChunkPlugin这里不做介绍。module.exports = {
optimization: {
//打包 公共文件
splitChunks: {
cacheGroups: {
vendor: {
//node_modules内的依赖库
chunks: 'all',
test: /[\\/](node_modules)[\\/]/, // 文件路径里面带有node_modules 都抽离出来做共通
name: 'vendor',
minChunks: 1, //被不同entry引用次数(import),1次的话没必要提取
maxInitialRequests: 5,
minSize: 0,
priority: 100,
// enforce: true?
},
common: {
// ‘src/js’ 下的js文件
chunks: 'all',
test: /[\\/]src[\\/]js[\\/]/, //也可以值文件/[\\/]src[\\/]js[\\/].*\.js/,
name: 'common', //生成文件名,依据output规则
minChunks: 2,
maxInitialRequests: 5,
minSize: 0,
priority: 1,
},
},
},
runtimeChunk: {
name: 'manifest',
},
}
}一开始我对于这个属性的名字难以理解,以至于没有效果,看了下面的文章后全明白了。
效果图如下
JS文件的依赖关系图2JS文件大小
JS文件大小2
- 分析包大小问题
- 从上面的依赖效果图可以明显的看出,有几个包特别大,特别显眼
- ant-design的Icons文件
- moment文件
- quill文件
- highlight.js文件
- ant-design的Icons文件优化
- 这是ant-design的一个问题
- 而关于上面的问题,我建议你们直接看链接最下面的部分。(上面的一群人聊了半天,不知所以然,各种链接来回跳,也没找到结果)
- 核心的几句话。
JS解决方案
TS解决方案 - 通过了自己的理解,一个要自己引入相应的Icon,另一个是要在webpack里面进行配置
增加antdIcon.ts代码,引入相应的Icon
// 自己项目里面用到的Icon
export {
default as FileOutline,
} from '@ant-design/icons/lib/outline/FileOutline'; // antd的message组建内部用到的Icon 把源代码复制过来。
// var iconType = {
// info: 'info-circle',
// success: 'check-circle',
// error: 'close-circle',
// warning: 'exclamation-circle',
// loading: 'loading'
// }[args.type] // message info
export {
default as InfoCircleTwoTone,
} from '@ant-design/icons/lib/twotone/InfoCircleTwoTone'; // message success
export {
default as CheckCircleTwoTone,
} from '@ant-design/icons/lib/twotone/CheckCircleTwoTone'; // message error
export {
default as CloseCircleTwoTone,
} from '@ant-design/icons/lib/twotone/CloseCircleTwoTone'; // message warning
export {
default as ExclamationCircleTwoTone,
} from '@ant-design/icons/lib/twotone/ExclamationCircleTwoTone'; // message loading
export {
default as LoadingOutline,
} from '@ant-design/icons/lib/outline/LoadingOutline';修改 webpack 配置
module.exports = {
resolve: {
modules: [path.resolve(__dirname, './src'), 'node_modules'], // <- 追加代码
extensions: ['.ts', '.js', '.vue', '.json'], // <- 追加代码
alias: {
vue$: 'vue/dist/vue.esm.js',
'@ant-design/icons/lib/dist$': path.resolve(__dirname, './src/tools/antdIcon.ts'), // <- 追加代码
},
plugins: [ // <- 追加代码
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, './tsconfig.json'),
}),
],
},再一次编译,是不是发现已经看不到Icon了,本来就应该这样,我的项目中根本没用几个Icon
依赖效果图3JS文件的大小,直接减少了500K左右
JS文件大小3
- moment文件优化
- 这是个Ant-design内部依赖的语言文件,我的程序里面本身没有引用,我主要用到的是里面的中文,所以,中文以外的我全部在webpack里面设置忽略就行了
module.exports = {
plugins: [
// 只读取(zh-cn)文件。
new webpack.ContextReplacementPlugin(/moment[\\\/]locale$/, /^\.\/(zh-cn)$/),
],
}
- quill文件优化
这个是我用到的富文本功能,本身对这个组件不太了解,但又必须要用到,也没什么太好优化方法,索性,把它抽离成一个单独的共通JS文件,这样起码有2个组建同时调用这个富文本的情况下,只有第一个掉用的那个需要引入JS文件,第二次的那个会直接利用浏览器的缓存来调用这个JS文件的,也有一定程度的优化效果。
所以我修改了抽离共通组件的那部分代码
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'all',
test: /[\\/](quill)[\\/]/, // <- 就是简单修改了下匹配规则
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: 1,
},
},
},
runtimeChunk: {
name: 'manifest',
},
}
}7和8修改之后的效果
依赖关系效果图47和8修改之后的JS文件大小
JS文件大小4
- highlight.js文件优化
- 这个主要是我用markdown编辑器的时候,用来给文字着色的。没有这个,在编写markdown的时候,内容非常的丑陋。
- 但是这个东西的语法太多了,导致这个包非常的大,我编写的时候,只需要利用其中的几种情况而已,我先随便定几种情况,反正是自己的项目,有不够的以后随时再追加(正式项目的话请做好调研)
-
// 按需加载的写法
import hljs from 'highlight.js/lib/highlight';
import javascript from 'highlight.js/lib/languages/javascript';
hljs.registerLanguage('javascript', javascript); 改完文件以后再看依赖关系
依赖关系效果图5JS文件大小
JS文件大小5至此,我觉得以我现在的水平代码已经没有什么好调整了,main文件还是有点大,我也已经尽力了。
- 服务开启Gzip代码压缩
- 我用的是nginx服务器,它可以开启Gzip,代码压缩率非常可观。200k文件直接被它压缩到几十k。
原本还有点小卡的网站,在启用了Gzip之后,变得一点也不卡了。
修改nginx配置,这里有个小的坑(最后还给我来一个坑),随便找个网站复制下,大致都长下面这样,最后要重启nginx服务,让它读取最新配置
nginx -s reload。如果你用的是docker请输入docker exec -it 容器名字 service nginx reloadgzip on;
gzip_min_length 5k;
gzip_buffers 4 16k;
#gzip_http_version 1.0;
gzip_comp_level 3;
gzip_types text/plain application/x-javascript text/css application/xml text/javascript application/x-httpd-php image/jpeg image/gif image/png;
gzip_vary on;坑在哪里?你自己看吧,说出来都是泪啊坑
Gzip有啥缺点? 我也不太清楚,第一应该是它不支持IE6以及IE6以下的浏览器。还有人说他不利于SEO,但也有人说他利于SEO,是真是假去问百度。网上大部分人觉的他的优点大于缺点。
谢谢大家。
Vue发布过程中遇到坑,以及webpack打包优化的更多相关文章
- Torch-RNN运行过程中的坑 [2](Lua的string sub函数,读取中文失败,乱码?)
0.踩坑背景 仍然是torch-rnn/LanguageModel.lua文件中的一些问题,仍然是这个狗血的LM:encode_string函数: function LM:encode_string( ...
- Torch-RNN运行过程中的坑 [1](读取Lua非空table,size为0)
0.踩坑背景 执行Torch-RNN的时候,在LanguageModel.lua中的encode_string函数中,对start_text的各个character进行id映射编码,实现功能类似“北京 ...
- Torch-RNN运行过程中的坑 [0](一些基础概念)
0.Lua & LuaJIT简介 Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴 ...
- 记一次webpack打包优化
未进行打包优化的痛点: 随着项目的不断扩大,引入的第三方库会越来越多,我们每次build的时候会对所有的文件进行打包,耗时必定很长,不利于日常开发. 解决思路: 第三方库我们只是引入到项目里来,一般不 ...
- Webpack 打包优化之速度篇
在前文 Webpack 打包优化之体积篇中,对如何减小 Webpack 打包体积,做了些探讨:当然,那些法子对于打包速度的提升,也是大有裨益.然而,打包速度之于开发体验和及时构建,相当重要:所以有必要 ...
- Webpack 打包优化之体积篇
谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...
- webpack 创建vue项目过程中遇到的问题和解决方法
目录 1 webpack简介 2 webpack实现多个输入输出多个html 3 webpack 中的module下rules 下的use和loader选项 4 webpack 文件更新,如何使页面 ...
- Vue使用过程中常见问题
目录 一.vue监听不到state数组/json对象内的元素的值的变化,要手动通知触发 二.vue用splice删除多维数组元素导致视图更新失败情况 三.vue项目如何部署到php或者java环境的服 ...
- 菜鸟帮你跳过openstack配置过程中的坑
一:前言 对于一个以前做java全栈工程师而言,而且没学过Linux,很少用虚拟机(还是在大学的时候简单的用过),去配置openstack我想我入的坑肯定比有基础的一定要多,躺在每个坑中徘徊思索的时间 ...
随机推荐
- nuxt https
我用的模板是nxut-express,版本是:1.4.2.服务器:阿里云.一.申请免费证书:网站能通过https访问,首先得申请https证书,付费的阿里云上有售卖的,一年几千块.免费的可以通过cer ...
- Java切换JDK版本的方法及技巧
由于项目的不同安排,之前项目开发时,使用的jdk版本为1.8,现临时接手一以前项目,需要更换jdk版本. 安装 不再赘述,去Oracle网站(https://www.oracle.com/techne ...
- 一文读懂架构师都不知道的isinstance检查机制
起步 通过内建方法 isinstance(object, classinfo) 可以判断一个对象是否是某个类的实例.但你是否想过关于鸭子协议的对象是如何进行判断的呢? 比如 list 类的父类是继 o ...
- 关于while((c=getchar()))的一些应用与思考
最近做题发现一个特别牛逼又特别神奇的读取入字符串的方法 while((c=getchar())!=....) { //do something } 为什么说强大呢,首先这个表达式对空格回车都不怕,他不 ...
- java面试题(转)
1.面向对象的特征有哪些方面?答:面向对象的特征主要有以下几个方面:- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面.抽象只关注对象有哪些属性和行为,并不关注这些 ...
- [加强版] Codeforces 835D Palindromic characteristics (回文自动机、DP)
题目链接: https://codeforces.com/contest/835/problem/D 题意: 一个回文串是\(1\)-回文的,如果一个回文串的左半部分和右半部分一样且都是\(k\)-回 ...
- redis学习五,redis集群搭建及添加主从节点
redis集群 java架构师项目实战,高并发集群分布式,大数据高可用,视频教程 在redis3.0之前,出现了sentinel工具来监控各个Master的状态(可以看上一篇博客).如果Master异 ...
- MSSQL的表备份成INSERT脚本的存储过程
USE [SupplyChain]GO/****** Object: StoredProcedure [dbo].[ExpData] Script Date: 2015-12-18 10:23:08 ...
- Jmeter压测问题_Non HTTP response code: org.apache.http.conn.ConnectTimeoutException
负载机压测,线程500,服务器根本无压力,负载机本身发的请求都是失败的 Sample result如下: Thread Name: 考勤(考勤提交) 1-134 Sample Start: 2018- ...
- 自定义列标题 case when
set@schoolid=41;select l.StartTime,l.EndTime,c.EntranceYear as 入学级,cg.Grade as 年级,c.ClassName as 班级名 ...