从14年开始,手机百度就开始支持localstorage的细粒度缓存,配合inline渲染模式使用,在2G慢速网站将页面的js和css嵌入 到script和style标签,而后将源码存到localstorage,第二次访问的时候从localstorage读取,提升页面访问速度。css
最大的缺点是:须要页面渲染以后,读取localstorage缓存内容,而后二次拉取没有缓存或须要更新的资源。java
还有一个方案,就是利用cookie保存一个版本号信息,server端拿到cookie就能够判断出来须要下发和更新的资源。这个方案虽然能够避 免二次拉取,可是毕竟cookie的存储量有限,cookie太大就影响http上行请求速度。因此以前百度移动搜索结果页的方法就是整个页面存储一个 md5的版本号,若是有一个资源更新,那么就须要整个页面的资源代码从新下发,因此每每每周上线的时候会引发页面性能数据抖动。ajax
上面提到的cookie方案最大的问题就是:业务代码和通用代码都“一视同仁”,这样常常频繁变化的业务代码只要发生变化,通用代码也须要更新,因此每周固定上线时间就会所有从新下发一遍代码。缓存
为了解决这个方案的缺点,首先将须要缓存的代码进行分层:通用 和 业务。经过区分通用和业务代码,每段代码都有本身的独立版本号,业务层代码的修改就不会引发通用代码的更新,只会更新本身的版本号,下发本身的新版本。cookie
你们都知道cookie是能够按照域名来缓存的,二级子域名能够读取主域名的cookie,这个咱们称之为:cookie的doman维度。dom
cookie除了域名以外,还有一个容易被忽略的维度,就是不一样的pathcookie也能够不一样,下一级path是能够读取上一级path的cookie。这个是cookie的第二个维度:cookie的path维度工具
下面例子是同一个cookiepo_lsv在不一样domain和path的状况。post
key | value | domain | path |
---|---|---|---|
po_lsv | jZ-1_jA-1_cF-1_cM-1_jB-2 | po.m.baidu.com | /tiny |
po_lsv | jZ-1_jA-1_cF-1_cM-1_jB-1 | po.m.baidu.com | / |
po_lsv | jZ-1_jA-1_cF-1 | m.baidu.com | / |
以前使用md5,cookie value的长度是32个长度,若是利用value足够短的长度保存足够多的cookie信息。咱们的方法是使用以下约定:
维护版本号是很麻烦的一个工做,若是一不留神漏了哪一个,就会致使重大bug,好比页面一直reload等,因此咱们使用了打包工具来完成这个过程,避免了人工的错误。
localstorage.json的格式内容以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
{
"jA"
: {
"hash"
:
"2c79d70"
,
"files"
: [
"common:widget/localstorage/zepto-ajax.tpl"
],
"version"
:
1
},
"jZ"
: {
"hash"
:
"5358395"
,
"files"
: [
"common:widget/localstorage/zepto.tpl"
],
"version"
:
1
}
}
|
须要缓存到localstorage的文件都统一放在localstorage文件夹,再看下须要缓存的widget通过打包工具自动生成的代码:
1
2
3
|
<script data-lsid=
"jZ"
>
__inline(
'/static/js/zepto.js'
);
</script>
|
通过打包工具release以后,变成下面的smarty模板:
1
2
3
4
5
6
7
|
{%
if
($_ls_nonsupport) || ($_parsedLSCookies.jZ.isUpdate )%}
<script data-lsv=
"{%$_parsedLSCookies.jZ.version|escape:html%}"
data-lsid=
"jZ"
>
var Zepto=xxx
</script>
{%
else
%}
<script>LS.exec(
"jZ"
,
"js"
);</script>
{%/
if
%}
|
代码执行时候,解析cookie,而后读取localstroage.json的内容,跟cookie的版本号对比,生成模板变量,赋值给模板文件。