3.预取
接下来讲Prefetching,预取,是优化的另一个思路。我们现在优化的思路无非就是少。很多都是从少的角度,比方说前面把文档大小减少,把图 片的大小减少。很多张的图片变成一张精灵图,都是为了把发送请求的数量减少。预取的话,是另一种思路,提早加载好资源,用户去点的时候,实际上已经加载 好,那肯定是更快了。
预取,一共有两部分:一部分是资源的预取,还有一部分是DNS的预解析。
资源预加载有几个点需要注意:
预加载只是在浏览器空闲的时候才会去拉,但不保证一定会去拉,这是很重要的一点。因为本身浏览器有一个全局的监听器,这是内部的一个接口,当浏览气空闲的时候,它会去执行浏览器空闲的时候应该做事情,但是这个空闲的回调不一定被触发,所以说并不保证一定会执行预加载。
Chrome不支持HTTPS资源的预加载,像Alipay是HTTPS的页面,Chrome不会去预拉取。
一个预拉取的页面虽存在后不可见,实际上它是在正常解析。假如说我预拉取登陆页面,登陆页面有很多资源,比方说有图片,有CSS文件,JS文件。它 是从上往下正常的会被解析,解析的过程中,这个页面没有显现,但是它实际上是存在的。在HTML5里面,可通过 document.visibilityState得到当前页面状态,通常页面有两种状态,可见与不可见,但是现在有一个新的状态,叫做预渲染的状态。可 以直接通过document.visibilityState 是否等于 prerender 来判断页面是否在预渲染状态。
4.DNS解析
接下来是关于DNS的解析。有时候我们登入页面,对用户可能点的地方相对而言是比较难探测到,当然有时候我们会做一些埋点来探知用户下一步行为大部 分是往里走。但有些情况下,我们不知道用户下一步具体会走到哪一个页面的时候,但是我们知道他要走到哪一个域。这个时候,我就可以预解析DNS。因为实际 上,整个页面的请求过程中间有一个很长的DNS的解析过程,如果说这个我们提前做了,就可以更进一步让用户看到这一页面。
以下是Q+壁纸的案例。Q+壁纸是Q+某一个系统系统,首先Q+整个的架构是基于WEB + 客户端。我们现在看到的就是一个WEB的页面,虽然它外面是一个客户端的壳,但是它的心是WEB的。整个过程在我们第一次在完成的时候,因为图片比较多, 所有的静态资源是分配到十几个静态服务器上。也就是说,如果我要去拉的时候,我就要解析10个DNS,这个时间是相当耗时的,最慢的时候可能会延迟几秒 钟,这是我们肉眼能感觉到的。如果进行DNS预解析,因为本身资源我不知道具体是哪一个,所有图片都是随机的,所以我们只能说在DNS预解析上下功夫,来 提升它的速度。这样的话,从原来可能需要2秒钟,我就变成1秒钟。
接下来讲Q+中的应用。我们会像QQ里面一样,QQ里面跟Q+都有很多文字链,就是窗口的左下角有一个文字APP信息的推送。这边是通过WEB时时 去拉取后端,后端拉取过来然后在前台显示。但是在某一个时期,其实所有的APP它一共推送的运营信息是固定的。如果说按某个具体APP去分析每个文字链对 应数组的话,这个时候是非常大数据。因为这里一个就大概有达到三四百个字节,从优化的角度说,我们把这些每次拉区过来的存在本地。再存上本地的 localStorage,我们是同一域,所有的APP之间的信息都是可以相互访问的。然后就是把所有拉过的ID,就不会再重新拉一遍。
在这里也有一个需要注意的点,localStorage目前很多厂商的实现是同步的。如果你大量地调用localStorage这个接口,实际上他 会阻塞你的渲染进程。这个时候,当用户往下拖动页面的时候,然后你这个时候又正好在做存储数据,这个数据又比较大,这个时候用户就会感觉你这个页面非常 卡。之前他们都有讨论这个问题,本身这个接口的设计IE是设计成异步的,他们设计是成同步。这个会导致在调这个借口的时候,假设你程序比较多,因为有一个 序列化的过程,序列到磁盘。这样的话,整个过程就会显得比较慢。再加上本身localStorage可以做不同的窗口之间共享这个数据,它会在这个数据上 加锁。如果大量地数据在调用这个本地接口,它就会显得比较卡。所以目前没有什么特别好的解决方案,但是这是需要记住的。即使说目前最大的五点多兆,如果你 用了五点多兆,会让用户很悲催。因为你如果一去调用这个借口,用户在拖用鼠标,就觉得非常卡。