资讯专栏INFORMATION COLUMN

前端性能优化与上线

wupengyu / 2584人阅读

摘要:看下状态可以看到我已经有一些镜像了我已经删除了拉镜像正常即可,中间那段是中国镜像源,我们成功下来了的镜像。攻破像我这样屌丝的服务器一般都买的,大的资源文件不住,一个动辄的文件这很蛋疼,不上很难受。

4000字长文,多图预警!!!流量慎入!!

性能优化 - 屌丝前端性能优化、上线一条龙

大家好我又来了,本章给大家带来的内容是:上线和上线后的性能优化

项目地址

实战预览地址

实战项目地址

本章代码地址

本章你会了解

前端需要了解的 docker 基础知识

部署前端项目到本地/外网服务

前端项目的 gZip 优化

了解 CDN 的重要性

webpack 按需加载

图片的相关优化

如何分析项目依赖,方便针对性处理

如何减小 webpack 打包大小/速度

上线

我们通常在本地开发,本地环境和线上也并非完全一样,很多项目第一次上线几乎都会遇到本地开发无法复现的问题,可能是字体、样式的问题,也可能是webpack 编译的问题、甚至可能是本地的奇葩环境。所以 本地完美运行 ≠ 线上完美运行,我们需要 build 项目,模拟线上测试一下,看看是否可以完美运行,有问题可以方便及时作出调整。

准备
为了避免本教程污染大家本地环境,推荐大家安装一个docker,后期运维也会根据 docker 展开。

看到这个 Title :《准备docker》,没接触过的前端不要怂,装一个,勇于跨出第一步,不学习就是等死「点击这里了解 docker」

虽然 tomcat nginx apache jboss jetty 等等等等都可以作为 http 服务,本章以最常见的 nginx 展开讲述:

大白话介绍下 docker

docker 就是用更优雅的方法,做到了虚拟机的事情,并且做的更好,可编程管理集群。docker 启动容器,在容器内部运行你的环境,默认各个容器是互相隔离的,当然你可以通过 link network 关联容器,或者直接使用 docker-compose 编排,启动容器的前提是镜像,也类似与虚拟机的镜像,想跑容器,先得下载「pull」镜像。

使用 docker

也许很多人没用过,没用过也不讲怎么安装了,自己去看官网吧中文官网、社区版下载、中国镜像加速,windows 的话可能要开启虚拟化,linux 推荐 ubuntu, 为了性能请不要在ventos中运行 Docker ,证据在这里 - 查看翻译点这里),几年前的文章了,现在怎么样有待考究。

看下 images 状态
docker images

可以看到我已经有一些镜像了「我已经删除了nginx」

dockerHub 拉 Nginx 镜像
docker pull registry.docker-cn.com/library/nginx:latest
正常 docker pull nginx 即可,中间那段是中国镜像源

ok,我们成功 pull 下来了 Nginx 的镜像。默认存储的镜像名为: registry.docker-cn.com/library/nginx

打包

进入我们上一章源码的目录,build 一下进行发布。
上一章源码在这里

npm run build

启动 docker 容器
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 你可能会有更多的疑问:

你怎么知道需要将主目录挂载到: /usr/share/nginx/html ?

能否/怎样 查看 Nginx 日志 ?

容器内的 nginx 能否自定义配置 ?

......

这些小白问题本章简单讲讲,后面做自动运维的时候多带带展开讲,可以关注我的博客

gZip

我们可以通过 webpack 压缩脚本文件,上传到 http 服务器,浏览器浏览的时候,经过压缩的HTTP应答报文是由浏览器解压的,比起压缩,解压的速度是非常快的(只要数据正常,可以解压的话),所以不用担心浏览器用于解压的时间会降低用户体验。事实上,浏览器解压消耗的这点时间比起数据包因为网络拥堵而耽误的时间要少的多也可控的多。

 

在浏览器发给服务器的HTTP请求报文中,使用Accept-Encoding字段标明自己支持的压缩格式,即自己可以解压哪几种压缩报文(gzip、zlib库提供的deflate)。服务器回复客户端的HTTP应答报文中,使用Content-Encoding字段标明该应答报文使用哪种压缩方式。

gZip 攻破 webpack、nginx

像我这样屌丝的服务器一般都买 1M 的,大的资源文件 hold 不住,一个动辄 400K 的 vendar 文件这很蛋疼,不上 gZIp 很难受。

打开 network 观察一下:

它有 144K 这么大

