145  
查询码:00000831
前端性能优化最佳实践(三)
作者: 朱凡 于 2020年06月26日 发布在分类 / FM组 / FM_App 下,并于 2020年06月26日 编辑

网络

DNS

prefetch,看淘宝首⻚


TCP

IP TCPHTTP的关系

1.IP负责找到

2.TCP负责数据完整性和有序型,三次握手,粘包,滑动窗口等机制

3.http应用层,负责应用层数据,数据终止时机


优化策略:

1.⻓连接

2.减少文件体积

1.js打包压缩

2.图片压缩

3.gzip

3.减少文件请求次数

1.雪碧图

2.js,css打包

3.缓存控制

4.懒加载

4.减少用户和服务器的距离

1.cdn

5.本地存储三次握手


图片

首先我们先来总结一下我平时开发当中经常会用到一些图片格式分类:


1.PNG概念简介便携式网络图形(PNG)是一种无损压缩的位图图形格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。是现在网⻚当中应用最广泛的图片格式之一

PNG-8只能使用256种颜色,可以设置透明色,支持索引色透明和Alpha透明。PNG-24最多可使用1600万种颜色,色彩度和清晰度相比PNG-8更好,但是不支持透明度。PNG-32则是综合了PNG-8和PNG-24的有点,既有丰富的色彩和清晰度表现,而且还支持设置透明度。

logo,颜色简单但对图片质量要求较高,雪碧图


2.JPG/JPEG简介JPG/JPEG是另外一种在网站中使用频率较高的格式之一,它是一种有损压缩的格式,在不影响人们可分辨图片质量的前提下,尽可能的压缩文件的大小

大的轮播banner图片,其他一些列表图片。使用JPG/JPEG格式的图片大小不会太大,图片质量也适中,是当下图片主要的解决方案。

3.GIF简介GIF文件的数据,是一种基于LZW算法的连续色调的无损压缩格式。它的压缩率一般在50%左右,它不属于任何应用程序。GIF格式可以存多幅彩色图像,如果把存于一个文件中的多幅图像数据逐幅读出并显示到屏幕上,就可构成一种最简单的动画。平时大家微信聊天用到的动态表情包都是GIF格式,GIF格式应用也是比较广泛的。主流网站应用场景GIF的应用场景主要是一些动画的展示

项目进入前loading加载效果。各种需要动画的列表


4.SVG简介SVG是一种基于XML语法的图像格式,全称是可缩放矢量图。严格来说应该是一种开放标准的矢量图形语言,可让你设计激动人心的、高分辨率的Web图形⻚面。用户可以直接用代码来描绘图像,可以用任何文字处理工具打开SVG图像,通过改变部分代码来使图像具有交互功能,并可以随时插入到HTML中通过浏览器来观看。而且SVG体积很小,可以大大节省资源。主流网站应用场景SVG本身是可编程性的语言(支持直接插入DOM当中),可被非常多的工具读取和修改。SVG与JPEG和GIF图像比起来,尺寸更小,且可压缩性更强,而且SVG图像可在任何的分辨率下被高质量地打印,SVG可在图像质量不下降的情况下被放大,SVG图像中的文本也是可选的,同时也是可搜索的(很适合制作地图)。

常用来绘制地图,股票K线图但是会损耗性能


5.WebP简介WebP格式是谷歌开发的一种旨在加快图片加载速度的图片格式。这里为了说明其优势,我们引用官方的说法来说明,WebP为网络图片提供了无损和有损压缩能力,同时在有损条件下支持透明通道。据官方实验显示:无损WebP相比PNG减少26%大小;有损WebP在相同的SSIM(StructuralSimilarityIndex,结构相似性)下相比JPG/JPEG减少25%~34%的大小;有损WebP也支持透明通道,大小通常约为对应PNG的1/3。全能的解决方案,就是兼容性不太好

除了谷歌浏览器对WebP格式支持比较好之外,其他浏览器对WebP的支持显然还不够好,这也是WebP的短板之一。

虽然WebP的兼容性不是很好,但是由于其巨大的优势,我们想出了各种方案来处理这个问题,下面我们主要介绍一下主流网站是如何使用WebP格式的图片的。

根据浏览器判定加载格式


6.Base64简介Base64这个术语最初是在“MIME内容传输编码规范”中提出的,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64不是一种加密算法,虽然编码后的字符串看起来有点像加密。它实际上是一种“二进制到文本”的编码方法

因为图片base64之后会变大,所以适合小的矢量图标

其他图片优化

图片渐进显示(先显示低分辨率,然后显示高的)懒加载(实践)

⻣架图(实践)


缓存

缓存的优点不用多说,少加载文件,节省流量,好处大大的

1.cdn缓存

2.本地缓存

1.localstorage

2.indexdb


3.cookie

3.浏览器缓存

cdn

缓存+回源

地理位置更近,新的域名规避cookie

浏览器缓存

看图说话



强缓存,expires和cachecontrol

expiresexpires是强制缓存策略的关键字段,expires是HTTP1.0的字段,通过指定一个具体的绝对时间值作为缓存资源的过期时间,具体的设置方法如下:

我们在首次发起请求的时候,服务端会在ResponseHeader当中设置expires字段,可以看到我们设置的过期时间是Tue,09Jul201906:16:29GMT。那么如果在这个时间之前我们发起请求去请求资源,我们就不会发起新的请求,直接使用本地已经缓存好的资源,这样我们可以有效减少了不必要的HTTP请求,不仅提升了性能,而且节省了流量,减少网络资源的消耗。expires作为最开始的强制缓存解决方案,看起来没什么问题,但它的时间和服务端的时间是保持一致的,可是我们最终比较的时候是用本地


