Cordova深度定製的H5容器實際應用

前言

上一篇關於Cordova的文章簡單介紹了Cordova的主要實現代碼和Cordova對web容器和插件相關的處理,本篇將着重介紹Cordova在平臺化應用中的深度定製化。目前原生開發者持續不斷的在受到前端開發者的衝擊,前有Cordova相關的hybrid類APP,後有weex、RN等框架的出現,固然我以爲weex、RN類技術是更應該被提倡的,由於他們兼顧了JS開發,原生渲染的特色。可是Cordova類框架也有它們的優勢,微應用徹底可使用任何前端框架來編寫,而且可控性強,雖然在渲染層面和weex、RN有必定的差距,可是目前咱們使用react.js這種單頁面應用配合離線包策略,也必定程度上下降了它們在渲染層的差距,有效快速的解決發版週期之間的矛盾、跨平臺開發、實時發佈等一些問題,並且有效地保證了發佈質量和線上問題的及時修復。css

框架對外提供

1.基於Cordova交互插件化,打包提供給H5使用,H5只須要引入一個文件就可使用native提供的各類原生功能,包括但不限於fetch,map,IO操做,文件操做等。html

2.提供「離線包」策略,提高渲染速度和避免沒必要要的網絡請求,進行構建微應用。前端

3.提供三方受權服務,進行微應用的單點登陸受權功能。react

web容器優化方案

首先,手機要經過無線網絡協議,從基站得到無線鏈路分配,才能跟網絡進行通信。 無線網絡基站、基站控制器這方面,會給手機進行信號的分配,已完成手機鏈接和交互。 得到無線鏈路後,會進行網絡附着、加密、鑑權,核心網絡會檢查你是否是能夠鏈接在這個網絡上,是否開通套餐,是否是漫遊等。核心網絡有SGSN和GGSN,在這一步完成無線網絡協議和有線以太網的協議轉換。 再下一步,核心網絡會給你進行APN選擇、IP分配、啓動計費。 再往下面,纔是傳統網絡的步驟:DNS查詢、響應,創建TCP連接,HTTP GET,RTTP RESPONSE 200 OK,HTTP RESPONSE DATA,LAST HTTP RESPONSE DATA,開始UI展示。

可見,經過運營商的網絡上網,狀況比較複雜,通過的節點太多;運營商的網絡信號強度變化頻繁,鏈接狀態切換快;網絡延遲高、丟包率高;網絡創建鏈接的代價高,傳輸速度快慢不等(從2G到4G,相差很大)。程序員

1.壓縮html, js, css

壓縮代碼,尤爲是js和css資源,壓縮後的大小能夠下降至原來的1/3如下,有效節約流量。web

2.避免30*/40*/50*的http status

200是一個正常的response,咱們在瀏覽器中打開一個網頁(後面會講如何針對移動端進行調試),還會看到304,即命中瀏覽器緩存。這兩種狀態是正常的http status。瀏覽器

30二、301跳轉是常見的跳轉,尤爲前一種,在咱們進行鑑權的時候有時會用到,但這個作法要儘量地優化,一個頁面訪問,最多隻進行一次302跳轉便可,切忌頻繁地跳轉。緩存

40四、500,咱們對本身開發的代碼比較注意,通常不會發生,可是有的時候,加載第三方庫,尤爲是第三方庫中有本身load組件的操做,這時,404和500錯誤可能會在你不知不覺的時候發生。安全

3.資源的版本更新

業務的js和css可能常常會有更新,若是命中瀏覽器緩存,可能會讓一些新的特性不能及時展示,甚至可能致使邏輯上的衝突。所以對於這些js、css的資源引入,最好用版本號或者更新時間來做爲後綴,這樣的話,後綴不變,命中緩存;後綴改變,瀏覽器自動更新最新的代碼。bash

4.接口數據緩存

緩存接口數據,在一些數據新舊敏感性不高的場景下頗有做用,在非首次加載數據時候優先使用上次請求來的緩存數據,可讓頁面更加快速地渲染出來,而不用等待一個新的http請求結束以後再渲染。

5.單頁應用

釘釘的審批微應用,使用的就是單頁架構。在這種架構下,基本不存在頁面跳轉的等待時間,只須要執行js邏輯觸發界面變化,最多進行一次網絡請求,得到服務端數據,其餘資源均不須要再次請求。

6.資源離線

