1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Native地圖與Web融合技術(shù)的應(yīng)用與實(shí)踐

        共 7492字,需瀏覽 15分鐘

         ·

        2021-04-27 01:09


        有用戶反饋美團(tuán)打車地圖的性能有一些問題,美團(tuán)打車技術(shù)團(tuán)隊(duì)在調(diào)研分析之后,采用了一套Native地圖與Web的融合框架,不僅實(shí)現(xiàn)了用戶手勢(shì)事件智能分發(fā)的機(jī)制,還解決了WebView與Native地圖在同一頁面內(nèi)布局困難的問題,同時(shí)性能也得到全面的優(yōu)化。本文系融合技術(shù)的經(jīng)驗(yàn)總結(jié)與分享。

        1. 背景

        美團(tuán)打車業(yè)務(wù)很早就在美團(tuán)App與點(diǎn)評(píng)App中提供了服務(wù)入口,并在技術(shù)上采用了H5與Native的混合開發(fā)技術(shù)。隨著業(yè)務(wù)上線,有用戶反饋我們的地圖性能有一些問題,原因是我們打車地圖使用的是Web版的地圖(通過騰訊地圖JavaScript API),業(yè)內(nèi)同類產(chǎn)品使用的是Native版的地圖SDK,Native地圖相比Web地圖具有天然的性能優(yōu)勢(shì),所以美團(tuán)打車地圖從首屏地圖加載到后續(xù)的地圖操作體驗(yàn)都有一定差距。

        1.1 問題與挑戰(zhàn)

        為了改善打車業(yè)務(wù)的地圖體驗(yàn),我們想到的方案是在展示地圖的部分使用Native地圖,而非地圖部分使用H5頁面來顯示,這樣既能追平與競(jìng)品的地圖性能差距,又能充分發(fā)揮H5的開發(fā)效率。

        這種方案乍一看似乎是傳統(tǒng)的Hybrid開發(fā),沒什么難度與新奇。比如地圖使用預(yù)先內(nèi)置到App中的地圖SDK實(shí)現(xiàn),H5與Native的交互使用業(yè)界成熟的JSBridge技術(shù)。但從打車業(yè)務(wù)角度來看,因?yàn)榇蜍嚇I(yè)務(wù)有很多功能入口需要漂浮在地圖之上,如起終點(diǎn)卡片、用戶中心入口等,這種漂浮功能在技術(shù)上并不容易實(shí)現(xiàn),而且還要保證用戶觸摸動(dòng)作在漂浮元素與地圖上發(fā)生時(shí),分別派發(fā)給各自的事件系統(tǒng),Hybrid技術(shù)在這方面沒有經(jīng)驗(yàn)可以借鑒。

        帶著這些挑戰(zhàn),我們進(jìn)行一系列的嘗試與試驗(yàn),最終將問題解決并封裝出我們打車業(yè)務(wù)的地圖調(diào)用框架,我們稱之為Native地圖與Web融合框架(下文簡(jiǎn)稱融合框架)。在這個(gè)過程中,我們總結(jié)出了一些經(jīng)驗(yàn),希望能給從事相關(guān)研究的同學(xué)帶來一些幫助。

        1.2 融合框架上線前后的對(duì)比

        其實(shí),融合框架已經(jīng)在大眾點(diǎn)評(píng)App中上線了幾個(gè)月的時(shí)間了,我們可以先看看上線前后的效果對(duì)比。

        優(yōu)化前,未使用融合框架時(shí):

        優(yōu)化后,使用了融合框架:

        可以清晰地觀察到,使用融合框架掃碼后,地圖瞬間展示出來,相比Web地圖減少了漫長(zhǎng)的白屏?xí)r間。

        2. 調(diào)研

        基于混合技術(shù)開發(fā)體系,我們研究了市面上大部分H5頁面與Native地圖的應(yīng)用場(chǎng)景,主要分為如下兩類:

        • H5頁面與Native地圖分別是2個(gè)獨(dú)立的頁面:H5業(yè)務(wù)邏輯用到地圖時(shí)候,通過交互技術(shù)打開一個(gè)新地圖頁面,在新頁面內(nèi),Native地圖按照傳入?yún)?shù)調(diào)用對(duì)應(yīng)地圖組件,完成業(yè)務(wù)功能的展示。

        • H5頁面與Native地圖位于同一頁面內(nèi):兩者將屏幕分割為兩部分,如下圖所示:Native地圖位于上半部分,WebView H5頁面位于下半部分。

        經(jīng)過分析后,我們發(fā)現(xiàn)這兩種形式都無法滿足打車業(yè)務(wù)場(chǎng)景的需求,因?yàn)槟壳笆忻嫔现髁鞯拇蜍嚇I(yè)務(wù)場(chǎng)景由4部分構(gòu)成,如下圖所示:

        • 起終點(diǎn)選擇面板:占據(jù)頁面下半部分,可以上下滑動(dòng)露出更多內(nèi)容。
        • 地圖部分:頁面上半部分,顯示起終點(diǎn)、線路等地圖要素信息。
        • 更多菜單:左上角圖標(biāo),點(diǎn)擊后跳轉(zhuǎn)到H5功能菜單頁面。
        • 廣告入口:右上角圖標(biāo),點(diǎn)擊后跳轉(zhuǎn)到H5運(yùn)營(yíng)頁面。

        上文第一類,H5頁面與Native地圖分別位于兩個(gè)獨(dú)立頁面中,只能滿足部分地圖場(chǎng)景的需求,無法布局為上圖H5與地圖同框顯示的效果。

        上文第二類,實(shí)現(xiàn)這樣的布局需要多個(gè)WebView才能實(shí)現(xiàn),存在如下缺點(diǎn):

        • 下方WebView與上方Native地圖是平級(jí)的組件,各占屏幕的一半,相互間不存在壓蓋關(guān)系,實(shí)現(xiàn)起終點(diǎn)面板上下滑動(dòng)效果困難。
        • 左上角、右上角的更多菜單,廣告入口位置需要新增2個(gè)WebView組件才能實(shí)現(xiàn)覆蓋在地圖之上,WebView組件再加載對(duì)應(yīng)H5頁面實(shí)現(xiàn)上述布局,整個(gè)步驟比較繁瑣。
        • 多個(gè)WebView組件構(gòu)成的頁面布局,由于內(nèi)存空間不共享,它們之間信息的同步比較困難,太多的WebView組件對(duì)系統(tǒng)性能也是一種浪費(fèi)。

        調(diào)研結(jié)論是:市面上現(xiàn)存技術(shù)都無法滿足打車場(chǎng)景的需求。

        全新方案的提出

        基于打車場(chǎng)景的特殊性,我們做了一個(gè)大膽的假設(shè):把頁面分為2層,下層是Native地圖層,布滿屏幕;上層是WebView層,完全覆蓋到Native地圖層之上,如下圖所示:

        我們期望的效果是:

        • 點(diǎn)擊H5元素時(shí),點(diǎn)擊事件會(huì)派發(fā)給H5 WebView容器處理。
        • 點(diǎn)擊地圖區(qū)域時(shí),點(diǎn)擊事件會(huì)派發(fā)給Native地圖組件處理。
        • H5與Native地圖間的信息交互,可采用成熟的JSBridge技術(shù)實(shí)現(xiàn)。

        具體實(shí)現(xiàn)思路有如下幾點(diǎn),參照下圖:

        • Native地圖位于下層,WebView置于Native地圖之上,WebView背景透明,透過WebView可以看到下邊的地圖。紅框區(qū)域是上層WebView打開的H5頁面元素。
        • 增加一個(gè)手勢(shì)消息分發(fā)層,該層會(huì)智能判斷手勢(shì)事件落在H5元素還是地圖元素中。舉例:點(diǎn)擊紅框區(qū)域,消息會(huì)傳遞到WebView層的H5邏輯處理,點(diǎn)擊紅框之外的區(qū)域,消息會(huì)傳遞到Native地圖層處理(地圖移動(dòng)、縮放等操作)。
        • H5與Native地圖交互使用JSBridge完成。比如在地圖中添加一個(gè)Marker,H5層業(yè)務(wù)邏輯發(fā)出添加Marker的消息,H5層通過JSBridge技術(shù)將消息發(fā)送到Native地圖層,Native地圖收到消息后在地圖中添加Marker元素。

        為了驗(yàn)證想法是否正確,我們首先通過Android平臺(tái)開發(fā)出Demo,驗(yàn)證這種分層智能傳遞消息的做法是可行的,該方案最大優(yōu)點(diǎn)是兼顧了H5的開發(fā)效率與Native地圖的高性能特性,非常符合美團(tuán)業(yè)務(wù)地圖場(chǎng)景的需求。為了讓想法落地時(shí)更規(guī)范、更系統(tǒng),我們進(jìn)行了如下的框架設(shè)計(jì)。

        3. 框架設(shè)計(jì)

        3.1 熱區(qū)數(shù)據(jù)介紹

        先介紹一個(gè)“熱區(qū)數(shù)據(jù)”的概念,下圖(3.2節(jié))在手勢(shì)分發(fā)層存在著消息分發(fā)熱區(qū)數(shù)據(jù)部分,下文簡(jiǎn)稱熱區(qū)數(shù)據(jù)。熱區(qū)數(shù)據(jù)是針對(duì)上層WebView的一個(gè)概念,只對(duì)WebView層有效,對(duì)下層Native地圖層無效。如果用戶點(diǎn)擊屏幕事件想讓H5來捕獲處理,可以在屏幕區(qū)域內(nèi)設(shè)置一個(gè)邏輯上的矩形區(qū)域,如:[0, 0,  50, 50](上圖左上角區(qū)域),這個(gè)數(shù)據(jù)被稱為熱區(qū)數(shù)據(jù)。

        我們通過編寫代碼邏輯,控制手勢(shì)消息分發(fā)的策略,如果手勢(shì)消息發(fā)生在熱區(qū)數(shù)據(jù)矩形范圍內(nèi),我們把消息發(fā)送給WebView處理,否則發(fā)送給Native地圖處理。如上圖所示,可以在同一屏幕內(nèi)設(shè)定多個(gè)熱區(qū),[0, 0,  50, 50]、[430, 0,  50, 50]、[0, 200,  480, 200],熱區(qū)的格式可以自己定義,我們這里采用的基于WebView組件左上角為原點(diǎn)的像素坐標(biāo)格式:[left, top, width, height]。

        3.2 框架圖介紹

        手勢(shì)消息分發(fā)給WebView層流程

        主要為上圖1-->2-->3-->4過程,如下:

        1. 用戶觸摸動(dòng)作首先被手勢(shì)分發(fā)層捕獲,手勢(shì)分發(fā)層判斷用戶點(diǎn)擊到熱區(qū)數(shù)據(jù)范圍內(nèi),將消息分發(fā)到WebView H5層處理。
        2. WebView H5層收到消息,對(duì)消息進(jìn)行處理(比如:在地圖中添加一個(gè)終點(diǎn)Marker),通過通訊橋?qū)⑾鬟f到Native地圖層。
        3. Native地圖層收到消息,并執(zhí)行添加Marker操作,完成后返回成功信息。上述總體流程為:手勢(shì)分發(fā)層-->1-->2-->3-->6-->7。

        手勢(shì)消息分發(fā)給Native地圖層流程

        主要為上圖5-->6-->7過程,如下:

        1. 手勢(shì)分發(fā)層捕獲到消息,發(fā)現(xiàn)用戶手勢(shì)與當(dāng)前熱區(qū)數(shù)據(jù)矩形沒有交集,于是將獲取的消息分發(fā)到Native地圖層。
        2. 如果消息是拖動(dòng)操作,則Native地圖自動(dòng)識(shí)別拖動(dòng)地圖消息,實(shí)現(xiàn)移動(dòng)地圖的效果,涉及流程為:手勢(shì)分發(fā)層-->5。
        3. 如果消息是點(diǎn)擊操作,比如我們想實(shí)現(xiàn)點(diǎn)擊地圖中的Marker,將消息傳遞給H5處理的功能。實(shí)現(xiàn)步驟為我們事先在添加Marker時(shí)增加一個(gè)點(diǎn)擊事件(Native地圖層實(shí)現(xiàn)),Marker被點(diǎn)擊時(shí)Native地圖層會(huì)派發(fā)此事件,事件消息會(huì)通過JSBridge技術(shù)從Native地圖層傳到H5層,最后H5層獲取到點(diǎn)擊消息。整個(gè)操作流程為:手勢(shì)分發(fā)層-->5-->6-->7。

        熱區(qū)數(shù)據(jù)的動(dòng)態(tài)更新策略

        因?yàn)榇蜍嚇I(yè)務(wù)底部的面板高度是可伸縮的,所以底部的熱區(qū)數(shù)據(jù)并不是靜止不動(dòng)的,需要考慮熱區(qū)數(shù)據(jù)也要隨著DOM元素的拉伸做同步調(diào)整??梢酝ㄟ^在WebView H5層監(jiān)控DOM的變化,DOM元素發(fā)生變化時(shí),獲取變化后的DOM元素位置、大小,格式化為熱區(qū)數(shù)據(jù),并更新到消息分發(fā)熱區(qū)數(shù)據(jù)部分。因?yàn)槔靹?dòng)作是一個(gè)連續(xù)的動(dòng)畫效果,為了高效,我們只在動(dòng)畫結(jié)束的那一刻更新熱區(qū)數(shù)據(jù),中間過渡期不做處理。此整體流程為:2-->3-->4。

        4. 點(diǎn)評(píng)App中的落地實(shí)踐

        4.1 手勢(shì)分發(fā)層關(guān)鍵代碼

        這部分功能需要Native端同學(xué)實(shí)現(xiàn),包括iOS與Android。兩端分別在啟動(dòng)App時(shí)設(shè)置三層內(nèi)容,最上層是手勢(shì)觸摸事件接收層,中間是WebView層(背景設(shè)置透明),最下層是Native地圖層(如騰訊地圖SDK)。用數(shù)組記錄當(dāng)前熱區(qū)數(shù)據(jù),當(dāng)手勢(shì)分發(fā)層有事件發(fā)生時(shí),通過Touch事件獲取手指位置信息,遍歷熱區(qū)數(shù)組判斷手指位置是否與熱區(qū)的矩形相交,如相交則將消息分發(fā)給WebView層,否則分發(fā)給Native層。下邊是Android與iOS消息分發(fā)關(guān)鍵代碼:

        Android分發(fā)層關(guān)鍵代碼
        @Override
        public boolean dispatchTouchEvent(MotionEvent event){
          if(event.getAction() == MotionEvent.ACTION_DOWN) {
            // 分發(fā)層接收到手勢(shì)觸摸消息,通過dispatchService類判斷手勢(shì)是否落在熱區(qū)內(nèi),從而確定消息分發(fā)的對(duì)象
            this.touchHandler = dispatchService.inRegion(event) ? TouchHandler.WebView : TouchHandler.MapView;
          }
          // 分發(fā)給Native地圖層
          if(this.touchHandler == TouchHandler.MapView) {
            return this.mapView.dispatchTouchEvent(event);
          }
          // 分發(fā)給WebView H5層
          return super.dispatchTouchEvent(event);
        }
        iOS分發(fā)層關(guān)鍵代碼
        - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
           UIView *hitTestView = nil;
           // 分發(fā)層接收到手勢(shì)觸摸消息,通過pointInHotspot判斷手勢(shì)是否落在熱區(qū)內(nèi),從而確定消息分發(fā)的對(duì)象
           if ([self pointInHotspot:point]) {
             // 分發(fā)給WebView H5層
             hitTestView = [self.WebView hitTest:point withEvent:event];
           }else{
             // 分發(fā)給Native地圖層
             hitTestView = [self.mapView hitTest:point withEvent:event];
           }
           return hitTestView;
        }

        4.2 WebView H5層

        該層有2個(gè)功能:

        • 提供設(shè)置熱區(qū)的JS接口setHotRegion,業(yè)務(wù)可通過此接口設(shè)置屏幕中的熱區(qū)。
        • 封裝一層JS形式的地圖接口,為上層業(yè)務(wù)提供地圖服務(wù),該層借助JSBridge通訊橋?qū)崿F(xiàn)H5與Native層的異步通訊。


        4.3 通訊橋簡(jiǎn)介

        通訊橋即JSBridge技術(shù),主要實(shí)現(xiàn)H5與Native的信息交互,這方面的技術(shù)都已比較成熟,業(yè)界有非常多的JSBridge實(shí)現(xiàn),原理也都類似,常見的有:原生對(duì)象注入到H5層、URL攔截技術(shù),Native調(diào)用JS常用的內(nèi)置函數(shù)stringByEvaluatingJavaScriptFromString等。美團(tuán)內(nèi)部有比較成熟的KNB框架,所以項(xiàng)目中直接使用了KNB框架。

        4.4 Native地圖層

        該層在地圖SDK(如騰訊地圖SDK)基礎(chǔ)上進(jìn)行了封裝,提供一些打車業(yè)務(wù)友好的接口,如地圖基本操作、打車起終點(diǎn)Marker添加、接送駕司機(jī)小車動(dòng)畫、地圖事件、各種Marker的信息彈窗等。

        4.5 Dom元素?zé)釁^(qū)數(shù)據(jù)的自動(dòng)維護(hù)技術(shù)

        打車業(yè)務(wù)前端的技術(shù)棧是: Vue + VueX + Vue-Router構(gòu)建的單頁系統(tǒng)。如下圖所示,頁面中存在很多H5元素需要添加熱區(qū),逐個(gè)元素編寫代碼添加的話會(huì)很繁瑣,而且頁面元素的位置、大小變化時(shí)還需要同步更新熱區(qū)數(shù)據(jù),這里我們使用了Vue中的directive(指令)來解決了此問題。

        以上左右2圖是用戶操作時(shí)頁面展示的不同狀態(tài),很明顯右圖底部卡片變高了,卡片變化同時(shí)需要同步更新對(duì)應(yīng)的熱區(qū)數(shù)據(jù),directive技術(shù)可以很方便解決此問題,原理如下:

        • 在添加元素時(shí),Vue指令的bind鉤子函數(shù)被觸發(fā),此時(shí)計(jì)算出彈窗元素的大小和位置:使用getBoundingClientRect函數(shù)可以獲取到元素的left、top、width、height等信息,將新的熱區(qū)數(shù)據(jù)通過setHotRegion函數(shù)更新到手勢(shì)分發(fā)層。
        • 在移除元素時(shí),unbind鉤子函數(shù)被觸發(fā),此時(shí)將熱區(qū)數(shù)據(jù)移除,這樣便實(shí)現(xiàn)了熱區(qū)的自動(dòng)添加刪除功能了。
        • 使用指令技術(shù)很簡(jiǎn)捷,編寫好指令的邏輯后注冊(cè)到全局,在需要?jiǎng)討B(tài)更新熱區(qū)的元素上設(shè)置個(gè)v-hotRegion標(biāo)簽就可以了。

        4.6 調(diào)試工具及測(cè)試

        調(diào)試工具使用模擬器、真機(jī)都可以,開發(fā)期間我們使用的模擬器開發(fā),測(cè)試期間QA使用真機(jī)驗(yàn)證。調(diào)試過程中主要驗(yàn)證2部分功能,分別是熱區(qū)的驗(yàn)證與地圖接口驗(yàn)證。

        熱區(qū)驗(yàn)證

        主要驗(yàn)證主頁面設(shè)置的熱區(qū)是否正確,包括是否可以點(diǎn)擊、底部卡片是否能正常拖拉、業(yè)務(wù)功能是否正常等。因?yàn)闊釁^(qū)數(shù)據(jù)是一串?dāng)?shù)字,形如:[0, 0,  50, 50],無法直觀判斷出該數(shù)據(jù)是否有誤,于是我們開發(fā)了一個(gè)可視化工具,將設(shè)置熱區(qū)的元素都用紅色矩形高亮顯示,如下圖所示,這樣就能快速診斷出熱區(qū)數(shù)據(jù)是否有異常。工具是使用Canvas畫布實(shí)現(xiàn)的,畫布大小與屏幕大小完全重合,借助畫布就可以將矩形熱區(qū)數(shù)據(jù)在屏幕中實(shí)時(shí)繪制出來。

        地圖接口驗(yàn)證

        主要是編寫單元測(cè)試完成的,本項(xiàng)目封裝了50多個(gè)地圖接口,每個(gè)接口都編寫單測(cè)用例,觀察入?yún)?、出參、控制臺(tái)輸出結(jié)果,地圖展示效果是否正確等。測(cè)試主要在iOS模擬器中完成,這樣方便在控制臺(tái)打印一些調(diào)試信息進(jìn)行診斷。

        5. 上線效果

        該框架在大眾點(diǎn)評(píng)App中上線后地圖體驗(yàn)明顯提升,主要有體現(xiàn)在以下幾個(gè)方面:
        • 地圖的操作體驗(yàn),如地圖移動(dòng)、縮放明顯好于H5地圖,用戶利用Native地圖選擇起終點(diǎn)、下單叫車、接送駕小車動(dòng)畫效果更加流暢。
        • 首屏地圖數(shù)據(jù)指標(biāo)也有顯著提升,如下表所示:
        • 目前線上運(yùn)行穩(wěn)定,上線2月期間,Crash數(shù)量為個(gè)位數(shù),Crash率遠(yuǎn)低于0.1‰。
        • 框架上線后,大眾點(diǎn)評(píng)App中業(yè)務(wù)迭代可以按照H5節(jié)奏上線,實(shí)現(xiàn)隨時(shí)發(fā)版的開發(fā)效率。

        Native地圖層代碼接口穩(wěn)定、功能豐富,基本滿足地圖場(chǎng)景的業(yè)務(wù)需求。只需首次跟版發(fā)布,后續(xù)只需要迭代H5的業(yè)務(wù)邏輯即可。

        6. 本文小結(jié)

        本文將WebView與Native地圖組件疊加到一起,實(shí)現(xiàn)了用戶手勢(shì)事件智能分發(fā)的機(jī)制,解決了WebView與Native地圖在同一頁面內(nèi)布局困難的問題。這種融合機(jī)制為打車業(yè)務(wù)提升迭代效率同時(shí)保障地圖體驗(yàn)提供了一種有效的途徑,日常業(yè)務(wù)功能上線采用H5技術(shù)迭代,Native地圖作為不常更新的基礎(chǔ)能力首次發(fā)版時(shí)安裝到用戶手機(jī)上,實(shí)現(xiàn)業(yè)務(wù)需求隨時(shí)發(fā)版的能力,不再受各大應(yīng)用商店的限制,用戶操作地圖的體驗(yàn)也更加流暢。該融合框架適合以下業(yè)務(wù)場(chǎng)景:

        • 業(yè)務(wù)中使用了地圖功能,并對(duì)地圖的加載、操作體驗(yàn)等有較高要求的業(yè)務(wù)。

        • 業(yè)務(wù)屬于Hybrid業(yè)務(wù),并且H5頁面與地圖在同一頁面內(nèi)布局的功能。

        • 如果你的業(yè)務(wù)是基于多個(gè)WebView與Native地圖構(gòu)建的系統(tǒng),非常建議你了解下此文章。

        7. 作者簡(jiǎn)介

        美團(tuán)打車技術(shù)部終端研發(fā)中心,加鵬、張斌、楊睿、邱博、海峰等。

        ----------  END  ----------

        招聘信息


        快手商業(yè)化招聘前端,高級(jí)工程師、前端專家崗位都有名額,詳情請(qǐng)看【前端招聘】快手商業(yè)化。感興趣的同學(xué)可投遞簡(jiǎn)歷至:[email protected],或者私聊號(hào)主wx:qq1248351595

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

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            大香蕉伊思人在线 | 红桃视频一区 | 超碰大香蕉97 | 成人影视久久久无码三区 | 日韩三级理论片 | 狠狠狠狠操 | 日韩人妻精品无码 | 99re在线视频观看精品观看 | 老挝一级婬片A片AAA电影 | 精品国产乱码久久久久久软件影片 |