时间和expires设置的时间进行比较。如果服务端的时间和我们本地的时间存在误差,那么缓存这个时候很容易就失去了效果,这个时候功能更强大的Cache-Control出现了。Cache-ControlCache-Control同样也是强制缓存的关键字段。Cache-Control是HTTP1.1才有的字段,Cache-Control设置的是一个相对时间,可以更加精准地控制资源缓存。如下:

可以看到这里cache-control设置的值为max-age=315360000,这里的单位是秒,315360000代表缓存的时间跨度。由于这个是相对时间,所以不会受到服务端和本地时间不统一造成的缓存问题。315360000秒是一年,现在大多网站的静态资源设置的跨度都是315360000秒,也就是一年的时间跨度。用法expires的字段值是一个时间戳,而Cache-Control可设置的字段值较多,下面我们一一来介绍。

public:设置了该字段值的资源表示可以被任何对象(包括:发送请求的客户端、代理服务器等等)缓存。这个字段值不常用,一般还是使用max-age=来精确控制;private:设置了该字段值的资源只能被用户浏览器缓存,不允许任何代理服务器缓存。在实际开发当中,对于一些含有用户信息的HTML,通常都要设置这个字段值,避免代理服务器(CDN)缓存;no-cache:设置了该字段需要先和服务端确认返回的资源是否发生了变化,如果资源未发生变化,则直接使用缓存好的资源;no-store:设置了该字段表示禁止任何缓存,每次都会向服务端发起新的请求,拉取最新的资源;max-age=:设置缓存的最大有效期,单位为秒;s-maxage=:优先级高于max-age=,仅适用于共享缓存(CDN),优先级高于max-age或者Expires头;max-stale[=]:设置了该字段表明客户端愿意接收已经过期的资源,但是不能超过给定的时间限制。


两者同时存在,Cache-Control的优先级要高于expires。



协商缓存

如果命中强制缓存,我们无需发起新的请求,直接使用缓存内容,如果没有命中强制缓存,如果设置了协商缓存,这个时候协商缓存就会发挥作用了。下面我就来介绍协商缓存中的字段。Last-Modified/If- Modified-SinceLast-Modified从字面意思就可以看出是最后一次的修改时间,设置方法和我们上面讲的强制缓存的设置方法一样,都是设置一个时间戳,同样它也是由服务端放到ResponseHeaders返回给我们,如下:

如果有设置协商缓存,我们在首次请求的时候,返回的ResponseHeaders会带有Last-Modified。当再次请求没有命中强制缓存的时候,这个时候我们的RequestHeaders就会携带If-Modified-Since字段,它的值就是我们第一次请求返回给我们的Last-Modified值。服务端接收到资源请求之后,根据If-Modified-Since的字段值和服务端资源最后的修改时间是否一致来判断资源是否有修改。如果没有修改,则返回的状态码为304;如果有修改,则返回新的资源,状态码为200。

缺陷

服务端对Last-Modified标注的最后修改时间只能精确到秒级,如果某些文件在1秒钟以内被修改多次的话,这个时候服务端无法准确标注文件的修改时间。服务端有时候会定期生成一些文件,有时候文件的内容并没有任何变化,但这个时候Last-Modified会发生改变,导致文件无法使用缓存。

Etag/If-None-Match可以看到Last-Modified/If-Modified-Since是有一定缺陷的,因此后来又增加了Etag/If-None-Match,用法与Last-Modified/If-Modified-Since相似,但是Etag更准确。它通常是根据文件的具体内容计算出一个hash值,只要文件的内容不变,它就不会发生改变,保证了唯一性,这一点可以类比人的指纹。Etag/If-None-Match的用法这里对应Last-Modified/If-Modified-Since。如果我们


有设置协商缓存,在首次请求的时候,返回的ResponseHeaders会带有Etag值。当再次请求没有命中强制缓存的时候,这个时候我们的RequestHeaders就会携带If-None-Match字段,它的值就是我们第一次请求返回给我们的Etag值。服务端再用Etag来进行比较,如果相同就直接使用缓存,如果不同再从服务端拉取新的资源。



Tips:设置协商缓存,一般来说也是要这2个字段同时存在的,因为Last-Modified/If-Modified-Since本身有一定的缺陷,加上Etag/If-None-Match之后,整个缓存系统更加稳定。

小结这一小节我们介绍了强制缓存和协商缓存的对应字段,这些贯穿了整个浏览器的缓存方案。每个字段的概念和使用场景都非常重要,这里还是希望大家下去能够在项目当中真正实践起来,这样才能对这些字段有更加清晰的认识。下一小节我们将介绍Webpack结合缓存的使用方法以及如何使用Nginx和Apache设置缓存字段。


webpack打包和缓存的关系

1.hash,整个项目相关的hash

2.chunkhash,入口文件依赖的chunkhash

3.contenthash文件内容的hash


其他

1.memorycache内存缓存,比如存储在变量里,关闭tab就没了

2.Diskcache硬盘上的缓存

3.Pushcache推送缓存http2

4.serviceworkder浏览器背后的独立线程



 推荐知识

 历史版本

修改日期 修改人 备注
2020-06-26 15:49:48[当前版本] 朱凡 创建版本

 附件

附件类型

JPEGJPEG

  目录
    知识分享平台 -V 4.8.7 -wcp