淺談混合應用的演進

前端想要寫 APP

開篇想以這樣的方式開頭,從 APP 開始火到如今,前端同窗就一直想要寫 APP,各方技術也是爲了讓前端同窗寫上 APP 操碎了心。javascript

爲何要前端同窗來寫 APP,站在整個技術鏈上來看,都是在作頁面呈現,頁面交互,對於技術而言只是將產品在不一樣的端上進行呈現,因此很早以前就有提倡說大前端的概念。既然功能都差很少,就沒有分家的理由。前端

再者,開發客戶端如今的常規平臺有 iOS 和 android 兩個大的平臺,在前端領域愈來愈細分的大環境下,傳統意義上的客戶端開發至少須要兩撥開發者來作,成本就會有增長。而且伴隨着成本增長還帶來了須要兩套體系化的語言開發,開發效率也會大打折扣。相較於兩大客戶端平臺的開發人員,前端的開發人員是要更多的,而且隨着移動端的興起前端開發者會有資源剩餘的狀況,前端來寫 APP 也能夠平衡資源。java

因此不只僅是前端同窗想要來寫 APP,更多的是將來發展須要這樣的技術來提升生產力,因此纔會有各類各樣的方案出現,各類方案的誕生也發現了前端寫 APP 的不足,因此又有了不斷的演進來適應將來發展。送給每個前端人,咱們的征途是星辰大海android

web APP

就是咱們常說的 h5 應用,這個階段屬於知足展現功能階段,首先是解決手機端能展現頁面的問題。git

實現方式就是客戶端提供 webView 組件,就是一個基於 webkit 引擎、展示 web 頁面的控件。web APP 實際上就是客戶端提供了一個瀏覽器的宿主環境,能在手機上顯示對應的網頁內容,可是各大手機廠商對於內核都會有所謂的「優化」,這些所謂的優化或者內核版本升級所帶來的兼容性問題,也是讓前端同窗咬牙切齒。github

客戶端提供了相似瀏覽器的宿主環境,前端將本身的 HTML/CSS/JS 運行起來,就能夠看到頁面了。可是在 PC 端原來咱們看到的頁面放在手機上,展現和交互都不太合適。之因此咱們要叫 h5 應用,是說咱們在移動端上須要用到 HTML5/CSS3 的新功能,經過這些功能能在客戶端的瀏覽器上作適配展現頁面。web

響應式的佈局方式,新式的 meta 標籤,媒體查詢等功能讓前端之前顯示在 PC 端上的頁面能展現在手機端。隨着 PWA 的出現,如今手機端逐漸對 Service Worker 的支持(Safari 還在躊躇猶豫),web APP 又從新煥發了青春。ajax

優勢:chrome

  • 基於 webView 的跨平臺,調試方便(控制檯調試)
  • 開發速度快,只要有瀏覽器就能打開,適合小版本的試錯
  • 無需安裝,不佔內存,隨時更新,維護成本低

缺點:json

  • 打開白屏時間長,用戶體驗較差,交互功能受限。
  • 產品也受限於瀏覽器,而且留存低,適合拉新
  • 不採用 PWA 的方案就沒法離線,沒有網絡就失去了活力,如今不用網絡的 APP 狀況已經不多了。重複打開重複加載

表明產品:

  • 全部可使用手機瀏覽器打開的網頁(不作兼容展現會有問題)
  • 微信公衆號裏純文章

hybrid 應用

跨過了 web APP 的知足展現功能階段,這個時候開始想有更多的功能知足交互需求,好比調起原生的攝像頭(雖然 input 也能夠實現),這個時候催生了 hybrid APP,也進入了豐富功能階段。

前端 webView 的交互實現沒法直接與攝像頭的 API 進行交互,相似這樣的功能是客戶端的能力,webView 想要完成這樣的功能,若是不能直接完成是否是能夠經過調用客戶端來完成這樣的功能,可是前端和客戶端是兩種不一樣的語言及實現方式,如何進行通訊?

想要通訊完成通訊,其實就是須要再前端與和客戶端搭建一個溝通橋樑,就是如今常說的 js bridge。介紹擊中常見的 js bridge 通訊方式。

js bridge

js 調用 native:

  • 請求攔截
  • 彈窗攔截
  • 注入 js 方法

native 調用 js:

  • 直接執行 js 代碼

請求攔截

webView 發送請求都會通過客戶端的請求發送模塊,客戶端能夠在請求發送出去以前作攔截,你們約定好一種 URI 的實現協議,若是符合實現協議的請求,就攔截下來進行約定協議解析,其餘的就當作真正的請求發送出去。

