预备知识
W3C 的Navigation Timing Specification 定义了一组API ,可以观察浏览器的每一个请求的时序和性能数据。
浏览器发起一个链接请求的时候,浏览器会检查本地缓存,如果符合的cache信息,就会使用这个缓存填充请求。否则,因为无法命中缓存 ,就会发起一个完整的网络请求
浏览器检查连接池中已有的连接是否可以复用,即sockets 指定了scheme ,host ,port 定义的连接。如果没有,就会从DNS查询开始,获取网址对应的IP 地址
拿到IP 地址后,就会进行TCP 连接。三次握手,大家都知道的。当握手完成后,如果连接的是一个https 的地址,那么还需要一个SSL 握手过程
请求开始发送,服务器收到请求后,会传送响应数据回客户端。这里包含了最少的往返延迟和服务处理时间。一个请求完了,但是,如果期间有重定向,那么又要重头开始。
关于网页加载速度的思考
由上图可以看出,从App Cache 到 TCP ,对用户来说是透明的,浏览器可以优化这个阶段耗时。假设以下搜索场景,用户在浏览器输入框输入:githu ,打开github官网。
上图的依次是百度浏览器,QQ 浏览器,UC 浏览器,夸克浏览器,从搜索到打开网页,操作行为差异不大。那么搜索体验关键在于打开网页的速度。如何提高打开网页的速度,在网速等条件一样的时候,可以通过预连接来提高网页打开速度。
浏览器可以通过某些算法来预测用户搜索的行为,当满足条件的时候发起预连接。预测算法很关键,因为如果预测的命中率很低,那么将会引起多余的网络连接的处理,甚至会使加载速度更慢。浏览器这么成熟的产品,业内对此肯定有比较牛逼的实现方法。通过对关键字的搜索,结果显示Chrome 是最好的研究的对象。下面以mac 端的chrome 开展研究
Chrome 浏览器
用户在浏览器的行为:
- 启动浏览器
- 输入关键字
- 选择浏览器建议的网址
- 浏览器打开网页
启动浏览器
每次Chrome的启动,它会对你最近访问最多的10个域名进行DNS 解析,加快网页的打开速度 ,通过在浏览器输入框输入: chrome://dns 可以查看。
通过观察上面的数据,github.com 有8个对应的子资源主机,表中记录了每个主机的请求次数,TCP 预连接发生的次数以及DNS预解析发生的次数。这些数据都提供给Chrome 的Predicator 进行决策参考。
输入关键字
当用户在输入的时候,浏览器会根据输入的关键字,推荐相关的内容。并根据用户以往的行为等参数来预测点击的行为,提前进行预连接。通过在输入框输入:chrome://predictors 可以查看浏览器predicator。
Chrome维护着一个历史记录,内容包括用户输入的前置文字,采用的行为,以命中的资数。在上面的列表,你可以看到,当输入g时,有66%的机会尝试打开github. 如果再补充一个i , 打开github的可能性增加到100%。
黄色底色的url, Chrome会发起DNS预解析。绿色底色的话,Chrome还会在DNS解析后发起TCP预连接。通过chrome://dns 可以看出TCP 预连接的情况:
Chrome 在发生预连接之前,会检查socket pool 里面有没有可以复用的socket .如果没有,就发起TCP 连接,然后把对应的socket 放到socket pool 中,这些socket 会在socket pool 里面保留一段时间,方便下次复用。通过chrome://net-internals/#sockets 可以查看当前sockets 的状态:
平均而言用户从填写查询内容到评估给出的建议需要花费数百毫秒。此时Chrome可以在后台进行预解析,预连接,甚至进行预渲染。再当用户准备按下回车键时,大量的网络延迟已经被提前处理掉了。
浏览器打开网页
打开网页后,大量的资源会被cache 下来,当下次再次请求的时候,如果和cache 命中,网页的加载速度将会达到最快。在输入框输入: chrome://cache 可以查看chrome缓存的资,点击打开某一项,查看详细信息。
有效的cache 可以大幅度提高浏览体验。
Chrome 浏览器会是一个越用越快的浏览器! 它牛逼的地方肯定不止上面说的几点,利用周末学习了一下,受益匪浅呀。
移动端浏览器网络优化
- 记录用户常去的网站,在浏览器启动的时候进行预连接。
- 通过一定的算法预测用户打开网站的行为,提前进行预连接。