再快的網絡交互,畢竟也是跨越了數個網絡節點,所以一張圖片、一個js,優化到了極致,也照樣可能須要幾百毫秒的時間來得到。所以想要打破這個極限,就要使用資源離線的策略。網頁代碼裏面加載網絡資源的需求,就變成了直接加載本地文件,速度天然獲得再一次巨大的提高。

7.預加載機制

有時,咱們可以經過用戶的行爲統計,預判出用戶下一步可能進行的操做。假設,咱們統計出來針對某個微應用,用戶首頁渲染完成以後,大部分會點擊列表中的第一個項目查看詳情。那麼在首頁渲染完成以後,咱們就能夠先預先加載第一個項目的部份內容,那麼針對這部分用戶,他們實際點擊以後,當即就能看到新的頁面中的內容。

在平臺內H5頁面是怎麼加載JS插件的:

起初咱們的H5代碼都是隨着應用一同發佈的,這樣不一樣平臺的應用天然會將相應的cordova.js打包到應用中,加載相應的cordova_plugin.js,初始化js插件。因爲應用逐漸走向平臺化發展,那麼咱們的問題來了,怎樣將咱們的插件給其餘三方應用使用?讓其餘系統能夠方便的集成和使用?基於這樣的需求,咱們引入了兩個自定義的js文件,cordova-dynamic-loading.jspm-cordova.js。cordova-dynamic-loading.js須要在業務端代碼前引入,用於檢查cordova環境,而且根據客戶端系統,初始化不一樣的插件。而pm-cordova.js是js-bridge接口封裝庫。

架構圖大體以下:

  • 1.H5應用層:目前基於react.js構建的單頁面應用,取消頁面跳轉帶來的沒必要要的網絡加載。

  • 2.插件API接口層:平臺對外輸出插件接口。

  • 3.平臺標識:其實是爲瀏覽器設置的惟一標識,區分不一樣平臺,便於加載不一樣的js插件使用。

  • 4.動態加載:基於不一樣平臺的userAgent,動態加載相應平臺的js插件,其中cordova-dynamic-loading.js和cordova.js爲具體實現代碼。cordova.js還承擔着原生與js交互對插件id,參數的傳遞,回調的存儲等相關工做。

  • 5.平臺:不一樣平臺提供相應平臺的js插件,供cordova.js加載。

具體這兩個文件的實現代碼由前端大神編寫的,這裏就不粘了,做爲一個菜鳥iOS程序員,前端目前還尚處於學習中。固然框架內還提供了自定義的pm-cordova-mock.js可選引入,是pm-cordova.js的web端mock版本,本地開發業務進行測試時能夠引入這個文件替換pm-cordova.js。除此以外,平臺內也一樣內置了一套相關代碼,三方應用徹底能夠沒必要集成插件相關代碼也能夠與平臺進行交互。

定製userAgent

UIWebView沒有提供設置UserAgent的接口,可是能夠經過cordova框架內CDVUserAgentUtil類,設置userAgent。

@interface CDVUserAgentUtil : NSObject
+ (NSString*)originalUserAgent;
+ (void)acquireLock:(void (^)(NSInteger lockToken))block;
+ (void)releaseLock:(NSInteger*)lockToken;
+ (void)setUserAgent:(NSString*)value lockToken:(NSInteger)lockToken;
@end
複製代碼
+ (void)setUserAgent:(NSString*)value lockToken:(NSInteger)lockToken
{
    //斷言
    NSAssert(gCurrentLockToken == lockToken, @"Got token %ld, expected %ld", (long)lockToken, (long)gCurrentLockToken);
    //設置userAgent
    //必須在實例化UIWebView以前設置UserAgent。
    //它是按實例化讀取的,因此它不會影響之前建立的視圖。
    //除外!當一個PDF被加載時,全部當前活躍的uiwebview從新加載它們
    //來自NSUserDefaults的User-Agent在PDF bah的DidFinishLoad以後的一段時間!
    NSDictionary* dict = [[NSDictionary alloc] initWithObjectsAndKeys:value, @"UserAgent", nil];
    [[NSUserDefaults standardUserDefaults] registerDefaults:dict];
}
複製代碼

經過設置NSUserDefaults中UserAgent的值來修改,可是這種設置方法有一個限制,須要在UIWebView的loadRequest以前調用才能生效(加載PDF比較特殊)。這是Cordova源碼中關於這個問題的描述。

