官术网_书友最值得收藏!

1.4 客戶端緩存

客戶端緩存相對于其他端的緩存而言,要簡單一些,而且通常是和服務端以及網絡側的應用或緩存配合使用的。對于互聯網應用而言,也就是通常所說的BS架構應用,可以分為頁面緩存和瀏覽器緩存。對于移動互聯網應用而言,是指APP自身所使用的緩存。

1.4.1 頁面緩存

頁面緩存有兩層含義:一個是頁面自身對某些元素或全部元素進行緩存;另一層意思是服務端將靜態頁面或動態頁面的元素進行緩存,然后給客戶端使用。這里的頁面緩存指的是頁面自身的緩存或者離線應用緩存。

頁面緩存是將之前渲染的頁面保存為文件,當用戶再次訪問時可以避開網絡連接,從而減少負載,提升性能和用戶體驗。隨著單頁面應用(Single Page Application, SPA)的廣泛使用,加之HTML5支持了離線緩存和本地存儲,大部分BS應用的頁面緩存都可以舉重若輕了。在HTML5中使用本地緩存的方法也很簡單,示例代碼如下:

        localStorage.setItem("mykey", "myvalue")
        localStorage.getItem("mykey", "myvalue")
        localStorage.removeItem("mykey")
        localStorage.clear()

HTML5提供的離線應用緩存機制,使得網頁應用可以離線使用,這種機制在瀏覽器上支持度非常廣,可以放心地使用該特性來加速頁面的訪問。開啟離線緩存的步驟如下:

1)準備用于描述頁面需要緩存的資源列表清單文件(manifest text/cache-manifest)。

2)在需要離線使用的頁面中添加manifest屬性,指定緩存清單文件的路徑。

離線緩存的工作流如圖1-4所示。

圖1-4 HTML5 離線緩存的工作流程示意

由圖1-4可知:

1)當瀏覽器訪問了一個包含manifest屬性的頁面時,如果應用的緩存不存在,瀏覽器會加載文檔,獲取所有在清單文件中列出的文件,生成初始緩存。

2)當對該文檔再次訪問時,瀏覽器會直接從應用緩存中加載頁面以及在清單文件中列出的資源。同時,瀏覽器還會向window.applicationCache對象發送一個表示檢查的事件,以獲取清單文件。

3)如果當前緩存的清單副本是最新的,瀏覽器將向window.applicationCache對象發送一個表示無須更新的事件,從而結束更新過程。如果在服務端修改了任何緩存資源,必須同時修改清單文件,這樣瀏覽器才能知道要重新獲取資源。

4)如果清單文件已經改變,那么文件中列出的所有文件會被重新獲取并放到一個臨時緩存中。對于每個加入到臨時緩存中的文件,瀏覽器會向window.applicationCache對象發送一個表示進行中的事件。

5)一旦所有文件都獲取成功,它們會自動移動到真正的離線緩存中,并向window. applicationCache對象發送一個表示已經緩存的事件。鑒于文檔早已經從緩存加載到瀏覽器中,所以更新后的文檔不會重新渲染,直到頁面重新加載。

需要注意的是:manifest文件中列出的資源URL必須和manifest本身使用同樣的網絡協議,詳情可參考W3C相關的標準文檔。

1.4.2 瀏覽器緩存

瀏覽器緩存是根據一套與服務器約定的規則進行工作的,工作規則很簡單:檢查以確保副本是最新的,通常只要一次會話。瀏覽器會在硬盤上專門開辟一個空間來存儲資源副本作為緩存。在用戶觸發“后退”操作或點擊一個之前看過的鏈接的時候,瀏覽器緩存會很管用。同樣,如果訪問系統中的同一張圖片,該圖片可以從瀏覽器緩存中調出并幾乎立即顯現出來。

對瀏覽器而言,HTTP1.0提供了一些很基本的緩存特性,例如在服務器側設置Expires的HTTP頭來告訴客戶端在重新請求文件之前緩存多久是安全的,可以通過if-modified-since的條件請求來使用緩存。其中,發送的時間是文件最初被下載的時間,而不是即將過期的時間,如果文件沒有改變,服務器可以用304-Not Modified來應答??蛻舳耸盏?04代碼,就可以使用緩存的文件版本了。

HTTP 1.1有了較大的增強,緩存系統被形式化了,引入了實體標簽e-tag。e-tag是文件或對象的唯一標識,這意味著可以請求一個資源,以及提供所持有的文件,然后詢問服務器這個文件是否有變化。如果某一個文件的e-tag是有效的,那么服務器會生成304-Not Modified應答,并提供正確文件的e-tag,否則,發送200-OK應答。以Web瀏覽器使用e-tag為例,如圖1-5所示。

圖1-5 瀏覽器使用e-tag的流程示意

在配置了Last-Modified/ETag的情況下,瀏覽器再次訪問統一URI的資源時,還是會發送請求到服務器詢問文件是否已經修改,如果沒有,服務器會只發送一個304回給瀏覽器,瀏覽器則直接從本地緩存取數據;如果數據有變化,就將整個數據重新發給瀏覽器。

Last-Modified/ETag與Cache-Control/Expires的作用是不一樣的,如果檢測到本地的緩存還在有效的時間范圍內,瀏覽器則直接使用本地緩存,不會發送任何請求。兩者一起使用時,Cache-Control/Expires的優先級要高于Last-Modified/ETag。即當本地副本根據Cache-Control/Expires發現還在有效期內時,則不會再次發送請求去服務器詢問修改時間(Last-Modified)或實體標識(e-tag)了。

