性能优化手段之如何从10多秒到3.5秒(fast 3g disable cache)

1.性能优化手段有哪些?

image.png

2.咱们利用这些手段具体作了些什么?

网络环境默认为fast 3g disable cachehtml

构建优化

1.采用同构渲染(服务端渲染+客户端渲染)

a.什么是同构渲染,服务端渲染和客户端渲染

服务端渲染(Server Side Render),其实很是好理解,就是服务器返回一堆html字符串,而后让浏览器显示。与服务端渲染相对的是客户端渲染(Client Side Render)。前端

客户端渲染(Client Side Render):在浏览器中经过JS直接进行页面的渲染路由跳转等操做。好比:建立一个新的React项目,用脚手架生成项目,而后run起来。 这里你能够看到React脚手架自动生成的首页。打开页面源代码
image.pnghtml5

body中除了兼容处理的noscript标签以外,只有一个id为root的标签。那首页的内容是从哪来的呢?很明显,是下面的script中拉取的JS代码控制的。所以,CSR和SSR最大的区别在于前者的页面渲染是JS负责进行的,然后者是服务器端直接返回HTML让浏览器直接渲染。node

同构渲染:先后端共用一套JS代码,采用不一样的构建方式。经过Node服务器进行页面的首屏生成。webpack

SSR和CSR的渲染流程图:
image.pnggit

同构渲染的渲染流程图:
image.pngweb

b.他们的优缺点分别是什么?

SSR:npm

优势:后端

1.优秀的SEO浏览器

2.首屏加载快

缺点:

1.负载大:因为渲染任务都交由服务端进行,在高并发的状况下,对于服务端负载压力大。
2.复用性能差:由于返回的是整个页面,对于每一个路由都要从新进行页面刷新,复用性能 上不友好。
3.先后端耦合严重,前端开发依赖于后端,开发形式上不友好。

传统CSR:

优势:
1.节省服务器性能。
2.局部刷新,无需每次都请求完整页面,体验更好。
3.先后端分离开发。

缺点:

1.因为页面显示过程要进行JS文件拉取和React代码执行,首屏加载时间会比较慢。

2.对于SEO(Search Engine Optimazition,即搜索引擎优化),彻底无能为力,由于搜索引擎爬虫只认识html结构的内容,而不能识别JS代码内容。

同构渲染:

优势:兼顾前端渲染的大部分优势和后端渲染SEO和首屏加载的优势

缺点:1.须要额外的开发构建成本 2.对服务器有必定负载

c.使用以后效果如何?

CSR的效果

image.png

同构渲染的效果

image.png

经过对比,同构渲染 在下载html文件时,耗费的时间会多出(800ms-580ms)220ms的样子(由于文档内容较多的缘由)

CSR的白屏时间为3.8s

同构渲染的白屏时间为0.9s

可是,同构渲染在加载html文件的时间就几乎等于白屏时间,而CSR加载完html文件的时间远小于它的白屏时间。故咱们能够看出,同构渲染渲染大大减小了咱们页面的白屏时间,同时也减小了首屏时间。

d.具体在项目中的使用

由于咱们项目原本是CSR的,若是所有改为SSR,那么成本会很大,并且咱们的初衷只是提升性能,并非必定要用SSR,因此咱们就结合了一下,使用了同构渲染。即在服务器端执行一次,用于实现服务器端渲染(首屏直出),在客户端再执行一次,用于接管页面交互,获取须要的对应的数据,核心解决首屏渲染慢的问题。到这里你们必定会有疑问:

Q1:为何不在服务端经过请求接口的形式,把全部信息都拿到,这样就不用走一遍前端渲染了?

A1:由于咱们的项目须要在微信中打开,而后经过微信受权的形式,拿到对应的用户信息,而后再根据用户的信息发出请求以及对页面展现效果做出调整。因此在前期服务端渲染时,拿不到全部的信息,须要经过同构渲染的方式才能完成整个页面的渲染。

Q2:服务端渲染完了,前端再渲染一次,这样会消耗性能或者影响展现效果吗?

A2:不会,前端渲染会去作比较,只会渲染须要改变的DOM,而不会去改变其余的DOM。

2.按需加载

