shtml頁(yè)面局部緩存的實(shí)現(xiàn)
平時(shí)在web開發(fā)中,對(duì)于shtml頁(yè)面,用得最多的SSI指令是include。語(yǔ)法規(guī)則如下:
<!–#include virtual=”shtmlCache/header.shtml” –>
這樣可提高代碼重用性以及可維護(hù)性,因此,一般都把公共文件,如頭部、尾部、側(cè)邊欄、公共的JS等做成一個(gè)單獨(dú)的文件,然后通過include指令包含進(jìn)來,這樣整個(gè)站點(diǎn)的頭部、尾部、側(cè)邊欄、公共JS等,都可以被引入到shtml頁(yè)面中。后面需求更改,比如產(chǎn)品需要更改站點(diǎn)頭部,也只需要更改頭部文件,就可以實(shí)現(xiàn)全站頭部更新。可見通過include指令包含公共文件,可以使shtml頁(yè)面的維護(hù)性和重用性大大增強(qiáng)。
一般來說,對(duì)于shtml頁(yè)面,一個(gè)站點(diǎn),每個(gè)頁(yè)面都會(huì)有相同的公共文件,比如頁(yè)面的頭部、尾部、側(cè)邊欄目、公共JS等。訪問站點(diǎn)下的每一個(gè)頁(yè)面,相同的公共文件,都需要重復(fù)從服務(wù)器下載。從性能和帶寬角度看,重復(fù)下載相同內(nèi)容對(duì)性能不利,同時(shí)也會(huì)占用帶寬。因此include進(jìn)來的公共文件,是否有辦法緩存這些文件呢?這就是這里需要重點(diǎn)討論的內(nèi)容。 假設(shè)有這樣一個(gè)站點(diǎn),包含有頁(yè)面頭部、側(cè)邊欄、頁(yè)面尾部、公共JS。布局如下圖:
從上面的網(wǎng)頁(yè)布局結(jié)構(gòu)可看出,頁(yè)頭、側(cè)邊欄、頁(yè)尾都是屬于公共的內(nèi)容,HTML 代碼樁如下:
實(shí)現(xiàn)原理:
需要判斷include的文件是否緩存過,如果緩存過,則不會(huì)通過include來包含對(duì)應(yīng)的內(nèi)容。ssi有判斷的指令,語(yǔ)法如下:
<!–#if expr=”test_condition” –>
< !–#elif expr=”test_condition” –>
< !–#else –>
< !–#endif –>
我們可通過SSI指令來判斷是否緩存過。同時(shí)可利用html5的localStorage來對(duì)代碼進(jìn)行保存。
可localStorage只能夠通過JS訪問,那如何實(shí)現(xiàn)localStorage和服務(wù)器的ssi指令通信呢?這里利用到一個(gè)小技巧,借助cookie作為橋梁,不管是JS還是SSI都是可以訪問,因此可利用它來實(shí)現(xiàn)SSI和JS之間的通信。換言之,用JS寫一個(gè)cookie來標(biāo)識(shí)是否已經(jīng)緩存過相應(yīng)的內(nèi)容,然后利用SSI的if語(yǔ)句結(jié)合cookie來判斷是否需要include對(duì)應(yīng)的內(nèi)容。
主要流程圖如下:
示例分析:
來看一個(gè)簡(jiǎn)單的demo。以前面頁(yè)面框架為例,假設(shè)header里面有內(nèi)容是通過JS來輸出,側(cè)邊欄是全部的HTML,現(xiàn)在要緩存header中的JS和側(cè)邊欄的HTML。先來看核心的HTML代碼(SSI部分):
再看JS寫入緩存核心代碼:
localData.loadfromCache是實(shí)現(xiàn)從localStorage讀取緩存并渲染出來,這個(gè)比較簡(jiǎn)單,這里就不再單獨(dú)介紹,大家可以下載示例代碼來查看,或者放在支持ssi的服務(wù)器下運(yùn)行。第一次訪問后,將會(huì)把對(duì)應(yīng)的公共文件進(jìn)行緩存,先查看解析后的HTML源代碼:
從上圖可以看出,第一次訪問時(shí),因沒有緩存過,都是通過include進(jìn)行直接解析。同時(shí)通過cookie和localStorage可查看到相應(yīng)的值。
cookie信息:
第二次訪問時(shí),再查看解析后的HTML源代碼
從上面的2個(gè)圖對(duì)比可以看出,當(dāng)公共文件沒有被緩存時(shí),是通過解析include指令得到相應(yīng)的代碼;當(dāng)有緩存時(shí),直接通過JS代碼從緩存中讀?。粡亩鴮?shí)現(xiàn)shtml文件局部緩存;
版本控制:
上述示例演示了shtml的局部緩存,那么緩存的版本如何控制呢?可通過cookie來保存版本號(hào),當(dāng)有緩存的公共文件需要更新時(shí),需要更新ssi if語(yǔ)句中的的版本號(hào),也就是更新下面這行代碼中的版本號(hào):
<!–#if expr=”${HTTP_COOKIE} = /(;)?html_aside=01(;)?/”–>
假設(shè)上一個(gè)版本號(hào)是01,現(xiàn)在版本號(hào)是02,此時(shí)需要把上述代碼更改為:
<!–#if expr=”${HTTP_COOKIE} = /(;)?html_aside=02(;)?/”–>
當(dāng)從SSI中讀取到的cookie值和新的版本號(hào)不一致時(shí),就不會(huì)從緩存中讀取了。同理在檢測(cè)寫入緩存時(shí),也需要檢測(cè)當(dāng)前cookie的值和當(dāng)前的版本號(hào)是否一致即可,如果不一致,則需要重新寫入緩存。
安全控制
這里把JS和HTML等代碼都緩存到localStorage中去,如果網(wǎng)站中存在XSS漏洞,則攻擊者可利用XSS漏洞篡改localStorage保存的數(shù)據(jù),這樣會(huì)擴(kuò)大網(wǎng)站的危害性,因此首先要從源頭上控制好XSS漏洞,同時(shí)也需要對(duì)從localStorage中讀取出來的數(shù)據(jù)進(jìn)行合法性校驗(yàn),以便降低安全風(fēng)險(xiǎn)。大家可以自行設(shè)計(jì)一個(gè)算法來檢測(cè)數(shù)據(jù)的合法性。
上面的示例中只是對(duì)簡(jiǎn)單的header中的JS和側(cè)邊欄的HTML進(jìn)行緩存,在實(shí)際項(xiàng)目中,需要緩存的JS和HTML代碼量要比示例中大得多,因此性能優(yōu)化的實(shí)際效果也會(huì)更加明顯。因此在實(shí)際項(xiàng)目中,可根據(jù)公共文件的大小來決定是否需要使用shtml緩存。另外,關(guān)于緩存時(shí)間,只需要把cookie的有效期設(shè)置為N天,則緩存的周期就變成N天了,非常靈活!
本文地址:http://irelandcustomcontracting.com/tutorial/wd1915.html
- 專訪:石墨文檔產(chǎn)品總監(jiān)羅穎
- UI設(shè)計(jì)不得不知的移動(dòng)端UI尺寸適
- 光音移動(dòng)設(shè)計(jì)規(guī)范 — 表單類
- 體驗(yàn)設(shè)計(jì)中的排序問題
- 網(wǎng)頁(yè)設(shè)計(jì)精粹 網(wǎng)頁(yè)中那些迷人的按
- aliued:響應(yīng)式設(shè)計(jì)的現(xiàn)狀與趨勢(shì)
- 10個(gè)智能對(duì)象處理的ps技巧
- 網(wǎng)頁(yè)UI - 原子設(shè)計(jì)理論(上)
- 如何通過設(shè)計(jì)提升banner點(diǎn)擊率?
- 晉小彥視覺設(shè)計(jì)系列文章(二):全屏