我们就以 webpack 打包的核心 vendor 为例,我们发现,客户端向服务端请求了 gZIp 资源 Accept-Encoding: gzip, deflate,但可惜服务端并没有给我们理想中的 response - Content-Encoding: gzip 的响应, 我们需要排查一下原因。

首先看看 webpack 到底打没打出来打出来 gZip 呢?看看他的目录有没有 js 的 .gz 文件。

很遗憾没有,只有一些压缩文件和用于定位的 map 文件,看来首先我们的打包就出现了问题。

大家还记得当初构建项目我发的这张图吗?

package.json 项目描述文件

打开看看 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 主机
 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后台必须运行一个进程,否则容器就会退出
进入 nginx 主机的第一件事 nginx 在哪???

Linux whereis 命令用于查找文件。

该指令会在特定目录中查找符合条件的文件。这些文件应属于原始代码、二进制文件,或是帮助文件。

该指令只能用于查找二进制文件、源代码文件和man手册页,一般文件的定位需使用locate命令。

语法

whereis [-bfmsu][-B <目录>...][-M <目录>...][-S <目录>...][文件...]

查看 nginx 位置

root@e0017cab245f:/# whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx

我们在 /usr/share/nginx 找到了根目录 html/

我们在 /etc/nginx/ 找到了 nginx 配置文件

ps 中间件这么多,谁记得住呢,记不住自己看看就行了不是吗?

查看一下 nginx 的配置

确实 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配置 代码在这里

如何修改 docker 内部的配置

就目前来看,你有两种方法可以选择:

直接 exec 容器进行修改,增加上述 gZip 代码段。缺点:若想重新基于镜像构建容器容器内的配置会丢失。(除非你 commit 镜像)

独立出配置文件,一劳永逸。

我们基于第二点在 new-bee/ 目录 同级 创建了一个目录 nginx/ 创建一个同名的 nginx.conf 文件。

nginx配置 代码在这里

先停止 nginx 容器

docker stop nginx

删除 nginx 容器

docker rm nginx

重新构建 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 的意义了,主要意义不是节省开源项目服务器带宽,而是全国各个节点的访问速度问题,也就解释了:我部署的项目访问速度还不错,你这里怎么这么慢,你网不好吧?CDN 来告诉你答案。

cookie

我们还是拿实战的 bbs论坛 举例子吧,查看网络状态:

使用 CDN 的几点优势

访问快

服务端压力小

webpack打包小且快(下面讲)

客户端的 cookie 是绑定服务端 域名 的, 看上图,我们需要 XHR 请求携带 cookie 访问服务端获取对应权限,但试想一下:每一个 js、img、甚至是css 都携带垃圾的 cookie ,在大用户量下,服务端承受着不应该属于他的痛苦,这样的消耗是特别应该避免的,我们可以随便翻一翻任何一个成熟的网站,都会发现存在自己的 CDN 服务,这样既优化了中国不同地区的访问速度,同时也大大减小了服务端的开销。

节省 webpack 打包大小/速度

很长时间前经历过公司前端 webpack 编译特别慢的问题,dev 模式下我们可以注掉开发范围外的 路由,但是 build 发布的时候似乎没法解决,使用了 Happypack 多线程打包还是不如人意,查阅资料读到了 这篇文章

我们可以把能够 externals 调的排除掉,然后使用 webpack 的 webpack.DllPlugin 生成依赖库(这点很重要),大大减少便以速度,DllPlugin 本质上的做法和我们手动分离这些第三方库是一样的,但是对于包极多的应用来说,自动化明显加快了生产效率。

如何分析项目依赖 webpack-bundle-analyzer

其实很多人都知道,可能刚入坑的同学不太了解,不管是 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 饿了么组件比较大,(我比较懒,全局导入的,可以用哪个引入哪个避免全局打包问题)可以优化,然后无聊的同学没事儿点点玩玩吧。

webpack 按需加载 : 一切皆模块

当打包构建应用时,Javascript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。 Webpack 的代码分割功能, 实现路由组件的懒加载.

官方详细说明

官方说的挺详细了,这里就偷个懒不上代码了,给大家提供一种经典处理方式,我们不放在组件上,直接对路由进行拆分,具体可以看 实战项目路由 的路由拆分

会发现很多这种注释:

const Blog = () => import(/* webpackChunkName: "blog" */ "@/container/blog/Blog")

那么类似:

/* webpackChunkName: "blog" */

不是白写的,他是配合 webpack 对项目各路由拆分的,我们可以看看 实际项目加载情况 :

这个 blog.hash.js

不是我们写的,是 webpack 进行分割的,这样类似 vue 这样的单页面架构,不会加载某模块总是加载全部脚本,大大提升加载速度。