在优化手段的图中,构建优化这一块,除了咱们使用同构渲染,其余的中心思想都是在讲,如何作到按需加载,下面咱们就这一块具体来说一讲。

1.首先咱们须要肯定的就是咱们首屏中有哪些资源是必需的,哪些资源是非必需。js都是要作到异步加载的,同时根据状况调整成延迟加载和延迟执行的。

2.其次是给咱们首屏中的那些必需的资源,排一个加载顺序,作到尽可能不影响咱们的页面展现,影响展现的就延迟加载或者延迟执行。

a.js的异步加载,延迟加载,延迟执行

先解释标题,异步加载,延迟执行这2点是能够经过script标签加defer属性来作到,目的是不阻塞渲染,而延迟加载须要视业务场景来调整js文件的位置,目的是减小前期http并发请求数,减小首屏时间。

1.说说什么是defer,async,以及defer和async的区别是什么

defer 和 async 是 script 标签的两个属性。

对于defer,加载后续文档元素的过程将和 此js 的加载并行进行(异步),可是 js 的执行要在全部元素解析完成以后,DOMContentLoaded 事件触发以前完成。不过defer会按照本来的js的顺序执行,因此若是先后有依赖关系的js能够放心使用。(总结一下就是异步加载,延迟执行)

对于async,这个是html5中新增的属性,它的做用是可以异步的加载和执行脚本,不由于加载脚本而阻塞页面的加载,一旦加载到就会马上执行。在有async的状况下,js一旦下载好了就会执行,因此颇有可能不是按照本来的顺序来执行的。若是js先后有依赖性,用async,就颇有可能出错。

没有 defer 或 async,浏览器会当即加载并执行指定的脚本,“当即”指的是在渲染该 script 标签之下的文档元素以前,也就是说不等待后续载入的文档元素,读到就加载并执行。

二者的区别:

相同点:a.不会阻塞页面渲染 b.对于inline的script(内联脚本)无效 c.有脚本的onload的事件回调

不一样点:a.html的版本html4.0中定义了defer;html5.0中定义了async b.defer 执行要在全部元素解析完成以后,DOMContentLoaded 事件触发以前完成,而每个有async属性的脚本都在它下载结束以后马上执行,同时会在window的load事件以前执行。因此就有可能出现脚本执行顺序被打乱的状况。

2.具体在这个项目中的使用场景

七鱼客服的SDK 和 微信的SDK,都属于咱们刚刚说的,按需加载的第二点,这2个js都属于首屏中须要的文件,可是却须要延迟加载或者异步加载延迟执行的js。

其中七鱼客服的SDK能够延迟加载,延迟执行的,由于通常状况用户一进来页面是不会去当即点击咨询的,因此会给这个script加上defer属性,作到延迟执行,同时,在咨询按钮所在的footer组件中,走到componentDidMount生命周期时才去加载七鱼客服的SDK,就能够作到不阻塞渲染,减小前期http并发请求数,减小首屏时间。

其次,微信的SDK也是属于能够延迟加载,延迟执行的。咱们的项目是在微信中打开的,在项目中咱们须要先加载了微信的SDK,而后设置了微信分享的相关配置,才能点击分享。由于通常用户进来也不会当即去点击分享,因此会放到微信受权成功以后,再去加载微信的SDK,再经过script 标签上的onload回调函数,去设置微信分享的相关配置,同时给它加上defer属性,这样就作到了延迟加载,而且延迟执行。

对比调整先后的performance图

微信SDK调整前:
image.png

微信SDK调整后:
image.png

能够看到 调整后微信SDK的加载几乎对首屏加载没有较大的影响了。

b.webpack打包策略

默认的分包策略为:

1新的 chunk 是否被共享或者是来自 node_modules 的模块

2.新的 chunk 体积在压缩以前是否大于 30kb

3.按需加载 chunk 的并发请求数量小于等于 5 个

4.页面初始加载时的并发请求数量小于等于 3 个。

推荐阅读 https://juejin.im/entry/5b784... 这里是对webpack分包策略的分析。

总结性地来说,webpack分包是一个博弈的过程,须要结合具体的业务场景来决定是否分包。可是在咱们作性能优化的时候,有些基本点能够注意:

1.一些很小的包 好比只有几kb,可是由图能够看出
image.png

