w3ctech

好搜首页的cache研究

前言

现在jquery这么火,很多大公司也逐渐的“放弃”自己类库而使用jquery了,比如百度,360好搜(以下简称好搜)等,于是某天想看看他们用的哪个版本,百度源码里一搜,很明显的外链了jquery-1.10.2,而在360里源码居然没有找到,使我好奇心猛的上来了,于是我就查呀查。

本以为是用类型requirejs之类的工具处理了,可是抓取他的网络请求里也没有,且发现个怪异的问题,好搜的网络请求里的流量是异常的少,这是做什么处理了吗?于是。。。

思路

我查看好搜cookie发现一些资源标识,查看localStorage发现里面有大量代码,于是我想到了,可能是把代码放在localStorage里了,之前也见过类似的形式,但大多出现在移动端,主要是为了省流量,后来回过头再看百度,发现localStorage里的代码更多。那么好搜是如何处理的呢?又如何兼容的呢?

标识截图:

我把浏览器的cookie禁止后发现,好搜源码里内镶了jquery,用的版本跟百度的一样,哈哈。

禁用cookie后截图:

大概思路是这样的:每个资源(包括js,css)都有自己的uri标识,并且不会重复,后端在渲染页面的时候先判断cookie里有没有这个uri的信息,如果有则说明加载过了,则忽略,如果没有则加载这个uri的代码片段,当然需要js做一些事,大概伪代码是这样的:

// 后端渲染页面
// 如果cookie中存在,则证明已经加载并缓存过
if(cookie.get(uri)){
    <script>
        // 读取这个uri信息输出到页面
        cache.get(uri);
    </script>
} else {
    // 这里是大量的uri的代码片段
    <script>
        // 写入缓存
        cache.set(uri);
        // 写入cookie
        cookie.set(uri);
    </script>
}

优点和注意

  • 这样就充分的利用缓存来减少网络的成本,带来的好处大大的
  • 只要cache.js位置靠前,加载页面整个css都没问题,测试demo中加载同link方式加载效果一致,没有出来闪烁、卡顿的问题
  • 要注意做版本控制,时间控制,比如现在要上线项目,如何让用户访问到最新的
  • 需要注意到用户禁用cookie的时候,别出现如:

感谢 @乱码

目前前端小武博客使用该思路实现,点击查看

w3ctech微信

扫码关注w3ctech微信公众号

共收到9条回复

  • 哈哈,被你发现了

    整套机制,我们都是通过工具自动编译的。

    回复此楼
  • @老六 哈哈,不过禁用cookie后好搜首页报错不少

    回复此楼
  • 期待相关工具的出现

    回复此楼
  • 是判断locationStorage吧,cookie怎么放得下?

    另外jQuery有暴露版本号的接口,jQuery.fn.jquery,当然这个不是本文的重点。

    回复此楼
  • @前端小武 嗯,这是业务用到了localStorage,没加try导致的。

    回复此楼
  • @亦秋 先是后端处理,后端要判断cookie里是否有id标识,如果有表示有cache,然后输出localstorage2html的代码,如果没有cache则输入源码并追回html2localstorage的代码,js里负责写入localStorage并写信cookie标识的作用,当然还有一系列的版本控制机制

    回复此楼
  • 很赞~

    使用这个方案,需要考虑很多问题:1)cookie 被禁用;2)localStorage 被禁用;3)localStorage 被写满;4)localStorage 数据损坏;5)需要有一套完善的机制确保代码修改时能更新用户本地 localStorage。

    另外,我在这里也简单写了一下好搜的这个缓存策略:http://imququ.com/post/http2-and-wpo-1.html#toc-1-1

    其实,这个方案最好在服务端存一下每个用户拥有哪些资源,分别是什么版本,这样可以精准的更新指定代码。我们现在是记了一个总的版本号,任何一处修改都会导致所有 localStorage 缓存失效。

    回复此楼
  • m.haosou.com也用了这套,异步加载的js还会变成类似jsonp的方式,把js的md5当回调函数名,然后eval执行的; 数据接口使用了Math.round(当前时间戳/要缓存的时间)实现了定时过期; 不要问我为什么知道得这么多。。。

    回复此楼
  • @ququ 赞,一直在拜读你的博文。。。

    回复此楼