图片处理

本来不想讲的,简单说说吧,常用的也就那几种 svg 、base64、 或使用fastdfs组件类似 CDN 的服务。

base64

简单来讲 base64 会减少你的 http 请求数量,要知道 XHR 可不是省油的灯,他会带来额外的处理请求和处理响应损耗,以表情为例,动辄几十个表情 http 请求似乎太智障了一些,通常采用 base64 处理,减少了 http 请求数量,但是增大了图片本身的体积,如果你用了webpack 且你的表情在本地,那么 webpack 可以帮你自动进行 base64 编码哦。

压缩图片

用户上传的图片可以通过压缩图片大小或质量减少带宽哦,通常使用 GM 对用户上传的有必要大锁的图片 压缩成不同大小的,根据业务加载,比如头像,默认肯定不会请求原始图片,今日头条的正文,使用流量的情况下也会默认加载小图,这些都不是客户端能做到的,需要服务端压缩。

结语

当然这些知识万里长征的第一步,以后的优化之路茫茫多,能大概想起来的比如 :Lazy-Load(优化首屏体验)、PWA(构建web APP)、服务端渲染(为了SEO)、骨架屏(提升用户体验),后端和服务端文章还没写,没时间了 1.0 版本就放这些吧,回头可以补个第二版。

SO - 努力吧!

项目预览地址

实战项目地址

博客地址

本章代码地址

感兴趣可以点个 star


ps:mac下求推荐个懒人图床,七牛开始收费了,mweb 不能直接发布到七牛了,一张一张上传,我也很无奈啊。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/27594.html

相关文章

  • 前端黑科技:美团网页首帧优化实践

    摘要:在美团支付的前端技术体系里,通过预渲染提升网页首帧优化,从而优化了白屏问题,提升用户体验,并形成了最佳实践。我们团队主要负责美团支付相关的业务,如果网站太慢会影响用户的支付体验,会造成客诉或资损。 前言 自JavaScript诞生以来,前端技术发展非常迅速。移动端白屏优化是前端界面体验的一个重要优化方向,Web 前端诞生了 SSR 、CSR、预渲染等技术。在美团支付的前端技术体系里,通...

    mrli2016 评论0 收藏0
  • 如何构建前端代码

    摘要:首先散文件是有害处的,第一是,散文件可能没有版本号的区分,这样因为缓存导致第二是散文件会严重拖慢性能,因为很多散文件不仅消耗请求资源,而且是在串行消耗。 基本认识 开发环境和线上环境的区别 在很久以前,前端的部署其实比较简单,开发环境下,静态资源往服务器上面一扔就ok了,如果考虑下优化或者代码保护,也只是加一个代码压缩和混淆。没错,刚入行的时候我就是这么干的。。。 但是随着前...

    jhhfft 评论0 收藏0
  • 链家网前端总架构师杨永林:我的8年架构师成长之路

    摘要:杨永林,人称教主,八年前端开发经验,原新浪微博前端技术专家,现任链家网前端总架构师。年年底,教主加入链家网,负责前端的整体架构工作。 杨永林,人称教主,八年前端开发经验,原新浪微博前端技术专家,现任链家网前端总架构师。长期研究Web访问性能优化和前端框架搭建。作为初始团队成员,教主参与了新浪微博所有PC版本的开发,其中4~6版以架构师的身份设计了微博PC版的前端架构。在新浪微博任职期间...

    liaosilzu2007 评论0 收藏0
  • Web优化躬行记(5)——网站优化

    摘要:最近阅读了很多优秀的网站性能优化的文章,所以自己也想总结一些最近优化的手段和方法。个人感觉性能优化的核心是减少延迟,加速展现。初步以为是这个功能导致的服务挂起,询问相关操作人员,得到当时的操作过程。  最近阅读了很多优秀的网站性能优化的文章,所以自己也想总结一些最近优化的手段和方法。   个人感觉性能优化的核心是:减少延迟,加速展现。   本文主要从产品设计、前端、后端和网络四个...

    233jl 评论0 收藏0
  • 大型网站性能监测、分析优化常见问题Q&A

    摘要:后端和移动性能优化需要的时间较长,出成果较慢。大型网站上,一般通过什么方式监控性能的用户端主要是真机监测监测,都属于真实用户监测。目前主要有以下两种类型,,最终用户性能监测。,,真实用户性能监测。 showImg(https://segmentfault.com/img/bVAbWm);@tanwen110 (唐文),曾负责腾讯四大平台之一网络媒体平台的整体运维、运营规划工作;曾任百度...

    Lavender 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<