这个包绝大部分时间都花在了创建链接上,而它实际只有1.7kb.这样就能够考虑不拆这个包,将这个包和其余资源合并。

2.一些很大的包(具体怎么衡量包的大小,参考webpack默认的30kb)视它阻塞渲染的程度考虑是否拆包。

3.对打包的文件,要尽可能压缩,减小其大小。

对于静态资源的优化

1.图片资源的优化

a.对图片作压缩,在项目中对图片大小的要求是:1.gif不超过1M 2.其他不超过200kb3.宽度最多为页面宽度三倍。
b.兼容性的写法:经过<picture>元素使用在不一样情景下使用不一样格式的图片,优先级依次为webp,渐进式jpeg, png。

首先是对picture标签的介绍:HTML <picture> 元素经过包含零或多个 <source> 元素和一个 <img> 元素来为不一样的显示/设备场景提供图像版本。浏览器会选择最匹配的子 <source> 元素,若是没有匹配的,就选择 <img> 元素的 src 属性中的URL。而后,所选图像呈如今<img>元素占据的空间中。

eg:
image.png

oss 就支持转 webp, 只须要在图片连接后面加上?x-oss-process=image/format,webp 就能够了,不须要本身手动去转,iOS不支持webp,因此会在iOS设备上使用渐进式jpeg,对应的渐进式jpeg图片的说明 (confluence文档地址使用渐进式JPEG来提高用户体验),对于须要使用到透明度的图片才推荐使用png,不然不推荐使用png格式的图片。

c.对非首屏图片(img 背景图 视频的预览图)作懒加载。对于首屏的图片作懒加载反而会增长首屏时间。懒加载的npm包地址 https://gitlab.xiguacity.cn/e...

2.使用CDN

将咱们打包的静态资源文件上传到阿里云上。

其余优化手段

1.http/2

http/2这一块,因为不是由前端去设置,可是须要你们对它有所了解。

a.http/2是什么?
HTTP/2(超文本传输协议第2版,最初命名为HTTP 2.0),简称为h2或h2c,是HTTP协议的的第二个主要版本。

b.http/2和http/1.X相比有什么优点?
a.新的二进制格式(Binary Format),HTTP1.x的解析是基于文本。基于文本协议的格式解析存在自然缺陷,文本的表现形式有多样性,要作到健壮性考虑的场景必然不少,二进制则不一样,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。

b.多路复用(MultiPlexing),即链接共享,即每个request都是是用做链接共享机制的。一个request对应一个id,这样一个链接上能够有多个request,每一个链接的request能够随机的混杂在一块儿,接收方能够根据request的 id将request再归属到各自不一样的服务端请求里面。

c.header压缩,如上文中所言,对前面提到过HTTP1.x的header带有大量信息,并且每次都要重复发送,HTTP2.0使用encoder来减小须要传输的header大小,通信双方各自cache一份header fields表,既避免了重复header的传输,又减少了须要传输的大小。

d.服务端推送(server push),同SPDY同样,HTTP2.0也具备server push功能。

2.server workers

a.server wokers是什么?
service worker 是独立于当前页面的一段运行在浏览器后台进程里的脚本。

service worker不须要用户打开 web 页面,也不须要其余交互,异步地运行在一个彻底独立的上下文环境,不会对主线程形成阻塞。基于service worker能够实现消息推送,静默更新以及地理围栏等服务。

b.它能解决什么问题?
Service Worker 可使你的应用先访问本地缓存资源,因此在离线状态时,在没有经过网络接收到更多的数据前,仍能够提供基本的功能监控。

咱们在作页面性能优化时,也考虑过使用server workers,通常server works是在第二次访问时能访问到已有的本地缓存资源,咱们的项目的用户通常只会访问一次,因此咱们项目中没有使用这个方法,只是介绍给你们之后解决问题能够多一种思路。

3.结语

以上就是咱们在优化项目中所用到的性能优化手段,其中存在有不少能够改进和调整的地方,也欢迎你们都提出来。在性能优化这一块咱们也会持续地去作,在作的同时沉淀下来的文档,也但愿对你们之后在对本身项目进行性能优化的时候能有所帮助。

相关文章
相关标签/搜索