-
Notifications
You must be signed in to change notification settings - Fork 0
Description
页面请求过程优化主要是减少获取页面资源的时间,主要通过几个方面:
- 减少(或避免)请求数
- 减少请求和响应的数据量
- 缩短传输的路径和延迟
- 增加传输带宽
当浏览器请求资源时,需要通过发送网络请求来获取资源,网络请求是比较耗费时间的,如果浏览器减少网络请求的次数,甚至不发送网络请求就直接拿到需要的资源,就可以大大减少资源加载的时间,浏览器的本地缓存机制可以满足这一点。
Local cache
浏览器发送请求时,会根据url查找本地缓存,看是否本地缓存中存在该url的内容,如果不存在,则向服务器请求该url的内容;如果本地存在缓存,则按照如下策略:
优化点:
- 给静态资源设置适当的缓存时间 expire:xxx /cache-control:max-age=xxx,对更新不频繁的资源尽量利用本地缓存来减少网络请求的时间;
- 尽量利用条件查询请求,对资源返回的http头设置Last-Modified/Etag,当内容过期时,进行条件查询请求,尽量利用本地缓存的资源;
关于本地缓存机制,进一步阅读
充分利用本地存储LocalStorage
优化点
- 高级浏览器一般都支持本地存储,可以把需要网络请求的资源存放再浏览器的LocalStorage,需要资源时从本地存储获取,首次加载时通过服务端内联的方式返回,减少资源的网络请求;
静态资源多域名部署
在PC端或者强网络环境下,因为浏览器在同一个域名下的并发请求数有限制(4-6个url),为了能够加快静态资源的请求,可以
- 把静态资源分发到多个域名,让浏览器同时建立多个连接,并发进行多个静态资源的请求
注意:这种方法只适用于强网络环境,譬如移动端弱网络环境下,建立链接的耗费很多时间时,此方法不适用
DNS query
浏览器向服务器请求资源,是通过http协议进行通讯的,http协议是应用层协议,底层是TCP协议。因此浏览器发送请求时,需要和服务器先建立TCP连接,而建立TCP连接需要知道服务器的IP和PORT。而请求的url一般都是通过域名而不是IP提供给用户,因此浏览器和服务器建立连接之前,首先是获取服务器的IP。浏览器通过检查是否本地DNS缓存中是否有服务器host的ip,如果没有通过DNS查询来获取服务器的ip。
无线网络的现状:
- 2G:一般只有10KB/S下行和1KB/S左右的上行速度,延迟基本 >= 400ms;
- 3G网络:一般为下行100-200KB/S,上行10-100KB/S,延迟0-400ms,带宽方面基本逼近2M有线网络,但延迟较高,稳定性不够
DNS查询耗时:
- 在相对较快速的有线网络环境下,平均值为几十毫秒左右;
- 2G网络环境下,平均值在几百毫秒左右;
- 在网络很差的移动环境下,平均值达到几秒左右
优化点:
- 让浏览器提前查询dns: dns-prefetch
<link rel="dns-prefetch" href="xxx.com" >
- 在弱网络环境下减少页面中的资源的域名的个数,或者url中直接ip而不是域名
Connect To Server 和服务器建立连接
浏览器根据DNS查询得到ip+url中的端口跟服务器建立TCP连接。
因为用户和服务器之间的距离(不仅是物理距离,还有网络链路距离,以及跨运营商中转等)不同,建立连接的时间不同。
优化点:
- 采用CDN,让用户与它最近的服务器建立连接
TCP 3 handshake TCP建立连接3次握手
因为HTTP协议是无连接的,每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。每一个请求都要建立TCP连接,都要进行3次握手,建连成本大;
优化点:
- 减少建立连接的次数:merge CSS/js/image,合并资源,减少请求的资源的个数
- 减少建立连接的次数:remove empty src/href/URL
- 减少建立连接的次数:keep-alive, 若connection 模式为close,则服务器处理完一个请求之后会主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection 模式为keepalive,则当服务器处理完一个请求之后,该连接会保持一段时间,在该时间内可以继续接收请求;
Send HTTP Request 发送http请求
当浏览器发送http请求头时,会把相关一些信息发送,这些信息包括:UA,Localsetting,Referer,Cookie等,为了加快发送请求的效率,减少发送请求的时间,需要减少发送给服务器的数据量。
优化点:
- 能用get,不用post请求url,post至少发送两个包
- 减少发送的http header的大小:避免发送不需要的cookie,静态资源放到独立域名的服务器上
- 减少发送的http header的大小:缩短url的长度,不同浏览器和服务器对url的长度也有限制
GET / HTTP/1.1
Host:www.taobao.com
User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.17) Gecko/20110420Firefox/3.6.17
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Encoding:gzip,deflate
Accept-Language:en-us,en;q=0.5
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.
Keep-Alive:115
Connection: keep-alive
HTTP/1.1 200 OK
Server: nginx
Date: Thu, 12May 2011 11:02:36 GMT
Content-Type:text/html; charset=GB2312
Transfer-Encoding:chunked
Connection:keep-alive
进一步阅读
服务器的工作
服务器接到请求后,根据请求的url和数据等,经过一系列处理,最后返回一个大字符串就是网页的内容给浏览器。一般服务器处理一个动态请求的工作过程大概分几个部分:
- 接收请求
- 解析请求
- 路由转发
- 通过缓存、接口、数据库查询等途径获取数据
- 返回文件/渲染模版
- 输出内容
浏览器是边下载边解析,因此优化的方法是尽量减少浏览器的首包等待时间TTFB (TIME TO FIRST BYTE) ,
优化点:
- 服务端优化,通过各级缓存(页面缓存/数据缓存/数据库缓存/模板缓存/)及服务器多IDC部署等方法,减少服务端的数据处理时间;
- 采用bigPipe方案,flush buffer early 不必等所有数据都拿到再拼页面,有一点就输出,早点刷新缓冲区,减少浏览器的首包时间TTFB (TIME TO FIRST BYTE) ,让
浏览器尽早的进行解析和渲染。
传统页面展现
bigpipe页面展现
HTTP Response Header
再服务器端配置Last-Modified 和Etag,和设置缓存时间,让浏览器端尽量利用本地缓存;当缓存过期时,如果请求的资源没有修改,通过304响应,返回很少的响应头而不用返回全部的页面内容到浏览器。
- 304 Not Modified 浏览器还是利用老的缓存数据
- 200 Ok 新的内容
HTTP Response Body
返回的数据越少,传输的越快
优化点:
- 按需加载和返回页面需要的资源,优先返回首屏依赖的资源,剩余的资源按需加载
- 资源懒加载,例如图片,依赖的模块等,滚动加载剩余
- 异步刷新,不需要返回全部内容,只返回变化的部分,ajax等
- 返回的内容进行压缩HTML/CSS/js/img compres gzip
首屏优化
优化点:
- 按需加载和返回首屏需要的资源,服务端一开始只返回首屏依赖的资源,剩余的资源按需加载
- 首屏依赖的css和js除了类库,进行页面内联
- 页面的小图标进行base64编码之后,页面内联
- 首屏最好不要放js资源,js资源都放在首屏的下面进行加载
采用CDN服务
通过CDN服务,把资源部署到更接近用户的物理机房,
- 减少浏览器建立连接的时间
- 减少数据传输的链路长度
- 同时CDN会对数据进行缓存
- CDN会根据用户所在的运营商,在DNS解析时返回访问最快的机房IP
通过CDN服务,可以加快浏览器的获取数据的时间
采用SPDY/ HTTP/2
针对http1及http1.1存在的问题,产生了SPDY/ HTTP/2,尤其是HTTP/2 大大提高资源的请求和响应的时间。主要体现在:
优化点:
- HTTP/2 采用二进制格式传输数据,而非 HTTP/1.x 的文本格式。二进制格式在协议的解析和优化扩展上带来更多的优势和可能。
- HTTP/2 对消息头采用 HPACK 进行压缩传输,能够节省消息头占用的网络的流量。而 HTTP/1.x 每次请求,都会携带大量冗余头信息,浪费了很多带宽资源。头压缩能够很好的解决该问题。
- 多路复用,直白的说就是所有的请求都是通过一个 TCP 连接并发完成。HTTP/1.x 虽然能利用一个连接完成多次请求,但是多个请求之间是有先后顺序的,后面发送的请求必须等待上一个请求返回才能发送响应。这会很容易导致后面的请求被阻塞,而 HTTP/2 做到了真正的并发请求。同时, 流还支持优先级和流量控制。
- Server Push:服务端能够更快的把资源推送给客户端。例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 再发送这些请求。当客户端需要的时候,它已经在客户端了。