- (NSString*)userAgent
{
    if (_userAgent != nil) {
        return _userAgent;
    }

    //省略部分源代碼
    _userAgent = [NSString stringWithFormat:@"%@ %@", _userAgent, @"[AWV/v1.0.0;AD/iOS]"];
    
    return _userAgent;
}
複製代碼

Cordova框架內提供對瀏覽器userAgent的設置相關代碼,平臺內對userAgent作了一些定製化的內容,好比自定義了userAgent參數,這裏的userAgent實際上就是提供給上面cordova-dynamic-loading.js文件進行解析使用的。實際上經過Cordova源碼能夠看到還有一些包括對userAgent的釋放等其餘操做,這裏不作具體分析。關於CDVUserAgentUtil能夠參考Cordova源碼解析(二)- 自定義UserAgent

實際上平臺在js部分深度集成作了什麼?

  • 1.對三方系統提供cordova-dynamic-loading.js文件,用於檢查cordova環境。

  • 2.提供pm-cordova.js文件用與對js橋封裝。

  • 3.提供pmCordova.platform.ready(其實是對外提供的一個插件)函數,因爲cordova插件異步進行加載和初始化,用於保證安全調用。

  • 4.提供高級配置,三方系統可按照本身的需求對插件進行配置,減小須要加載的plugin,提升性能。

  • 5.提供pm-cordova-mock.js文件,用於本地開發業務進行測試使用。

提供「離線包」策略,進行構建微應用

爲何要提供離線包,前言也有說明,這裏再詳細說一下:

  • 1.儘可能使容器內H5接近native體驗,將HTML,JabaScript,CSS壓縮爲離線包動態下發。

  • 2.減小網絡環境對H5應用的影響。

  • 3.提高打開H5的速度,減小白屏渲染時間。

  • 4.實現微應用的動態更新。

經過應用管理平臺,發佈應用時會配置相應的版本號等信息,客戶端啓動後會後臺比對版本等信息,檢查應用是否須要更新等。關於離線包策略,爲了防止用戶阻塞,服務器會部署一套徹底同樣的代碼,在離線包沒有下載好的狀況下,客戶端會先去加載服務端的代碼,待下次進入該應用的時候加載本地離線包內的代碼,這一塊的處理和前幾天看到支付寶移動端動態化方案實踐有些類似。

離線包統一由打包平臺一鍵打包發佈,從代碼獲取到壓縮,到生成zip包,再到發佈一鼓作氣,並相應的對版本號進行遞增,目前平臺客戶端支持增量更新和全量更新,增量更新能夠更節省流量,更新速度更快。全量更新能夠保證版本更穩定,安全性更高。基於此,平臺客戶端實現了應用的動態發佈與更新以及線上bug的修復,不須要再從新打包發佈。

那麼離線包功能客戶端作了什麼

  • 1.提供離線包安裝路徑:

客戶端經過不一樣應用的應用id擴展不一樣的應用安裝路徑,用於應用的安裝和打開。 實際上在客戶端最終會有這樣的目錄結構:

  • 2.改造Cordova默認加載路徑,指定爲上圖中的目標路徑:
- (NSURL*)appUrl
{
    //省略了一部分代碼
    NSURL* appURL = nil;
    if ([self.startPage rangeOfString:@"://"].location != NSNotFound) {
    } else if ([self.wwwFolderName rangeOfString:@"://"].location != NSNotFound) {
    } else if([self.wwwFolderName hasSuffix:@".bundle"]){
    } else {
        // CB-3005 strip parameters from start page to check if page exists in resources
        NSURL* startURL = [NSURL URLWithString:self.startPage];
        NSString* startFilePath = [self.commandDelegate pathForResource:[startURL path]];
    }
    
    return appURL;
}
複製代碼

主要作的工做所有在NSString* startFilePath = [self.commandDelegate pathForResource:[startURL path]];內實現,這行代碼會生成咱們預設好的目錄文件路徑。 Cordova內部實際上默認加載的路徑爲bundle,須要修改成咱們指定的沙盒路徑而後去加載沙盒裏面相應的微應用進行UI展現。

提供三方受權服務,進行微應用的單點登陸

應用有了,也提供了離線包策略,那麼三方應用怎麼登陸平臺?基於這個需求咱們提供了Oauth2服務,進行三方登陸受權。這部分不在web容器範疇內,後續會具體分析。

注:以上工做的實現以及web容器優化方案來源於民生辦公開發團隊。

相關文章
相關標籤/搜索