從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的版本號對比,生成模板變量,賦值給模板文件。