首先約定一個簡單的協議

eros://bmImage/camera?params={"imageNum":2,"allowCrop":true,"callbackId":"bmImage.camera1527235458519"}

eros            // 做爲協議存在,用於作攔截的方式
bmImage/camera  // 用於約定是調用客戶端的方法名,能夠是想要調用相機上傳兩種圖片的接口
params          // query 表示參數,其中有一個參數名叫 params 的參數是一個 json,是調用客戶端的方法所須要的三個參數
複製代碼

無論 js 如何封裝,就是須要發送一個請求出去,最好前端能作統一封裝經過 iframe 或者直接經過 ajax 發送請求。

客戶端如何攔截

android 的攔截方式 shouldOverrideUrlLoading

@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
    // 根據協議判斷是否須要攔截
    if (true){
      // 解析協議路徑得知調用方法
      // 解析 query 獲得參數
      // 經過反射的方式去調用對應的原生方法
      return true;
    }
    return super.shouldOverrideUrlLoading(view, url);
}
複製代碼

iOS 的攔截方式(UIWebView) webView:shouldStartLoadWithRequest:navigationType:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    // 根據協議判斷是否須要攔截
    if (true){
        // 解析協議路徑得知調用方法
        // 解析 query 獲得參數
        // 經過 AOP 的方式去調用去調用對應的原生方法
        return NO;
    }
    return YES;
}
複製代碼

上述過程就完成了 js 向 native 的通訊的一種方式,客戶端完成了操做以後如何告知 js 後面會講到。這種方式很差的地方在於只能支持異步的調用方式,網絡 I/O 就決定了這種方式不支持同步。既然是 URI 的協議就會有長度限制,超長了請求就會被截斷

更爲嚴重的是無序性和有丟消息的可能,這也致使了這個方式很是不穩定,也是早期沒有其餘選擇使用的方式。

彈窗攔截

js 調用彈窗時通常有 alert/confirm/prompt 三種彈窗,這三種彈窗對應客戶端都會有方法實現,能夠直接作攔截。

var actionInfo = {
    type: 'eros',
    action: 'bmImage/camera',
    params:{
        "imageNum":2,
        "allowCrop":true,
        "callbackId":"bmImage.camera1527235458519"
    }
}

prompt(JSON.stringify([actionInfo]))
複製代碼

android 攔截 prompt

@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
    // 解析傳過來的字符串判斷 type 類型是否是解析的方式
    if (true){
        // 解析協議路徑得知調用方法
        // 解析 query 獲得參數
        // 經過 AOP 的方式去調用去調用對應的原生方法
        // 若是是異步返回
        return true;
        // 若是是同步,待上面的程序執行完畢以後返回結果
        // return res
    }
    return super.onJsPrompt(view, url, message, defaultValue, result);
}
複製代碼

iOS 攔截 prompt(使用 WKWebView)

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(nullable NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString * _Nullable result))completionHandler{
    // 解析傳過來的字符串判斷 type 類型是否是解析的方式
    if (true){
        // 解析協議路徑得知調用方法
        // 解析 query 獲得參數
        // 經過 AOP 的方式去調用去調用對應的原生方法
        // 若是是異步返回
        NSInvocation *invocation = [執行方法]
        [invocation invoke];
        return invocation;
        // 若是是同步,待上面的程序執行完畢以後返回結果
        return nil
    }else{
        執行對應的彈窗
    }
}
複製代碼

這種方式比請求攔截好的地方是能夠支持同步調用了。可是 iOS 中有兩種 UIWebView 和 WKWebView,前者在 webView 中屏蔽的彈窗的功能。後者雖然內存要比前者控制的好可是有不少兼容性的問題。

js 注入上下文

上面的使用方式仍是比較曲折,發展到如今有了 JavaScriptCore,也是如今大部分混合應用解決方案核心,JavaScriptCore 沒有 BOM 對象也沒有 DOM 對象,甚至還缺失一些瀏覽器的方法,可是這塊是 js 和 native 都能訪問到的公共區域。在打開 webView 以後,往 js 的上下文中注入方法,供 js 進行調用。

iOS JavaScriptCore 注入(UIWebView)

