? ? ? 微信小程序這兩天被傳的熱火朝天。相比傳統應用需要安裝對應的app而言,騰訊這次推出的微信小程序以微信app作為入口平臺,第三方應用運行在微信環境上,從使用上來講,其類似于網頁瀏覽,打開某個小程序鏈接便可以使用,訪問結束后直接關閉,本地無需安裝其它app,官方宣稱其具備與原生同樣的用戶體驗。小程序與傳統web頁面的主要區別在于,web頁面是完全運行在客戶端的瀏覽器環境下,小程序則更多地依賴于本地組件,例如調用本地視圖類來顯示內容,而不是通過瀏覽器來渲染,所以從性能上講,小程序的性能將超過web,用戶體驗也會更好。
? ? ? 目前由于微信小程序還處于內測階段,現在對其原理細節還不太清楚,但現在已經有很多網絡大咖指出微信小程序應該是使用了react native的來實現的。本文則主要對React Native iOS的實現原理進行一定的分析。雖然微信小程序不一定直接使用React native,但至少應該是借鑒了其設計精髓。
“如何賣土豆”
? ? ? 在iOS開發當中,一個比較典型的需求是后臺希望能夠對客戶端某些屬性進行動態配置,比如像視圖顯示:現在非常流行的“千人千面”。這是目前傳統客戶端所能夠做到的,后臺提供數據給客戶端,客戶端根據數據來對自身進行配置。更進一步,公司每天都會有新的業務產生,后臺希望能把這些業務展示給用戶,比如一家提供視頻服務的公司突然決定拓展業務開始賣土豆,這時客戶端開始犯難了,由于之前客戶端只是播放視頻,現在突然要賣土豆了,客戶端并沒有代碼來實現賣土豆控制邏輯,現在后臺只能配置數據,但控制邏輯又怎么告訴客戶端呢。傳統遇到這個問題的時候有兩種辦法,一種是客戶端增加賣土豆的代碼,發一個新app版本,用戶必須升級到最新的版本才能買土豆,另一種方法,如果客戶端集成了webview,后臺可以通過開發web頁面來實現買土豆的功能,所有操作通過web交互來實現。React Native的出現就是解決了業務邏輯下發的問題,除了數據之外,后臺可以將業務代碼下發到客戶端,客戶端根據下發的邏輯實現完全新的功能,實現了真正意義上的“動態應用”。
React Native核心——js引擎
? ? ? React Native通過編寫js代碼,來實現本地應用的構建,這是如何實現的呢?首先一點,iOS目前還是比較封閉的,js代碼是無法直接來對iOS應用進行構建,其必須通過其它途徑來實現。React Native巧妙的使用了iOS的js引擎來實現js到Object-C轉接的功能。js是一門腳本語言,只有在運行時才會進行語法分析,iOS提供了JavaScript Core框架,這是個js引擎,可以執行js代碼,例如:
JSContext *context = [[JSContext alloc] init];
JSValue *jsVal = [context evaluateScript:@"21+7"];
int iVal = [jsVal toInt32];
React Native創建了一個單獨的線程來執行js代碼,其制定了一套轉義規則,通過React Native對外提供的接口,來實現js代碼到Object-C的轉換。這種思想其實在之前已經存在,比較典型的案例是cordova,前端通過js bridge來調用客戶端功能模塊,其原理也是通過webview的js引擎來實現轉義。React Native在這基礎上走得更深、更遠。不再局限于某個功能模塊的調用,而是要在應用的根基上,完全實現一個全新的app。
React Native工程分析
React Native的環境搭建可以參考:
http://reactnative.cn/docs/0.31/getting-started.html#content
使用react-native init AwesomeProject命令可以創建一個名為AwesomeProject的React Native的工程。下面是創建好的工程目錄,Libraries目錄下存放的React Native的客戶端核心代碼,其由若干個子工程組成。
通過Xcode在模擬器中啟動應用,項目會執行腳本開啟終端來執行node命令,效果如下,從打印內容來看,是啟動一個服務器。
應用運行效果如下圖所示:
在工程目錄里面有一個index.io.js文件,其便是構建ios應用的js核心代碼。
index.ios.js內容如下所示:
上面展示了整個工程的結構及js代碼。那么在應用運行時,React Native是如何將js代碼發送給應用的呢?通過對代碼進行分析,發現在應用啟動后,會創建js代碼URL地址,如下圖所示:
其中jsBundleURLForBundleRoot內部會調用下圖的方法,其會創建一個完整的URL,通過調試發現其最終生成這樣的地址:
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false
通過瀏覽器訪問該地址返回得到下面的結果,是一個js代碼文件。
搜索其中內容找到自己創建的部分,發現其已經被轉義成了原生js代碼。
通過上面的分析,可以了解其中的原理,我們編寫的React Native js代碼需要在后臺經過一次轉義,將代碼轉義成原生的js代碼后,發送給客戶端,客戶端再將其放入到js引擎中來運行。服務器端最終將所有的代碼都整合到一個js文件當中,發送給客戶端。為了驗證這個猜想,我將js代碼保存到本地文件,將其放在http服務器上,通過http://localhost:8080/examples/index-ios.html來訪問該文件,通過對工程代碼進行修改,將返回的url改成上述目標,發現工程能夠正常運行。
由此可以整理出React Native的整個運行過程:
微信小程序
? ? ? 如果微信小程序的確是借鑒了React Native的思想,那么其整體的運行原理應該如上面分析的一樣。微信有可能會在此基礎上做一些優化或增強。例如在上面的測試過程中發現,下發的js文件,單只實現了一個hello world的功能,其文件大小就有1.5M,這是由于其包含了React Native的js核心代碼。如果微信需要減少數據交互,則很有可能會將Native代碼轉義原生js代碼的過程放在客戶端來完成,或者通過某些方式,將重用的核心代碼放在本地,數據交互只更新業務代碼,另外在代碼安全上有可能會做一些增強工作。從目前透露的消息來看,微信提供的本地接口還是非常豐富的,對絕大部多數應用來講都是滿足的。
小程序的前景:
? ? ? 從功能上講,微信小程序與之前UC、百度推廣的輕應用并沒有很大區別。但由于微信擁有巨大的流量優勢,其所帶來的影響是不可比擬的。本地化在提升運行速度的同時也提供了更多的權限,公司可以開發出各種功能復雜的應用,給用戶更為豐富的體驗。在應用推廣上將會非常方便,未來很有可能會產生多個超級小程序。
? ? ? 小程序同時也面臨著不少挑戰,像微信需要在apple store通過審核才能發布,如果微信成為了應用的入口,這將搶去apple store的市場,apple也不會容忍這種情況發生。同時,應用的發布將通過微信來完成,應用的安全審核,按理都需要微信來做,這對微信來說也是非常大的挑戰。對于第三方公司而言,在微信上使用小程序來帶來利益的同時,也面臨著微信的審查壓力,之前就出現過訂閱號被封的情況,如果出現這種情況將會對公司帶來致命的打擊,公司也不會將流量全部分到小程序當中。
“小程序”能否代替App
? ? ? HTML5與App還是存著本質的區別:App功能極為復雜,而HTML5基本上只有簡單的一個功能,這種差別就像早年間的flash小游戲和大型單機游戲之間的差別,“小程序”根本無法替代App。
? ? ? “小程序”主打“用完即走”、無需安裝和卸載的模式,這對于用戶來說方便快捷,但對于產品而言,卻失去了沉淀用戶最基本的方式。這里可以看到,APP獲取一個用戶的門檻是高的,但高門檻帶來的好處是,用戶的二次消費門檻低了。
? ? ? 而H5雖然首次消費門檻低,但卻遇到了后續消費門檻無法降低的問題。而這方面正好是APP的優勢。
關于微信和手機操作系統
? ? ? 很多人可能會覺得微信的未來就是手機操作系統。但微信基本不可能這么定位自己。因為,手機操作系統的核心展示是APP收藏夾,而微信是聊天窗口。這個本質不改變,就很難改變“應用APP”和“小程序”在各自體系里的地位。
? ? ? 手機操作系統未來依然是APP的天下,側重重體驗、重交互、高粘性需求的產品。比如微信就是這樣的產品。
? ? ? 設想微信就是一款基于瀏覽器的H5產品,估計你用起來就很崩潰了。
參考資料: