上一节介绍了网页加载过程中可优化的点,这一节我来说一下网络部分的优化。
网络部分包括了以下几个过程:
- DNS查询
- 建立TCP连接
- 发送HTTP请求
这几点中DNS和TCP方面我们其实是无从下手的,所以我们只能咋HTTP上动刀子了。HTTP是一个往返的过程,浏览器发送请求和接收响应。
请求
在请求层面,上一节我们也说到了请求环节的优化,那就是减少HTTP请求,因为网络请求是整个过程中最不确定的因素,它受环境的影响最为直观。那么具体该从哪些方面减少,比如:
- 每一个图片、样式……加载都会发送HTTP请求,所以可以将图片转为base64,现在前端开发一般都是使用打包工具来进行的工程化开发,打包工具一般会提供图片转base64的插件;合并小图标到css sprites (CSS精灵图)等,将小图标放置到一个文件,只需要一次加载,然后从这一张图片的位置去裁切,但是不要盲目合并导致文件过大,那样同样可能会影响体验
- 过多的样式文件和脚本文件也会增加HTTP的压力,所以适当的将脚本和样式进行合并,但是不要盲目合并,盲目合并导致文件过大同样会影响加载速度
- 少用location.reload()来刷新页面,每重新加载一次都会重新去请求资源
响应
在响应方面可以做的优化其实很简单,减小响应资源的体积——使用gzip压缩,启用gzip压缩也很简单,只需要在请求头中加入accept-encoding:gzip
。HTTP 压缩就是以缩小体积为目的,对 HTTP 内容进行重新编码的过程。
gzip可以帮我们压缩大约70%体积,但是他并不是万能的,他也是有代价的,开启gzip需要浪费服务器的计算资源,服务器的 CPU 性能不是无限的,如果存在大量的压缩需求,服务器也扛不住的,这时候就会得不偿失
HTTP缓存
HTTP缓存是一个减少加载时间的最有效地方法,HTTP缓存有强缓存和协商缓存两种形式。
强缓存使用Expires 和 Cache-Control 两个字段来控制,当请求再次发出时,浏览器会根据其中的 expires 和 cache-control 判断目标资源是否“命中”强缓存,若命中则直接从缓存中获取资源,不会再与服务端发生通信。
来看一个使用了强缓存的响应,可以看到它使用了cache-control,最大有效时间31536000,换算过来借接近一年,也就是说在未来一年中都不需要再去请求这个资源
协商缓存顾名思义就是浏览器和服务器共同协商的结果,当请求资源的时候浏览器会询问服务器资源是否过期,如果过期就重新加载资源,如果没有过期就直接使用缓存资源,协商缓存常用的字段有ETag/If-None-Match、Last-Modified/If-Modified-Since等
使用协商缓存之后HTTP状态码会变为304
关于强缓存和协商缓存可以看我之前的这篇文章
内容分发网络CDN
现在CDN已经是一种很廉价的资源了,各大云服务商都提供了自己的CDN服务,价格也很便宜,CDN通过判断用户的地理位置来选择请求距离最近的一台服务器,来减少资源传输的距离,从而减少响应的时间
CDN的核心在于缓存和回源,CDN服务器会缓存根服务器的资源文件;回源是CDN服务器去向根服务器请求资源的过程,一般发生在资源缓存过期。
静态资源加载速度始终是前端性能的一个非常关键的指标,因为静态资源的请求量一般比较大,而且体积较大,放置到CDN上可以减轻应用服务器的压力,应用服务器就可以专心处理业务而不用分心来响应静态资源。一般放置在CDN上的都是些静态文件,比如图片、样式文件等
懒加载
懒加载可以将不重要的图片文件在需要时加载,优先将网页的整体框架加载出来,当用户需要浏览图片时再去请求。此外可以在用户等待页面加载的过程中使用骨架屏来优化用户的体验,比如掘金的文章详情页就使用了骨架屏