Weex緩存管理和實現(xiàn)

本文閱讀的前提是您對Weex已有所了解.
本文的緩存管理主要是由Native端去實現(xiàn)的(99%), Web端可能需要配合做相應的處理(1% 后面會提到).
本文的緩存管理是基于我對Weex的理解而建立的.

前言:
在做緩存之前也是網(wǎng)上看了很多資料, 大體的思路就是將所有JS打包成JS Bundle下載到本地, 通過服務端返回的ETag去判斷是否有更新, 決定是否更新本地JS Bundle.
參考資料:
Weex的JS緩存實現(xiàn) - Android
可能是史上最全的weex踩坑攻略
但是我覺得沒有必要將JS打包成Bundle統(tǒng)一下載, 一是慢, 二是如果某一個頁面發(fā)生改動則需要連同下載所有的JS, 這樣不是很好~

首先說下我的緩存思路~

在WeexSDK加載Url之前(RenderUrl), 對這個Url進行緩存處理和判斷, 針對頁面進行緩存處理和更新判斷
比如iOS代碼~:

// 拿到要渲染的http://xxx.js路徑 在渲染前對這個js進行處理
[[WeexCacheManager defaultManager] getRenderUrlWithRequestUrl:self.urlString callBack:^(NSURL *URL) {
            dispatch_async(dispatch_get_main_queue(), ^{
                // WeexSDK 渲染 js 
                [self.wxInstance renderWithURL:URL options:@{@"bundleUrl":URL.absoluteString} data:nil];
            }); 
        }];

這樣的話會很方便管理緩存~

緩存思路

目的:

1.僅對.js文件進行緩存處理, 降級后顯示的.html無需考慮~

2.將服務端.js文件下載保存至本地沙盒, Weex管理并只加載緩存JS文件

3.若從服務端下載.js文件失敗則不考慮加載緩存,直接渲染網(wǎng)絡文件

基礎(chǔ)配置:

1.在做緩存管理之前. 我是將JS文件放在服務端的, 本地渲染的是服務端上的JS地址.

2.圖片靜態(tài)資源也都是放到服務端部署的. 所以不存在加載Native端的圖片

3.頁面跳轉(zhuǎn)我是分開寫的,如果是Web環(huán)境使用Weex自帶的Navigator.Push(), 否則我是在Native中注冊跳轉(zhuǎn)的Module, 實現(xiàn)Native端可控的跳轉(zhuǎn)方法.JS代碼如下:

// push操作
    $push (path) {
      if (this.$isNativePlateform() && weex.supports && weex.supports('@module/navigation.push')) {
        weex.requireModule('navigation').push({
          h5Url: this.$getPushPath(true, path),
          fallbackUrl: this.$getPushPath(false, path),
          animated: true
        })
      } else {
        weex.requireModule('navigator').push({
          url: this.$getPushPath(this.$isNativePlateform(), path),
          animated: 'true'
        })
      }
    },

navigation是我在Native端自己注冊的方法, 方法也就是創(chuàng)建一個自己的WeexViewController, 當前頁面Push過去~ 我的這篇文章有關(guān)于頁面跳轉(zhuǎn)的思路說明

4.跳轉(zhuǎn)參數(shù)傳遞

  goOrderDetail (status) {
      if (status || this.isOrderList) {
        this.$push('views/order/order-detail?applyId=' + this.dataItem.applyId)
      }
    }

上面JS代碼可以看到我跳轉(zhuǎn)頁面的參數(shù)傳遞, 我只傳了頁面的相對地址和需要的參數(shù),在真正跳轉(zhuǎn)之前我會對這個path進行處理:

$getPushPath (path) {
 // 用于處理path, 返回正確完整的Path, 主要工作是判斷當前環(huán)境是否是Web環(huán)境, 如果是則返回.html + Query,  否則就是 .JS+Query 的形式
}

具體實現(xiàn):

先看下獲取到的完整的JS路徑地址:
http://baidu.com/blife-weex/dist/views/home/home.js?tokenServer=27abb15db479989f841c365ebbd&appDeviceid=e7212FF79-80-EC88D156AE95&sourceType=1&fromWhere=APP&appType=1&moduleCd=Home&inApp=1&refType=&refId=&version=1.0.0

