<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          貨拉拉 Android H5離線包原理與實(shí)踐

          共 4833字,需瀏覽 10分鐘

           ·

          2022-07-26 23:32

          點(diǎn)擊上方藍(lán)字關(guān)注我,知識(shí)會(huì)給你力量


          背景

          在實(shí)際業(yè)務(wù)中,app中的H5頁(yè)面使用的場(chǎng)景越來越多,在貨拉拉app中也存在大量的H5頁(yè)面,比如金秋拉貨節(jié)、余額、車型介紹頁(yè)等,加載速度成為了困擾用戶的一個(gè)痛點(diǎn)。為此我們決定引入離線包方案,另外還需要解決傳統(tǒng)離線包方案不靈活,體積大,不易管理,不易降級(jí)等問題,我們?cè)O(shè)計(jì)和開發(fā)一套H5離線包系統(tǒng),經(jīng)過幾個(gè)sdk版本的迭代,目前貨拉拉H5離線包sdk,已在多個(gè)業(yè)務(wù)中落地,接受了大量用戶檢驗(yàn)。車型介紹頁(yè)面使用離線包前后打開效果:

          行業(yè)方案

          目前H5離線包方案,通常是將離線包置入assets目錄中,打包在apk內(nèi)部,用戶使用過程中再按需加載。所以大部分情況下可能存在以下問題:

          1. 由于離線包內(nèi)容固定導(dǎo)致更新不及時(shí)
          2. 當(dāng)離線包內(nèi)容較多或者離線包個(gè)數(shù)較多時(shí),會(huì)嚴(yán)重影響App包體積
          3. 由于離線包內(nèi)部的邏輯固定,當(dāng)出現(xiàn)問題時(shí)無法降級(jí),無法禁用
          4. 上線沒有數(shù)據(jù)對(duì)比無法知道上線效果

          針對(duì)以上痛點(diǎn),我們團(tuán)隊(duì)對(duì)離線包進(jìn)行設(shè)計(jì)優(yōu)化,應(yīng)用于團(tuán)隊(duì)內(nèi)的多個(gè)應(yīng)用,多個(gè)業(yè)務(wù)場(chǎng)景中。

          技術(shù)實(shí)現(xiàn)

          H5離線包的基本原理是將html、js、css、圖片等靜態(tài)資源打包到成壓縮文件,然后下載到客戶端,H5加載時(shí)靜態(tài)資源直接從本地取文件,減少網(wǎng)絡(luò)請(qǐng)求,提高速度。加載本地文件路徑存在的問題和解決:

          存在問題解決方法
          cgi請(qǐng)求跨域跨域請(qǐng)求頭增加null支持
          cookie跨域問題目前靜態(tài)js中無cookie操作,沒有cookie跨域問題
          localstorage跨域問題暫時(shí)不涉及域名隔離問題,如果有需要,采取調(diào)用原生的方式解決
          前端使用絕對(duì)路徑問題相對(duì)路徑

          4.1 總體結(jié)構(gòu)

          H5發(fā)布基本流程

          image.png

          App端流程圖

          image.png

          前端的打包平臺(tái),支持發(fā)布為線上頁(yè)面,也支持發(fā)布為離線包。離線包模式時(shí),客戶端會(huì)先查詢是否有離線包需要更新,有則更新,同時(shí)支持離線包降級(jí)為線上網(wǎng)頁(yè)。

          H5離線包和線上H5一樣也能進(jìn)行更新和升級(jí),有三個(gè)更新時(shí)機(jī):

          1)WebView容器打開時(shí)更新。在需要開啟離線包功能的H5頁(yè)面打開時(shí),會(huì)去后端檢查對(duì)應(yīng)的離線包頁(yè)面是否有更新。如果有更新,則下載離線包到本地,絕大部分場(chǎng)景是下次打開時(shí)生效。

          2)啟動(dòng)查詢離線包更新。對(duì)于實(shí)時(shí)性要求比較高的頁(yè)面,可配置在啟動(dòng)時(shí)檢查更新。

          3)通過長(zhǎng)連接推送的方式通知客戶端下載最新的離線包。(需要接入方自己實(shí)現(xiàn)長(zhǎng)鏈接,調(diào)用SDK更新方法)

          4.2 性能優(yōu)化

          1)多業(yè)務(wù)并行化,單業(yè)務(wù)串行

          離線包檢查更新時(shí),存在同時(shí)查詢多個(gè)業(yè)務(wù)的離線包是否有更新的情況,為了提高查詢效率,多個(gè)業(yè)務(wù)離線包檢查的請(qǐng)求采取并行請(qǐng)求的方式。考慮到后端改造成本問題,目前還不支持聚合查詢,計(jì)劃在后續(xù)版本中完善。另外,考慮業(yè)務(wù)流程的更新流程取消可能導(dǎo)致不穩(wěn)定,單業(yè)務(wù)只做串行,避免過程中文件損壞,下載不全,線程并發(fā)的問題。

          image.png

          2)啟動(dòng)預(yù)下載

          大部分離線包查詢和下載的時(shí)機(jī)為打開H5頁(yè)面時(shí),由于離線包查詢、下載、解壓總體耗時(shí)較長(zhǎng),導(dǎo)致首次打開無法命中離線包。所以貨拉拉離線包支持配置部分離線包在啟動(dòng)時(shí)檢查和下載離線包。配置為:

          OfflineConfig offlineConfig = new OfflineConfig.Builder(true)

                  .addPreDownload("offline-pkg-name")//預(yù)加載業(yè)務(wù)名稱

                  .build();,

          4.3 可靠性設(shè)計(jì)

          1)解壓操作可靠性設(shè)計(jì)

          文件解壓耗時(shí)較長(zhǎng)(大約30ms),如果中間程序退出可能會(huì)導(dǎo)致只解壓了其中一半文件,影響后續(xù)離線包邏輯。所以解壓到文件夾操作采取先解壓,然后重命名,保證最后的文件夾的里的文件是完整的。同時(shí)當(dāng)離線包正在使用時(shí),一般情況下采取先解壓,下次生效的策略,極端情況下可以立刻生效,但會(huì)導(dǎo)致頁(yè)面強(qiáng)刷,影響用戶體驗(yàn)。操作過程采取了temp、new、cur三個(gè)文件夾,解壓細(xì)節(jié)如下

          image.png

          2)三重降級(jí)策略

          a.客戶端自動(dòng)降級(jí)。

          本地沒有離線包時(shí),客戶端會(huì)自動(dòng)將啟用了離線包的H5頁(yè)面降級(jí)為線上H5頁(yè)面。

          b.客戶端遠(yuǎn)程配置降級(jí)。

          可以設(shè)置局部降級(jí),即臨時(shí)將某個(gè)使用離線包的H5頁(yè)面降級(jí)為線上,也可設(shè)置全局降級(jí),關(guān)閉所有頁(yè)面的離線包功能。接入方可以自行根據(jù)自己服務(wù)端下發(fā)參數(shù)進(jìn)行配置:

          OfflineConfig offlineConfig = new OfflineConfig.Builder(true)//總開關(guān)

                  .addDisable("disable-offline-pkg-name")//禁用業(yè)務(wù)名稱

                  .addPreDownload("offline-pkg-name")//預(yù)加載業(yè)務(wù)名稱

                  .build();

          c.服務(wù)端接口降級(jí)。

          服務(wù)端提供的離線包查詢接口也可以設(shè)置將某個(gè)頁(yè)面降級(jí)為線上H5,也可以支持讓客戶端更新離線包后強(qiáng)制刷新。目前,強(qiáng)制刷新為空實(shí)現(xiàn),需要接入方自己實(shí)現(xiàn),例如重啟當(dāng)前頁(yè)面,關(guān)閉當(dāng)前頁(yè)面等。

          降級(jí)策略流程圖如下:

          image.png

          3)性能監(jiān)控

          貨拉拉對(duì)webview的加載成功率,錯(cuò)誤碼、耗時(shí)進(jìn)行了統(tǒng)計(jì)上報(bào),通過監(jiān)控面板查看。

          此外離線包sdk還有離線包下載,請(qǐng)求,解壓的耗時(shí)、結(jié)果數(shù)據(jù)上報(bào)。監(jiān)控和上報(bào)采取的接口擴(kuò)展方式,接入方根據(jù)業(yè)務(wù)特點(diǎn)選用具體的數(shù)據(jù)上報(bào)sdk。

          4.4 效能優(yōu)化

          離線包和URL映射配置化

          image.png

          配置格式如下:主要通過url中的host、path、Fragment配置命中規(guī)則。根據(jù)接入方是否需要傳入,不需要可以不傳遞。

          //匹配規(guī)則相關(guān) 可選

          ArrayList<String> host = new ArrayList<>();

          ArrayList<String> path = new ArrayList<>();

          ArrayList<String> fragment = new ArrayList<>();

          host.add("www.xxxx.cn");

          path.add("/aaa");

          fragment.add("/ccc=ddd");



          OfflineRuleConfig offlineRuleConfig = new OfflineRuleConfig();

          offlineRuleConfig.addRule(new OfflineRuleConfig.RulesInfo("offline-pkg-name",host,path,fragment));


          new OfflineParams()

                  .addRule("offline-pkg-name",host,path,fragment)//自定義配置的形式

                  .setRule(Constants.RULE_CONFIG)//json形式的規(guī)則

                  .setRule(offlineRuleConfig)//實(shí)體類形式
          {
              "rules": [{
                      "host": ["test1.xxx.cn""test2.xxx.cn"],
                      "path": ["/pathA"],
                      "offweb""offline-pkg-name-a"
                  },
                  {
                      "host": ["www.aaa.cn""aaa.xxxx.cn"],
                      "path": ["aaa/path""bbb/path"],
                      "offweb""offline-pkg-name-b"
                  }
              ]
          }

          總結(jié)

          離線包上線后,收益明顯,平均加載速度從2秒提升到1秒,同時(shí)H5頁(yè)面加載成功率也有提升。頁(yè)面主框架(不考慮動(dòng)態(tài)數(shù)據(jù))加載成功率從96%提升到100%。

          后期工作與展望

          擴(kuò)大開源范圍。比如支持?jǐn)帱c(diǎn)續(xù)傳的下載SDK,后續(xù)會(huì)考慮開源。離線包依賴的后端服務(wù)暫時(shí)未開源,目前采取是通過HttpServer搭建一個(gè)簡(jiǎn)單的本地Web Server,可保證離線包示例在本地正常運(yùn)行。

          具體使用方法參考開源代碼中介紹(https://github.com/HuolalaTech/HLLOfflineWebView-android )

          參考資料

          https://zhuanlan.zhihu.com/p/34125968

          https://juejin.cn/post/6844903934004297736

          作者介紹

          貨拉拉移動(dòng)端技術(shù)團(tuán)隊(duì)

          向大家推薦下我的網(wǎng)站 https://xuyisheng.top/  點(diǎn)擊原文一鍵直達(dá)

          專注 Android-Kotlin-Flutter 歡迎大家訪問



          往期推薦


          本文原創(chuàng)公眾號(hào):群英傳,授權(quán)轉(zhuǎn)載請(qǐng)聯(lián)系微信(Tomcat_xu),授權(quán)后,請(qǐng)?jiān)谠瓌?chuàng)發(fā)表24小時(shí)后轉(zhuǎn)載。
          < END >
          作者:徐宜生

          更文不易,點(diǎn)個(gè)“三連”支持一下??


          瀏覽 69
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  伊人婷婷五月 | 国产视频性高潮 | 综合网操笔 | 69精品又硬又爽又粗少妇 | 一区二区三区在线 | 欧 |