4000字长文,多图预警!!!流量慎入!!javascript
你们好我又来了,本章给你们带来的内容是:上线和上线后的性能优化css
咱们一般在本地开发,本地环境和线上也并不是彻底同样,不少项目第一次上线几乎都会遇到本地开发没法复现的问题,多是字体、样式的问题,也多是webpack 编译的问题、甚至多是本地的奇葩环境。因此 本地完美运行 ≠ 线上完美运行,咱们须要 build 项目,模拟线上测试一下,看看是否能够完美运行,有问题能够方便及时做出调整。html
为了不本教程污染你们本地环境,推荐你们安装一个docker,后期运维也会根据 docker 展开。前端
看到这个 Title :《准备docker》,没接触过的前端不要怂,装一个,敢于跨出第一步,不学习就是等死「点击这里了解 docker」vue
虽然 tomcat nginx apache jboss jetty
等等等等均可以做为 http 服务,本章以最多见的 nginx 展开讲述:java
docker 就是用更优雅的方法,作到了虚拟机的事情,而且作的更好,可编程管理集群。docker 启动容器,在容器内部运行你的环境,默认各个容器是互相隔离的,固然你能够经过 link network 关联容器,或者直接使用 docker-compose 编排,启动容器的前提是镜像,也相似与虚拟机的镜像,想跑容器,先得下载「pull」镜像。node
也许不少人没用过,没用过也不讲怎么安装了,本身去看官网吧中文官网、社区版下载、中国镜像加速,windows 的话可能要开启虚拟化,linux 推荐 ubuntu, 有篇文章这样讲:为了性能请不要在 centos中运行 Docker , 查看翻译点这里,几年前的文章了,如今怎么样有待考究。linux
docker images
复制代码
能够看到我已经有一些镜像了「我已经删除了nginx」webpack
docker pull registry.docker-cn.com/library/nginx:latest
复制代码
正常 docker pull nginx 便可,中间那段是中国镜像源nginx
ok,咱们成功 pull 下来了 Nginx 的镜像。默认存储的镜像名为: registry.docker-cn.com/library/nginx
进入咱们上一章源码的目录,build 一下进行发布。 上一章源码在这里
npm run build
复制代码
docker run --name nginx -d -p 8888:80 -v /new-bee/dist:/usr/share/nginx/html registry.docker-cn.com/library/nginx
复制代码
CMD | 解释 |
---|---|
-d | 守护进程运行 |
-p | 端口映射 8888 :80 docker80端口映射到本机「宿主机」 |
-v | 挂载宿主机的一个目录 本机「宿主机」: docker容器 |
—name | 为容器命名 |
http://localhost:8888/#/
复制代码
固然初次尝试 docker 你可能会有更多的疑问:
这些小白问题本章简单讲讲,后面作自动运维的时候单独展开讲,能够关注个人博客
咱们能够经过 webpack 压缩脚本文件,上传到 http 服务器,浏览器浏览的时候,通过压缩的HTTP应答报文是由浏览器解压的,比起压缩,解压的速度是很是快的(只要数据正常,能够解压的话),因此不用担忧浏览器用于解压的时间会下降用户体验。事实上,浏览器解压消耗的这点时间比起数据包由于网络拥堵而耽误的时间要少的多也可控的多。
在浏览器发给服务器的HTTP请求报文中,使用Accept-Encoding字段标明本身支持的压缩格式,即本身能够解压哪几种压缩报文(gzip、zlib库提供的deflate)。服务器回复客户端的HTTP应答报文中,使用Content-Encoding字段标明该应答报文使用哪一种压缩方式。
像我这样屌丝的服务器通常都买 1M 的,大的资源文件 hold 不住,一个动辄 400K 的 vendar 文件这很蛋疼,不上 gZIp 很难受。
打开 network 观察一下:
它有 144K 这么大
咱们就以 webpack 打包的核心 vendor 为例,咱们发现,客户端向服务端请求了 gZIp 资源 Accept-Encoding: gzip, deflate
,但惋惜服务端并无给咱们理想中的 response - Content-Encoding: gzip
的响应, 咱们须要排查一下缘由。
很遗憾没有,只有一些压缩文件和用于定位的 map 文件,看来首先咱们的打包就出现了问题。
你们还记得当初构建项目我发的这张图吗?
打开看看 build 命令执行了哪一个脚本?
打开 build.js 看看执行了哪些内容,难道是 vue-cli 没有为咱们配置好webpack gZip 相关的配置吗?
咱们发现没什么特别的,发现一个 const webpackConfig = require('./webpack.prod.conf')
的依赖,大概就是字面意思(webpack生产配置)进去看看。
哦,咱们看到了,webpack 确实为咱们配置了 gZip 相关配置。
但是发现这个配置被这个判断包裹住了:
if (config.build.productionGzip) {
}
复制代码
追踪下去
// Gzip off by default as many popular static hosts such as
// Surge or Netlify already gzip all static assets for you.
// Before setting to `true`, make sure to:
// npm install --save-dev compression-webpack-plugin
productionGzip: false,
复制代码
咱们的所有疑惑都被揭开了,开发者经过注释这样告诉咱们他的理由,我简单翻译一下:
首先下载一下依赖:
vim package.json
"devDependencies": {
"compression-webpack-plugin": "^1.1.12",
}
复制代码
而后 productionGzip 改为 true
npm run build
复制代码
成功了,出现了 .zg 文件压缩包,可是 gZip 是须要服务端的支持的,服务器经过客户端请求的 Accept-Encoding
首部开判断返回哪一种格式的脚本文件,而后由浏览器解压,咱们拉下来的 nginx 镜像,nginx 是不会为咱们默认配置 gZIp 服务端压缩的,咱们去查看一下吧。
docker exec -it nginx /bin/bash
复制代码
或者
docker exec -it nginx "bash"
复制代码
CMD | 解释 |
---|---|
exec | 进入docker容器 |
-i | -i: 以交互模式运行容器,一般与 -t 同时使用; |
-t | -t: 为容器从新分配一个伪输入终端,一般与 -i 同时使用; |
-it | -it = -i -t |
“bash” 或 /bin/bash | /bin/bash的做用是由于docker后台必须运行一个进程,不然容器就会退出 |
Linux whereis 命令用于查找文件。
该指令会在特定目录中查找符合条件的文件。这些文件应属于原始代码、二进制文件,或是帮助文件。
该指令只能用于查找二进制文件、源代码文件和man手册页,通常文件的定位需使用 locate 命令。
语法
whereis [-bfmsu][-B <目录>...][-M <目录>...][-S <目录>...][文件...]
复制代码
root@e0017cab245f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
复制代码
ps 中间件这么多,谁记得住呢,记不住本身看看就好了不是吗?
确实 gZip 真的没开启,被注掉了。
咱们打开 gZip 的注释,而且防止服务端对 css 偷懒,咱们一步到位加上几行经典配置。
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 6;
gzip_types application/javascript text/plain application/x-javascript text/css application/xml text/javascript application/json;
gzip_vary on;
复制代码
nginx配置 代码在这里
就目前来看,你有两种方法能够选择:
咱们基于第二点在 new-bee/ 目录 同级 建立了一个目录 nginx/ 建立一个同名的 nginx.conf 文件。
nginx配置 代码在这里
docker stop nginx
复制代码
docker rm nginx
复制代码
docker run --name nginx -d -p 8888:80 -v /new-bee/dist:/usr/share/nginx/html -v /nginx/nginx.conf:/etc/nginx/nginx.conf:ro registry.docker-cn.com/library/nginx
复制代码
http://localhost:8888/#/
复制代码
为了不浏览器加载刚才的 304 缓存,清除下浏览器缓存或进行隐身模式
已经奏效了。
只有 50K 左右,压缩了 2/3 的大小,这对于大型项目来讲,节省的不仅是 100K ,甚至是更多,webpack 或者说 gz 等压缩算法,会将全部的大量重复的片断单独标记,因此重复的越多,压缩的越多,这对于如今带宽比金子贵的云服务来讲是十分重要的。
你们注意到,有些能用 CDN 的我选择使用了 CDN,那么 CDN 对于线上服务来讲到底有多重要呢?
废话先不说给你们上个对比图 测试地址
能够看到仅有几个地方还算不错,其他地方都是一塌糊涂
不用说了吧?不过还好,这部分咱们资金不足败了也很正常,但你们可能也大概知道 CDN 的意义了,主要意义不是节省开源项目服务器带宽,而是全国各个节点的访问速度问题,也就解释了:我部署的项目访问速度还不错,你这里怎么这么慢,你网很差吧?CDN 来告诉你答案。
咱们仍是拿实战的 bbs论坛 举例子吧,查看网络状态:
使用 CDN 的几点优点
客户端的 cookie 是绑定服务端 域名 的, 看上图,咱们须要 XHR 请求携带 cookie 访问服务端获取对应权限,但试想一下:每个 js、img、甚至是css 都携带垃圾的 cookie ,在大用户量下,服务端承受着不该该属于他的痛苦,这样的消耗是特别应该避免的,咱们能够随便翻一翻任何一个成熟的网站,都会发现存在本身的 CDN 服务,这样既优化了中国不一样地区的访问速度,同时也大大减少了服务端的开销。
很长时间前经历过公司前端 webpack 编译特别慢的问题,dev 模式下咱们能够注掉开发范围外的 路由,可是 build 发布的时候彷佛无法解决,使用了 Happypack 多线程打包仍是不如人意,查阅资料读到了 这篇文章
咱们能够把可以 externals 调的排除掉,而后使用 webpack 的 webpack.DllPlugin 生成依赖库(这点很重要),大大减小便以速度,DllPlugin 本质上的作法和咱们手动分离这些第三方库是同样的,可是对于包极多的应用来讲,自动化明显加快了生产效率。
其实不少人都知道,可能刚入坑的同窗不太了解,无论是 npm maven 都有本身一套以来分析工具,固然也都来源于第三方,这里为你们介绍 npm 的以来分析工具: webpack-bundle-analyzer ,他会在浏览器生成一个报表,直观的展现哪里大,哪里须要优化,以及预测 gZip 的大小,仍是以 实战项目为例:
按照官方指引的配置,下载依赖,package.json 文件指定下 build 的脚本:
"analyz": "NODE_ENV=production npm_config_report=true npm run buildProd",
复制代码
运行一下:
npm run analyz
复制代码
效果:
分析:
发现了问题,static/
静态文件下 hightlight 文件比较大,有钱能够考虑下 CDN,node_modules/
下 element-ui 饿了么组件比较大,(我比较懒,全局导入的,能够用哪一个引入哪一个避免全局打包问题)能够优化,而后无聊的同窗没事儿点点玩玩吧。
当打包构建应用时,Javascript 包会变得很是大,影响页面加载。若是咱们能把不一样路由对应的组件分割成不一样的代码块,而后当路由被访问的时候才加载对应组件,这样就更加高效了。 Webpack 的代码分割功能, 实现路由组件的懒加载.
官方说的挺详细了,这里就偷个懒不上代码了,给你们提供一种经典处理方式,咱们不放在组件上,直接对路由进行拆分,具体能够看 实战项目路由 的路由拆分
会发现不少这种注释:
const Blog = () => import(/* webpackChunkName: "blog" */ '@/container/blog/Blog')
复制代码
那么相似:
/* webpackChunkName: "blog" */
复制代码
不是白写的,他是配合 webpack 对项目各路由拆分的,咱们能够看看 实际项目加载状况 :
这个 blog.hash.js
不是咱们写的,是 webpack 进行分割的,这样相似 vue 这样的单页面架构,不会加载某模块老是加载所有脚本,大大提高加载速度。
原本不想讲的,简单说说吧,经常使用的也就那几种 svg 、base6四、 或使用fastdfs组件相似 CDN 的服务。
简单来说 base64 会减小你的 http 请求数量,要知道 XHR 可不是省油的灯,他会带来额外的处理请求和处理响应损耗,以表情为例,动辄几十个表情 http 请求彷佛太智障了一些,一般采用 base64 处理,减小了 http 请求数量,可是增大了图片自己的体积,若是你用了webpack 且你的表情在本地,那么 webpack 能够帮你自动进行 base64 编码哦。
用户上传的图片能够经过压缩图片大小或质量减小带宽哦,一般使用 GM 对用户上传的有必要大锁的图片 压缩成不一样大小的,根据业务加载,好比头像,默认确定不会请求原始图片,今日头条的正文,使用流量的状况下也会默认加载小图,这些都不是客户端能作到的,须要服务端压缩。
固然这些知识万里长征的第一步,之后的优化之路茫茫多,能大概想起来的好比 :Lazy-Load(优化首屏体验)、PWA(构建web APP)、服务端渲染(为了SEO)、骨架屏(提高用户体验),后端和服务端文章还没写, 1.0 版本就放这些吧,期待第二版填坑,下篇开始后端。
SO - 努力吧!
ps:mac下求推荐个懒人图床,七牛开始收费了,mweb 不能直接发布到七牛了,一张一张上传,我也很无奈啊。