這個地址也就是對應我們寫的一個Vue頁面~ 參數(shù)部分暫不考慮, 需要保存的文件名稱應該是:(URL.scheme + “://“ + URL.host + URL.relativePath 再去掉.js后綴)

http://baidu.com/blife-weex/dist/views/home/home

這就能保證文件名(地址)的唯一性了, 因為需要支持文件系統(tǒng)命名, 所以我將.js前面的部分用MD5轉(zhuǎn)換一下, 這樣文件名稱就變成了 0d86bb3022272b658d2b14374173e497.js
只要是這個地址, 所生成的MD5就是一樣的! 這也就是我們下在下來需要緩存的文件

保存在本地沙盒中某一指定的位置吧~

下一次再訪問這個地址, 如果發(fā)現(xiàn)本地存在這個MD5.js的文件就說明之前已經(jīng)做了緩存了~ 如果沒有當然就下載這個.js文件 以MD5.js形式保存就行了

接下來考慮下得到了已經(jīng)緩存的本地JS后改怎么辦~

我們需要判斷服務端的JS是否有更新, 如果更新了我們需要刪除本地JS并重新下載新的JS并緩存到本地,再加載最新的JS文件, 方法是通過Headers中的ETag值.
ETag: 可以理解成服務端文件對應的hash,當文件內(nèi)容變動了這個hash也會隨之變化,ETag也會變, ETag值存在請求服務端文件(.js)的網(wǎng)絡請求返回的Headers里
這樣的話我們就需要存儲ETag值去標識對應的緩存JS文件了~

我的做法是在當前沙盒目錄中再創(chuàng)建一個Plist/Map本地文件, 該Plist/Map文件只有一個, 構(gòu)造是Dictionary/Map套Dictionary/Map形式,
最外層Dictionary/Map以存儲的MD5(下載的JS文件名)作為Key, Value是一個Dictionary/Map, 這個子Dictionary/Map用于存Etag等值,

這樣的話在之前下載JS完成后, 存儲下載JS的請求的ETag值, 作為下次加載JS前判斷服務端是否更新的參照.

所以再加載本地JS前, 先發(fā)送一個Header請求, 拿到ETag值之后,通過Key/Value的形式找到本地存儲的Plist/Map中對應的MD5的對象, 再拿到上次請求JS的ETag標識, 如果不一樣則說明服務端更新了,需要重新下載~.

最后在只需要將本地JS路徑拼接上原URL的Query部分 返回給Weex讓其加載就可以了~
大致是這樣的URL:


file:///User/xxx/0d86bb3022272b658d2b14374173e497.js?tokenServer=27abb15db479989f841c365e

以上就是基本的緩存策略~

額外擴展:

1.簡化請求次數(shù)

在上述基本的緩存策略中, 我略加修改了一些東西 , 再下載后存儲ETag值的同時, 我同時保存了下當前的時間戳(秒), 我這邊設置了兩個小時(某一時間)內(nèi),不用判斷服務端是否更新, 不然的話每一次加載本地JS我都要去發(fā)送Header請求去判斷服務端更新這樣并不是很好~. 所以在加載本地JS時我判斷如果上次存儲的時間在兩個小時(某一時間)內(nèi), 則不發(fā)送Header請求, 直接加載本地JS. 如果超過兩個小時,則發(fā)送Header請求, 但如果發(fā)現(xiàn)服務端ETag值沒變 ,則更改這個時間戳為當前時間戳, 保證下一個兩小時(某一時間)內(nèi)依然不發(fā)送Header請求, 直接加載.

2.關(guān)于獲取域名和資源加載問題

其實一般都會出現(xiàn)關(guān)于域名更變的情況, 因為都會有測試服,正式服的部署.或者說在加載圖片的時候都是通過當前域名加相對途徑的形式去加載, 頁面跳轉(zhuǎn)也是這樣,所以這就會遇到一個問題:
在加載本地JS資源時,路徑都是file://的形式,沒有辦法獲取到真正的域名地址

解決方法:

同樣在下載JS保存ETag值的同時,保存下當前URL的域名, 在返回本地JS完整路徑的時候?qū)⑦@個域名以一個參數(shù)的形式拼接在Query里傳給前端, 這樣前端就可以通過獲取Query里的參數(shù)判斷出用什么域名去顯示靜態(tài)資源了(1%的修改在這里~)

3.關(guān)于加載本地JS緩存后 weex-ui 中 wxc-icon組件顯示錯誤
解決方法:

我在這里提了issue, 我是Copy了他們的源碼放在本地,改了下請求就好了

iOS的小禮物

我將整理好的緩存管理類上傳到GitHub(記得點個?)了, iOS的同學可以直接用或者修改, Android的...我不會哈

PS:以上思路可能不是最好哈, 如果有可以改進的地方還請留言交流討論

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末宇立,一起剝皮案震驚了整個濱河市扇救,隨后出現(xiàn)的幾起案子淳地,更是在濱河造成了極大的恐慌荷愕,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件牍帚,死亡現(xiàn)場離奇詭異茫死,居然都是意外死亡,警方通過查閱死者的電腦和手機履羞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進店門峦萎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人忆首,你說我怎么就攤上這事爱榔。” “怎么了糙及?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵详幽,是天一觀的道長。 經(jīng)常有香客問我浸锨,道長唇聘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任柱搜,我火速辦了婚禮迟郎,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘聪蘸。我一直安慰自己宪肖,他們只是感情好表制,可當我...
    茶點故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著控乾,像睡著了一般么介。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蜕衡,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天壤短,我揣著相機與錄音,去河邊找鬼慨仿。 笑死久脯,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的镶骗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼躲雅,長吁一口氣:“原來是場噩夢啊……” “哼鼎姊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起相赁,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤相寇,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钮科,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唤衫,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年绵脯,在試婚紗的時候發(fā)現(xiàn)自己被綠了佳励。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,965評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蛆挫,死狀恐怖赃承,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情悴侵,我是刑警寧澤瞧剖,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布,位于F島的核電站可免,受9級特大地震影響抓于,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜浇借,卻給世界環(huán)境...
    茶點故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一抵怎、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧槐雾,春花似錦瓦糟、人聲如沸堵泽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迎罗。三九已至,卻和暖如春片仿,著一層夾襖步出監(jiān)牢的瞬間纹安,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工砂豌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留厢岂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓阳距,卻偏偏與公主長得像塔粒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子筐摘,可洞房花燭夜當晚...
    茶點故事閱讀 44,914評論 2 355