黑魔法:斷網離線也能看的頁面

Html5

背景

曾經作過一個Html5的iPhone應用,應用一打開就是一個用webview加載的Html5的頁面(如今Apple好像不讓這麼作了),當時送審這個App的時候,被Apple打回來了,緣由是當網絡不穩定或者斷網離線的時候,App一打開就是個白頁或者錯誤頁,Apple毫不接受這種垃圾的用戶體驗。因爲種種緣由,咱們暫時沒法將App作成Native的,因而,咱們開始考慮如何讓一個Html5頁面在斷網離線時也能正常顯示。php

通過技術調研,咱們找到了兩個能夠利用的技術:頁面靜態化和Html5的離線存儲技術,將這兩個技術結合,不但能夠加速頁面的訪問速度,並且能夠實現斷網顯示的效果。html

頁面靜態化

這並非一個新技術,爲了提升服務器的響應速度,以及下降服務器的負載,不少Web應用都在使用頁面靜態化技術。實際上就是用本來動態編譯的PHP代碼,生成一個靜態的html頁面。頁面靜態化特別適合內容相同、訪問量大的頁面,具體作法以下圖所示:web

靜態化頁面訪問流程

雖然頁面上的內容變化的頻率不高,但仍有變化的可能性,所以,除了首次請求時生成靜態頁面外,還能夠利用定時任務,自動生成新的靜態頁面。數據庫

定時生成靜態頁面

或者爲靜態頁面設置過時時間,而後由用戶訪問來觸發,判斷靜態頁面文件是否過時,從而生成新的靜態頁面。瀏覽器

用戶觸發

Html5離線存儲

Html5離線存儲,或者叫離線緩存,是Html5的一個新特性,利用這個特性,甚至能夠製做一個徹底離線的Html5應用。固然,我目前的需求還不須要作一個離線應用,但我能夠利用這個特性,將一個頁面離線在客戶端本地。
Html5的離線功能主要包括:離線資源緩存、在線狀態監測以及本地數據存儲。緩存

  1. 離線資源緩存: HTML5經過一個擴展名爲appcache的manifest緩存資源列表文件,來指明須要緩存的資源。這樣,瀏覽器才能在在線狀態時,把這些文件緩存到本地。此後,當用戶離線訪問應用程序時,這些資源文件會自動加載,從而讓用戶正常使用。服務器

  2. 在線狀態檢測:開發者須要知道瀏覽器是否在線,這樣纔可以針對在線或離線的狀態,作出對應的處理。在 HTML5 中,提供了兩種檢測當前網絡是否在線的方式。微信

  3. 本地數據存儲:離線時,須要可以把數據存儲到本地,以便在線時同步到服務器上。爲了知足不一樣的存儲需求,HTML5 提供了 DOM Storage 和 Web SQL Database 兩種存儲機制。前者提供了易用的 key/value 對存儲方式,然後者提供了基本的關係數據庫存儲功能。網絡

根據咱們的需求,咱們只須要利用第一個功能便可。
首先,咱們將頁面使用的全部資源(主要是圖片、CSS、JS等資源),添加到manifest緩存列表文件index.appcache。架構

CACHE MANIFEST
# This manifest was generated by grunt-manifest HTML5 Cache Manifest Generator

# VERSION 201705111330
CACHE:

# banner
upload/2017_05/14939781424709.jpg?v=201705111330
upload/2017_04/14933720467395.jpg?v=201705111330

NETWORK: 

FALLBACK:

而後,咱們須要在頁面模板上聲明一些方法,使得加載頁面時能夠自動調用Html5的緩存更新機制。

<script>
    //添加一個事件監聽器,監聽頁面加載這個動做
    window.addEventListener('load', function(e){
      //爲applicationCache添加一個事件監聽器,監聽緩存資源的更新狀態
      //若是緩存資源有更新,就會觸發這個監聽器
      window.applicationCache.addEventListener('updateready', function(e){
        //當applicationCache的狀態是UPDATEREADY時
        if(window.applicationCache.status == window.applicationCache.UPDATEREADY){
          //清除本地緩存
          window.applicationCache.swapCache();
          //更新本地緩存
          window.applicationCache.update();
          //重載頁面
          location.reload();
        }
      }, false);
    }, false);
</script>

離線靜態頁面

雖然咱們並無將靜態頁面自己加入manifest,可是瀏覽器仍然將靜態頁面做爲一個資源緩存在本地,而且會在每次請求加載這個頁面時與服務端對比是否有變化,若是沒有變化,則會直接使用緩存在本地的靜態頁面文件來提供服務,同時,該頁面上的資源也被緩存在了本地。當斷網時,因爲瀏覽器檢測manifest的請求沒法正常收到相應,瀏覽器就默認資源沒有變化,因而,就將離線在本地的整個頁面呈現了出來,咱們的目的便達到了。

掃描下方二維碼或者微信搜索[phpjiagoushier],關注個人微信公衆號[PHP架構],參與互動交流。

phpjisgoushier

相關文章
相關標籤/搜索