Cache-Control與Expires的功能一致,都是指明當前資源的有效期,控制瀏覽器是直接從瀏覽器緩存取數據還是重新發請求到服務器取數據。只不過Cache-Control的選擇更多,設置更細致,如果同時設置的話,其優先級高于Expires。

一般情況下,使用Cache-Control/Expires會配合Last-Modified/ETag一起使用,因為即使服務器設置緩存時間,當用戶點擊“刷新”按鈕時,瀏覽器會忽略緩存繼續向服務器發送請求,這時Last-Modified/ETag將能夠很好利用服務端的返回碼304,從而減少響應開銷。

通過在HTML頁面的節點中加入meta標簽,可以告訴瀏覽器當前頁面不被緩存,每次訪問都需要去服務器拉取。代碼如下:

        <META HTTP-EQUIV="Pragma" CONTENT="no-cache">

令人遺憾的是,只有部分瀏覽器可以支持這一用法,而且一般緩存代理服務器都不支持,因為代理不解析HTML內容本身。

瀏覽器緩存能夠極大地提升終端用戶的體驗,那么,用戶在使用瀏覽器的時候,會有各種操作,如輸入地址后回車、按F5刷新等等,這些行為對緩存的影響如表1-1所示。

表1-1 用戶的瀏覽器操作對緩存的影響

1.4.3 APP上的緩存

盡管混合編程(hybrid programming)成為時尚,但整個移動互聯網目前還是原生應用(以下簡稱APP)的天下。無論大型或小型APP,靈活的緩存不僅大大減輕了服務器的壓力,而且因為更快速的用戶體驗而方便了用戶。如何把APP緩存對于業務組件透明,以及APP緩存數據的及時更新,是APP緩存能否成功應用起來的關鍵。APP可以將內容緩存在內存、文件或本地數據庫(例如SQLite)中,但基于內存的緩存要謹慎使用。

APP使用數據庫緩存的方法:在下載完數據文件后,把文件的相關信息,如URL、路徑、下載時間、過期時間等存放到數據庫,下次下載的時候根據URL先從數據庫中查詢,如果查詢到當前時間并未過期,就根據路徑讀取本地文件,從而實現緩存的效果。這種方法具有靈活存放文件的屬性,進而提供了很大的擴展性,可以為其他的功能提供良好的支持。需要注意的是,要留心數據庫緩存的清理機制。

對于APP中的某些界面,可以采用文件緩存的方法。這種方法使用文件操作的相關API得到文件的最后修改時間,與當前時間判斷是否過期,從而實現緩存效果,操作簡單,代價較低。需要注意的是,不同類型文件的緩存時間不一樣。例如,圖片文件的內容是相對不變的,直到最終被清理掉,APP可以永遠讀取緩存中的圖片內容。而配置文件中的內容是可能更新的,需要設置一個可接受的緩存時間。同時,不同環境下的緩存時間標準也是不一樣的,WiFi網絡環境下,緩存時間可以設置短一點,一是網速較快,二是不產生流量費。而在移動數據流量環境下,緩存時間可以設置長一點,節省流量,而且用戶體驗也更好。

在iOS開發中,SDWebImage是一個很棒的圖片緩存框架,主要類組成的結構如圖1-6所示。

圖1-6 SD Web Image中主要類組成的結構來源https://githubcom/rs/SDWebImage/blob/master/Docs/SDWebImageClassDiagrampng

SDWebImage是個比較大的類庫,提供一個UIImageView的類以支持遠程加載來自網絡的圖片,具有緩存管理、異步下載、同一個URL下載次數控制和優化等特征。使用時,只需要在頭文件中引入#import"UIImageView+WebCache.h" 即可調用異步加載圖片方法:

        -(void)setImageWithURL:(NSURL  *)url  placeholderImage:(UIImage  *)placeholder
            options:(SDWebImageOptions)options;

URL是圖片的地址,placeholder是網絡圖片在尚未加載成功時顯示的圖像,SDWebImageOptions是相關選項。默認情況下,SDWebImage會忽略Header中的緩存設置,將圖片以URL為key進行保存,URL與圖片是一一映射關系。在APP請求同一個URL時,SDWebImage會從緩存中取得圖片。將第三個參數設置為SDWebImageRefreshCached就可以實現圖片更新操作,例如:

        NSURL *url = [NSURL URLWithString:@"http://www.abel.com/image.png"];
        UIImage *defaultImage = [UIImage imageNamed:@"mydefault.png"];
        [self.imageView  setImageWithURL:url  placeholderImage:defaultImage  options:SDWebI
            mageRefreshCached];

在SDWebImage中有兩種緩存,一種是磁盤緩存,一種為內存緩存,框架都提供了相應的清理方法:

        [[[SDWebImageManager sharedManager] imageCache] clearDisk];
        [[[SDWebImageManager sharedManager] imageCache] clearMemory];

需要注意的是,在iOS7中,緩存機制做了修改,使用上述兩個方法只清除了SDWebImage的緩存,沒有清除系統的緩存,所以可以在清除緩存的代理中添加以下代碼:

        [[NSURLCache sharedURLCache] removeAllCachedResponses];
主站蜘蛛池模板: 景宁| 云南省| 太仆寺旗| 阿拉善右旗| 永州市| 石屏县| 汝阳县| 吴堡县| 台北市| 盖州市| 秭归县| 保山市| 双柏县| 远安县| 明光市| 翁牛特旗| 万荣县| 陆川县| 茌平县| 阿城市| 隆昌县| 五莲县| 迁西县| 柘城县| 申扎县| 泸州市| 和静县| 罗源县| 山东| 大邑县| 井陉县| 科尔| 梧州市| 宝坻区| 治多县| 泰宁县| 通城县| 垦利县| 伊通| 澄迈县| 芜湖县|