传输加载优化
启用压缩Gzip【必会的传输压缩方案】
Gzip是用来做网络资源压缩,帮我们减小资源文件在网络传输大小的技术,网络传输的过程中,去进行这种实时的动态的一个压缩,这个可以说是我们唯一可以选择的一个技术,Gzip压缩比和压缩效率比较高
在传输层进行的动态压缩和我们之前讲的对资源文件的压缩是不同的概念
Gzip
- 对传输资源进行体积压缩,可高达90%
- 如何配置Nginx启用Gzip
安装ngnix
- 安装homebrew
https://brew.sh/
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- 安装ngnix
brew install nginx
- 运行ngnix
sudo brew services start nginx
- 查看配置文件
vim /usr/local/etc/nginx/nginx.conf
看配置文件默认端口时8080
访问localhost:8080
在用户名目录下新建文件夹,把打包后的内容放到文件夹里,建议不要放到Documents下,因为这样会引起一些权限的问题,还要对权限进行相关的调整
然后修改配置文件的路径
配置gzip
gzip on;// 开启gzip
gzip_min_length 1k; //文件至少1k才进行压缩
gzip_comp_level 6; //压缩级别,有1-9,这边使用6,压缩比例越高,对cpu的消耗也越高,权衡下取6,比较合适的值
gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/xml text/javascript application/json;//压缩文件类型,通常对文本类文件进行压缩,压缩效果会比较好,图片类一般不进行压缩,消耗资源比较大,效果不是很好
gzip_static on;// 对gzip已经压缩的静态资源直接利用
gzip_vary on;//会在响应头部添加vary的属性,告诉客户端我们是否启用了gzip压缩
gzip_buffers 4 16k;// buffer优化压缩过程
gzip_http_version 1.1;//压缩使用的http版本
保存退出,重启ngnix,sudo brew services start nginx
启用Keep Alive【通过一个参数提速连接】
这个技术可以帮助对TCP链接进行复用,当我们和一台服务器进行TCP建立连接之后,接下来的请求就不需要进行重复建立链接了,这样对于请求量比较高的网站,就可以大大节约我们在网络加载时候的开销
它是我们http标准中的一部分,因为它多数情况下是有益无害,所以在http1.1开始,Keep Alive参数默认进行开启
第一个资源有下图的Initial connection,此为TCP链接的建立,后面的资源加载就没有Initial connection
下图头部可以看到keep-alive参数
curl -v http://127.0.0.1:8080可以查看请求和响应的详细信息
和Keep Alive相关的还有两个比较重要的参数,通常我们要根据网站实际的请求量和用户量进行相关配置,打开ng配置文件
keepalive_timeout 65;//超时时间,当客户端和服务端进行tcp链接建立后,服务端会尽量保持住tcp链接,但是一直不用的话,是需要进行超时关掉的,65秒都没使用tcp链接,就会把它关闭掉,如果设置为0,指的是不启用keepalive,每一个请求都必须建立自己的tcp链接,65这个值是否够用,如果做的是面向用户的网站,这个值是绰绰有余的,如果65秒你的页面还未加载完,这是非常可怕的,要根据实际情况,看下这个服务一共要花多长时间完成这些请求,请求数据量的情况,要找到上限,在这个时间之内,可以保证我所有的请求能充分复用一个tcp链接,完成我这次服务所需要请求到的数据就可以了
keepalive_requests 100;//当客户端和服务端进行tcp链接建立后,会开始一个计数,有个技术限,利用这个tcp链接一共可以发送多少个请求,比如这边100之后就会关闭tcp链接,第101个请求需要重新建立tcp链接
为什么要设置以上的值呢?一直开启不可以吗?每个东西都是有开销的,一个客户端和服务端建立tcp链接,考虑用户规模,上万、十万、百万、千万,服务器上要给这些用户都保持住tcp链接,这个开销还是非常大的,所以资源不再使用就要退出,以上参数要根据实际情况配置
Keep Alive
- 一个持久的TCP连接,节省了连接创建时间
- Nginx默认开启keep alive
HTTP资源缓存【必会的HTTP缓存方法】
-
提高重复访问时资源加载的速度
-
Cache-Control/Expires
-
Last-Modified+If-Modified-Since
与Etag+If-None-Match是等价的,Last-Modified+If-Modified-Since与时间相关,时间的精准性,客户端服务端时间不同步,会带来一些问题,要求不高可以使用,它们对http1.0是更兼容的 -
Etag+If-None-Match
第一个是匹配html,我们现在主要都是单页应用,所有的资源文件都是通过html进行后续的加载,如果html缓存了,更新时缓存如果没有过期就会通过html拿到旧的js、css,html不希望进行缓存,希望用户始终拿到最新的html,这个文件本身也不大
Cache-Control是http1.1的标准,不需要进行缓存,需要这个文件时去服务端重新获取,获取完要进行重新验证
配后面两个是为了兼容性问题,老版本浏览器不支持http1.1,要考虑http1.0里Cache-Control没有很好的实现,就需要Pragma参数,告诉只支持http1.0的浏览器也不要进行缓存,Expires配置0或者是负数的话,相当于无效值,告诉浏览器你这个文件立即就过期,下次再用时一定得去服务端拿
js、css7天内浏览器都缓存住,用户重新去访问时,直接去缓存去,不用来服务端取,结合webpack的缓存技术,js、css都用了hash的命名方法,当html进行有效更新后,html指向的css、js的url发生变化,这里过期时间就不重要了,url发生变化,浏览器就认为是新的资源文件,需要去服务器拿新的资源文件,旧的文件就被丢弃掉了,那能拿到的css、js也是最新的资源
虽然html没有缓存,但状态是304,会向服务器做请求,我要用的文件需不需要从你那拿,服务器告诉它你这个文件未发生变化,可以从缓存里拿,服务器就返回状态304,浏览器就知道未发生变化,还可以用之前的缓存
服务端如何知道客户端要请求的资源对客户端而言有没有发生变化
Etag(Response Headers)相当于是文件资源的唯一标识,是在服务端生成的,会告诉客户端我们这个资源标识是什么,在第一次请求时就会把这个信息带过来,再次进行请求时,会问下服务端我的Etag还匹不匹配(If-None-Match(Request Headers)),不匹配我就从你那拿最新的资源,还匹配就告诉我304,我就从缓存离直接取
Etag刚ng配置里没有配,ng是默认开启Etag缓存技术
js从磁盘的缓存里进行加载,有时候是内存缓存,这根据缓存策略不同
Expires(Response Headers)7天都从缓存去取,Date拿的日期是7月9日,过期时间Expires是7月16日
看看第三方如何缓存的
-
天猫
max-age设置正数,表示当前资源文件经过多少秒之后失效,0表示通过第一次获取立即失效
s-maxage不是给浏览器进行设置的,是给到达浏览器之前的一些中间的一些缓存或者说是代理服务器进行缓存的设置 -
知乎
默认是public,public认为中间层或者代理服务器可以做一级缓存,也就是说,所有的用户已经在代理啊服务器上进行了缓存,所有的用户可以去向代理服务器获取已经缓存的资源文件,private这个缓存只能在浏览器或者用户的层面上,不可以去获取一个代理服务器或者中间的缓存层上一个共享的缓存;再次进行访问时状态还是200,不是304,因为它这边不是设置no-cache,设置的是更强的缓存策略no-store,并不关心文件有没有发生变化,始终要跟服务器获取最新的文件,强制让你的缓存失效,而且不使用任何重新验证的策略,所以这边must-revalidate可能时没有必要的,下面也没有Etag+If-None-Match的设置了 -
google
重新访问状态也是200,不过这个200不是从服务器来的,而是从 ServiceWorker,ServiceWorker是一个缓存机制,在浏览器端建立了一个中间的缓存,后续的请求都是从这个中间的缓存里进行获取,虽然Cache-Control设置了no-cache,no-cache是和服务器重新验证下我这个资源有没有过期,但是它并没有真正去进行和服务器这样的一个确认,因为它通过了ServiceWorker,ServiceWorker直接告诉它这是命中的缓存,你可以直接去使用,不需要和服务器进行重新的确认,也是因为Cache-Control默认时public,才会有这样的效果
更多配置看https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers网站
一次性理解Service workers技术,给网站提速
Service workers作用
- 加速重复访问
- 离线支持
用户没有网络的情况下也可以让用户访问到我们的网页
将网络情况切换到offline,网页仍然可以正常访问
如果建工程是使用create-react-app这个脚手架工程的话,默认会获得serviceWorker的功能,使用很简单,不需要进行配置或者实现,serviceWorker也有自己的生命周期,首先要注册安装激活才可以使用
打包后的目录有个asset-manifest.json里定义了哪些资源要进行缓存,以及缓存文件的文件名
相关的版本信息会存在precache-manifest里,每个文件都有相关的版本信息,这些文件不可能手工去生成,会很复杂
需要借用webpack插件帮我们做这些事情,google帮我们去做了相关的实现