// 獲取 WebView 中 JS上下文
JSContext *context = [webview valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
//注入 callNative 函數方法
context[@"callNative"] = ^( JSValue * params )
{
    // 解析參數找到對應的方法進行處理
    // 同步回調
    NSInvocation *invocation = [執行方法]
    [invocation invoke];
    return invocation;
    // 異步回調
    return nil
}
複製代碼

js 調用方式

callNative({
    action: 'bmImage/camera',
    params:{
        "imageNum":2,
        "allowCrop":true,
        "callbackId":"bmImage.camera1527235458519"
    }
});
複製代碼

android webView 注入

// 經過 addJavascriptInterface 將對象映射到 JS 對象
// android 對象
// js 的對象名
mWebView.addJavascriptInterface(new JavaScriptBridge(), "callNative");
複製代碼

js 調用方式

callNative.bmImage.camera({
    "imageNum":2,
    "allowCrop":true,
    "callbackId":"bmImage.camera1527235458519"
})
複製代碼

這種方式就更接近寫代碼的方式了,無論是調用方式、傳遞參數的方式仍是同步異步回調都更好了。可是這種方式也有須要注意的地方,首先須要注意客戶端注入的時機,在 loadUrl 以前注入是無效的,可是在 FinishLoad 以後注入可能 webView 已經調用了方法,此時會出現調用不到該方法,因此還須要其餘的機制來保證這個問題。好比微信公衆號的 wx.config 接口。

native 調用 js

前面已經講了 js 調用 客戶端,js 在向客戶端發出調用指令以後,若是是同步方法,好比 獲取當前客戶端版本能當即獲得結果,若是是異步調用,以前每次調用客戶端的時候都傳遞了一個 callbackId,這個就是爲客戶端回調 js 作準備。

首先 js 會提供一個方法等待客戶端調用

window.nativeCallbackMap = {};
const callJs = (data) => {
    var data = JSON.parse(data);
    var callback = window.nativeCallbackMap[data['callbackId']
    if(callback){
        callback.call(null, data['resData'])
    }
    delete window.nativeCallbackMap[data['callbackId']
}
複製代碼

iOS 調用 js

NSString *resDataString = [self _serializeMessageData:data];
NSString* javascriptCommand = [NSString stringWithFormat:@"callJs('%@');", resDataString];
if ([[NSThread currentThread] isMainThread]) {
    [self.webView evaluateJavaScript:javascriptCommand completionHandler:nil];
} else {
    __strong typeof(self)strongSelf = self;
    dispatch_sync(dispatch_get_main_queue(), ^{
        [strongSelf.webView evaluateJavaScript:javascriptCommand completionHandler:nil];
    });
}
複製代碼

android 調用 js

final int version = Build.VERSION.SDK_INT;
// 由於該方法在 Android 4.4 版本纔可以使用,因此使用時需進行版本判斷
if (version < 18) {
    mWebView.loadUrl("javascript:callJs()");
} else {
    mWebView.evaluateJavascript("javascript:callJs()", new ValueCallback<String>() {
        @Override
        public void onReceiveValue(String value) {
            // js 的同步返回
        }
    });
}
複製代碼

上述 js bridge 的實現大體就是如今大部分的客戶端與 js 的通訊方式,如今 webView 也豐富了本身的功能,有能力調用客戶端提供的方法,完成全部客戶端能作的功能,js bridge 設計完以後剩下的就是需求推進,根據所需的功能提供不一樣的方法供前端調用。

若是須要與原生頁面間互相通訊,應該約定一種 scheme,也能夠理解成一種 URI 的實現,經過 js bridge 的接口調用客戶端(此時還能夠傳一個回調到客戶端,當客戶端完成某個操做以後返回該頁面執行回調,好比日期選擇),客戶端解析協議,打開對應的原生頁面,完成對應的操做。scheme 仍是手機瀏覽器會識別的一種協議,若是有對應的 APP 能夠直接呼起 APP,可是當你打開客戶端頁面的參數太多時,你的 scheme 會變得超長,瀏覽器會將 URL 截斷,這個時候還須要簡單的短鏈服務轉化

優勢:

  • 首先具備全部 webView 全部的優勢
  • 解決了單純 webView 的交互功能受限,能調用原生接口完成需求

缺點

  • 也沒法避免 webView 所帶來的性能問題,打開白屏時間長,用戶體驗較差,等問題,也存在受限與瀏覽器,及重複打開須要重複加載等問題
  • 全部新須要客戶端提供的功能都須要客戶端發版
  • 隨着業務發展客戶端定義的接口必須向下兼容,這會帶來不少冗餘代碼

表明產品:

  • 公衆號使用到微信 sdk 的功能
  • AppCan、PhoneGap、cordova 等 hybrid 框架

小程序

在 hybrid 混合應用穩定以後,你們發現功能上已經能知足開發需求了,因此下個階段應該追求體驗和性能上的提高,就是 RN 的方案了,ReactNative 的方案已經逐漸被你們所熟知並逐步落到項目中,混合應用方案也是本文介紹的重點,後面會詳述。

這裏想先講一講小程序,由於在技術的演進上小程序才應該是下一小步的提高,而且小程序嚴格意義上來講並不是 APP 的一種方案,更像是微信分發生態中的體驗進化,在使用公衆號這類 hybrid 的方案時,發現體驗和交互上的一些問題,好比加載白屏時間,頁面之間跳轉的交互,頁面內容的緩存等等。

因爲小程序如今實現方案面向開發者也是一個黑盒,我也是一邊瞭解一邊猜小程序如何實現的,小程序的框架包含兩部分:View 視圖層和 APP service。前者用來渲染頁面結構,後者用來作邏輯處理,接口調用。他們在兩個進程裏運行,有點相似在當前的頁面裏使用 web worker,關係以下圖:

APP View

咱們寫的視圖層和邏輯代碼是分離的,WXML 和 WXSS 構圖了視圖層的代碼,WXML 經過 wcc 工具轉換成 VDOM,WXSS 經過 wxsc 轉化 style 標籤。底層經過 WAWebview.js 來提供底層的封裝,每個視圖就會有一個 webView 來渲染,這也就提升了頁面渲染性能的問題,多個視圖頁面時就會有多個 webView 進程,因此小程序對頁面層級是有限制的,內存受限。視圖層主要包括如下內容:

  • WeixinJSBridge 封裝和上述的 hybrid 的 jsBridge 同樣
  • 小程序提供的組件註冊,一些能操做 DOM 的 API
  • 渲染的實現:VDOM、diff、render UI(在高人知道下了解到渲染出來的本質仍是 webview,在原生端只支持 flex 佈局,可是小程序裏還支持 web 的佈局,由此能夠看出,這裏必定是 webView 的渲染,並不是原生)
  • 頁面生命週期管理

APP Service

邏輯處理的代碼所有加載到一個進程 APP service 中,和視圖 webView 不一樣,全部的代碼邏輯都會一次性所有加載到這個進程中,由於主要的瓶頸仍是來自於渲染性能,而且全部的邏輯代碼都加載到進程中保證視圖切換的流程性,而且加上小程序有 2MB 大小的限制,在如今的網絡環境下一次加載體驗會更好。APP Service 包含如下內容:

  • WeixinJSBridge 封裝和上述的 hybrid 的 jsBridge 同樣
  • 全部小程序提供的 API 方法注入,全局方法注入
  • AMD 模塊化實現

小程序的開發環境

小程序運行在開發環境中和線上環境是不一樣的,線上環境 iOS 和 android 都有真正的 webView 環境提供,在開發過程當中小程序提供了一個 IDE,IDE 是基於 nwjs 實現的,釘釘客戶端也是基於這個實現的。其實就是在 PC 端的客戶端環境下儘量提供原生能力,若是是移動端纔會有的差別化能力就會 mock 掉。兩邊環境不一樣還體如今 APP Service 中,APP Service 主要是調用客戶端底層,因此底層的不一樣也影響着這層的封裝。

APP View 與 APP service 通訊

當咱們理解了前面的 hybrid 的通訊原理,這裏的通訊就比較好理解了。小程序的 bridge 實現原理就和 hybrid 同樣了。iOS 和 android 就很少說了。基於 nwjs 的客戶端是經過 window.postMessage 實現的,使用 chrome 擴展的接口注入一個 contentScript.js,封裝了 postMessage 方法。

// 發送消息經過 
window.postMessage(data, ‘*’);
// 接受消息經過
window.addEventListener(‘message’, messageHandler);
複製代碼

小程序的推進主要來自微信平臺的大流量,這就是所謂的微信流量紅利,公衆號已經承載了傳播和拉新的低成本方式,可是體驗一直被詬病,限制於 hybrid 的體驗問題讓追求體驗的開發者逐漸沒法忍受,此時小程序原生的組件,良好多頁面切換,幾乎沒有白屏時間的等待,讓你們又有了探索無限的可能。

優勢:

  • 首先具備全部 hybrid 全部的優勢
  • 無需安裝,極速打開
  • 原生的組件有了體驗上質的提高
  • 性能上也有了新的飛躍,白屏時間,頁面切換也有了更好的體驗(爲了減小白屏時間,小程序採用預加載的方案,而分不清哪一個會是邏輯裏的下一個頁面,因此小程序將全部 webView 全局預加載,這也是頁面層級和包大小限制的主要緣由)

缺點

  • 只能用於微信平臺,若是有多端的用戶需求,開發成本增長了
  • 組件仍是較少,不少操做 DOM 的方式也會有所限制,完成需求受限
  • 爲了性能的體驗,包的大小受限,打開頁面的層級受限

表明產品:

  • 各類客戶端的小程序

快應用

快應用是對標微信小程序的一場阻截,幾大手機廠商聯合發佈這個方案,一瞬間吸引了你們的眼球,愈來愈多端讓前端追都追不過來(這麼多技術確實讓人很絕望,甚至前段時間你們去惡意灌水了不少大項目的 issue,但這也是前端蓬勃發展的表現,當這些前沿的技術落地在項目中甚至你只是完成一個 demo 的時候,你仍是會有抑制不住的興奮和成就感)

快應用對自個人介紹是基於手機硬件平臺的新型應用形態,用的是新型應用形態,並不是新技術,相似這樣的實現有 PWA,只是 PWA 缺乏了手機硬件平臺的支持。

圖片來源:快應用發佈會PPT

快應用標準是由手機廠商組成的快應用聯盟聯合制定,快應用標準的誕生將在研發接口、能力接入、開發者服務等層面建設標準平臺。底層的硬件平臺提供底層 API 讓開發者調用,原生渲染組件,hybrid bridge 通訊,原理大體也與小程序實現相似,這裏就不詳細說明,下面是幾張快應用發佈會的 PPT 截圖,若是理解了上面的原理,這個應該就是比較好理解了。

之因此說是小程序的一場阻截,小程序曾放話說,將來兩年內,小程序將取代 80% 的 APP 市場,而手機廠商並不但願大量的 APP 被取代,因此催生了快應用的落地。可是創建在幾大國內手機廠商硬件平臺上的方案,就目前來看支持性,通用性,社交性上都是比不上小程序的。二者的前景不敢妄加揣測,可是小程序憑藉微信平臺的用戶量和用戶粘性,比幾大手機廠商實現的標準化仍是一目瞭然的。

優缺點就不詳述了,一目瞭然

Flutter

ReactNative 的開疆擴土進一步奠基了,React 的霸主地位,React 也由一個框架演進成了,以 React 爲基礎的前端多端解決方案,技術棧的生態方案。google 怎麼可能放棄本身在科技領域的地位,即便是前端相關的技術,因此出了 Flutter 技術方案完成 APP 的一環。

藉由自己的 android 和 chrome 的 平臺優點,準備重磅推出 Fuchsia OS,打造本身不基於 Linux 的底層系統,而 Fuchsia OS 欽定 UI Toolkit 就是 Flutter。Flutter 最大的改進就是本身重作了渲染引擎去渲染頁面,將混合應用的渲染性能推向了另外一個高度。

Flutter 之於 RN 來說最大的區別在於渲染,脫離了 JSFramework 的 Component 遞歸傳遞和逐個計算繪製,更像是 canvas 繪製,將 UI 直接繪製出來,Flutter 都是在狀態變動時從新構建 Widget Tree,Flutter 的渲染引擎在將 Widget Tree 轉化成渲染的 Render Tree,最後交給操做系統調用 GPU 去渲染,Flutter 由 Dart 程序寫的,Dart 和 native 之間仍然存在一個接口,能夠進行數據編碼和解碼,這可能比 JavaScript bridge 快好幾個數量級。

使用 Dart 是整個框架不太被前端所接受的問題,可是代碼都是相通的,上手仍是很快,嘗試 demo 期間仍是很快就能模仿出一個頁面,語言上的爭論就不說了,畢竟都不如 PHP。

因爲本身使用 Flutter 還在 demo 階段,並無真正圍繞 Flutter 作過相關的解決方案,具體的細節實現也沒有清楚的認知,也不適合展開詳述,很早以前以矢量圖起家的 Adobe 也嘗試過相似的方案,可是最終沒有把這條路走下去。

若是有興趣能夠移步:

weex 和 ReactNative

在講這兩種混合應用以前,再囉嗦幾句,上面大體瞭解了各類混合應用的方案,這些方案瞭解其原理和使用場景,在合適的場景去使用對應的方案,不要爲了落地某項方案而把業務生搬硬套,沒有一種方案是絕對的好,在不一樣的業務需求的驅動下權衡利弊再作決策。

這二者一直有人在試圖去比較分析得出利弊,看哪一種更好,甚至有人偏激的認爲 Weex 就不配合 RN 相提並論,可是我仍是想說理性的看待這個問題,客觀的面對前端技術,曾經 React 和 Vue 也是這樣的差距,直到如今依舊有人認爲使用 Vue 低俗,使用 React 高雅,但雅俗之分真的如此嗎?仍是應該理解其原理,辨別本身的業務場景,團隊學習成本,開發體驗等等一系列的緣由,而後再作評判。

就目前的各方面狀況講,RN 確實更優,橫空出世,背靠當時火的不行 React,一路都是風光無限。這種解決方案出來以後,若是沒有競爭者的挑戰,沒有對比,沒有選擇,也不必定是好事兒,雖然如今二者還有很大的差距。

我猜 Weex 始於 KPI,畢竟大廠造輪子來升級是很是好的途徑之一,可是日後發展,卻成了兩大陣營完善生態的方案,如今基於 React 的一整套的前端解決方案覆蓋PC、Web、Native 可謂是成了大公司前端方案的標準套路,後起之秀 Vue 用良好的開發體驗和低門檻的入門方式開始搶佔用戶,各類前端培訓學校讓一些前端不懂 js 基礎,可是 Vue 溜的飛起。但Vue 並無造成對 Native 的覆蓋,這個可能也是 Weex 和 Vue 一拍即合的緣由,雙方都有需求,就開始了合做。

扯會正題,在大前端逐漸融合的背景下,做爲以 Vue 創建技術棧的團隊開始尋找客戶端的方案,作技術選型開始考慮業務達成、團隊學習成本、開發效率,性能效率等問題,咱們一開始也是將 Weex 和 RN 做爲比較,在上一家公司使用的是 RN,可是現團隊創建技術棧基於 Vue,考慮到第二個因素偏向 Weex,實際調研過程當中發現 Weex 的坑確實不少,可是好在有不少問題已經有解決方案了,固然無論想要使用上述兩種方案,都須要有必定的原生能力。實際開發過程當中發現隨着對 Weex 的瞭解愈來愈多,開發效率也愈來愈快,入坑以後才發現了第三個和第四個甚至第五第六個優點。

至於 Weex 最大的賣點,兼容三端,Web 端這個優點每一個人都有本身的見解,咱們嘗試了去兼容 Web 可是發現反而犧牲了開發效率,有兼容的時間,單獨開發一套也出來了,而且更重要的是因爲用戶習慣的不一致,Web 端和 Native 針對的用戶羣體也不同,在這個流量就是金子的環境下犧牲用戶體驗和開發效率去兼容 Web 並不是是咱們的初衷。

固然也遇到了一些問題,一開始 Weex 沒有託管 Apache 的時候還有 issue,不少問題確實不能及時獲得解決,因此決定脫離 Weex 的全部 module,自行開發全部 module,從新設計,這也讓咱們對項目有了一些控制。

決定了自行開發 module 和組件以後,減小了對 Weex 自己的依賴,項目自己受到的限制也愈來愈小,業務很快也完成了。固然如今相似 demo 跑不起來,毀滅式的升級,市場組件沒法接入,bug 橫飛,組件不足以完成業務功能,兼容性不足,熱更新,公共文件致使包過大,社區經營很差等等這些問題,也都是一個技術產品成長的必經之路。

兩種方案在選型的時候,必定有可取的地方纔會選擇,工程師的精神就是趟坑,找準正確的方向而後勇往直前,兩種方案都有已經上線的優秀產品,說明是這條路至少是能走通的,固然咱們也在過程當中總結了咱們的解決方案,但願能幫助在 Weex 路上舉步維艱的同行人,無論選擇哪一種方案,選擇了就把他作好。Eros項目地址請戳(不要吝嗇你的 star)Eros文檔地址請戳。咱們公司已有三個項目經過 Eros 上線,也有幾十個應用經過 Eros 發佈上線。

固然還有不少優秀的方案沒有一一枚舉,好比:kotlin、WebAssembly,每一個方案都沉澱了不少前端工程師的積累,提供了各類能落地可實行的方案 phonegap -> cordova、mui、appcan、apicloud 等等

下一篇文章會詳細的講述 Weex 的原理

相關文章
相關標籤/搜索