? ? ? 微信小程序這兩天被傳的熱火朝天。相比傳統(tǒng)應(yīng)用需要安裝對(duì)應(yīng)的app而言犬钢,騰訊這次推出的微信小程序以微信app作為入口平臺(tái)苍鲜,第三方應(yīng)用運(yùn)行在微信環(huán)境上,從使用上來(lái)講玷犹,其類似于網(wǎng)頁(yè)瀏覽混滔,打開(kāi)某個(gè)小程序鏈接便可以使用,訪問(wèn)結(jié)束后直接關(guān)閉,本地?zé)o需安裝其它app坯屿,官方宣稱其具備與原生同樣的用戶體驗(yàn)油湖。小程序與傳統(tǒng)web頁(yè)面的主要區(qū)別在于,web頁(yè)面是完全運(yùn)行在客戶端的瀏覽器環(huán)境下领跛,小程序則更多地依賴于本地組件乏德,例如調(diào)用本地視圖類來(lái)顯示內(nèi)容,而不是通過(guò)瀏覽器來(lái)渲染吠昭,所以從性能上講喊括,小程序的性能將超過(guò)web,用戶體驗(yàn)也會(huì)更好怎诫。
? ? ? 目前由于微信小程序還處于內(nèi)測(cè)階段瘾晃,現(xiàn)在對(duì)其原理細(xì)節(jié)還不太清楚贷痪,但現(xiàn)在已經(jīng)有很多網(wǎng)絡(luò)大咖指出微信小程序應(yīng)該是使用了react native的來(lái)實(shí)現(xiàn)的幻妓。本文則主要對(duì)React Native iOS的實(shí)現(xiàn)原理進(jìn)行一定的分析。雖然微信小程序不一定直接使用React native劫拢,但至少應(yīng)該是借鑒了其設(shè)計(jì)精髓肉津。
“如何賣土豆”
? ? ? 在iOS開(kāi)發(fā)當(dāng)中,一個(gè)比較典型的需求是后臺(tái)希望能夠?qū)蛻舳四承傩赃M(jìn)行動(dòng)態(tài)配置舱沧,比如像視圖顯示:現(xiàn)在非常流行的“千人千面”妹沙。這是目前傳統(tǒng)客戶端所能夠做到的,后臺(tái)提供數(shù)據(jù)給客戶端熟吏,客戶端根據(jù)數(shù)據(jù)來(lái)對(duì)自身進(jìn)行配置距糖。更進(jìn)一步,公司每天都會(huì)有新的業(yè)務(wù)產(chǎn)生牵寺,后臺(tái)希望能把這些業(yè)務(wù)展示給用戶悍引,比如一家提供視頻服務(wù)的公司突然決定拓展業(yè)務(wù)開(kāi)始賣土豆,這時(shí)客戶端開(kāi)始犯難了帽氓,由于之前客戶端只是播放視頻趣斤,現(xiàn)在突然要賣土豆了,客戶端并沒(méi)有代碼來(lái)實(shí)現(xiàn)賣土豆控制邏輯黎休,現(xiàn)在后臺(tái)只能配置數(shù)據(jù)浓领,但控制邏輯又怎么告訴客戶端呢。傳統(tǒng)遇到這個(gè)問(wèn)題的時(shí)候有兩種辦法势腮,一種是客戶端增加賣土豆的代碼联贩,發(fā)一個(gè)新app版本,用戶必須升級(jí)到最新的版本才能買土豆捎拯,另一種方法泪幌,如果客戶端集成了webview,后臺(tái)可以通過(guò)開(kāi)發(fā)web頁(yè)面來(lái)實(shí)現(xiàn)買土豆的功能,所有操作通過(guò)web交互來(lái)實(shí)現(xiàn)座菠。React Native的出現(xiàn)就是解決了業(yè)務(wù)邏輯下發(fā)的問(wèn)題狸眼,除了數(shù)據(jù)之外,后臺(tái)可以將業(yè)務(wù)代碼下發(fā)到客戶端浴滴,客戶端根據(jù)下發(fā)的邏輯實(shí)現(xiàn)完全新的功能拓萌,實(shí)現(xiàn)了真正意義上的“動(dòng)態(tài)應(yīng)用”。
React Native核心——js引擎
? ? ? React Native通過(guò)編寫js代碼升略,來(lái)實(shí)現(xiàn)本地應(yīng)用的構(gòu)建微王,這是如何實(shí)現(xiàn)的呢?首先一點(diǎn)品嚣,iOS目前還是比較封閉的炕倘,js代碼是無(wú)法直接來(lái)對(duì)iOS應(yīng)用進(jìn)行構(gòu)建,其必須通過(guò)其它途徑來(lái)實(shí)現(xiàn)翰撑。React Native巧妙的使用了iOS的js引擎來(lái)實(shí)現(xiàn)js到Object-C轉(zhuǎn)接的功能罩旋。js是一門腳本語(yǔ)言,只有在運(yùn)行時(shí)才會(huì)進(jìn)行語(yǔ)法分析眶诈,iOS提供了JavaScript Core框架涨醋,這是個(gè)js引擎,可以執(zhí)行js代碼逝撬,例如:
JSContext *context = [[JSContext alloc] init];
JSValue *jsVal = [context evaluateScript:@"21+7"];
int iVal = [jsVal toInt32];
React Native創(chuàng)建了一個(gè)單獨(dú)的線程來(lái)執(zhí)行js代碼浴骂,其制定了一套轉(zhuǎn)義規(guī)則,通過(guò)React Native對(duì)外提供的接口宪潮,來(lái)實(shí)現(xiàn)js代碼到Object-C的轉(zhuǎn)換溯警。這種思想其實(shí)在之前已經(jīng)存在,比較典型的案例是cordova狡相,前端通過(guò)js bridge來(lái)調(diào)用客戶端功能模塊梯轻,其原理也是通過(guò)webview的js引擎來(lái)實(shí)現(xiàn)轉(zhuǎn)義。React Native在這基礎(chǔ)上走得更深谣光、更遠(yuǎn)檩淋。不再局限于某個(gè)功能模塊的調(diào)用,而是要在應(yīng)用的根基上萄金,完全實(shí)現(xiàn)一個(gè)全新的app蟀悦。
React Native工程分析
React Native的環(huán)境搭建可以參考:
http://reactnative.cn/docs/0.31/getting-started.html#content
使用react-native init AwesomeProject命令可以創(chuàng)建一個(gè)名為AwesomeProject的React Native的工程。下面是創(chuàng)建好的工程目錄氧敢,Libraries目錄下存放的React Native的客戶端核心代碼日戈,其由若干個(gè)子工程組成。
通過(guò)Xcode在模擬器中啟動(dòng)應(yīng)用孙乖,項(xiàng)目會(huì)執(zhí)行腳本開(kāi)啟終端來(lái)執(zhí)行node命令浙炼,效果如下份氧,從打印內(nèi)容來(lái)看,是啟動(dòng)一個(gè)服務(wù)器弯屈。
應(yīng)用運(yùn)行效果如下圖所示:
在工程目錄里面有一個(gè)index.io.js文件蜗帜,其便是構(gòu)建ios應(yīng)用的js核心代碼。
index.ios.js內(nèi)容如下所示:
上面展示了整個(gè)工程的結(jié)構(gòu)及js代碼资厉。那么在應(yīng)用運(yùn)行時(shí)厅缺,React Native是如何將js代碼發(fā)送給應(yīng)用的呢?通過(guò)對(duì)代碼進(jìn)行分析宴偿,發(fā)現(xiàn)在應(yīng)用啟動(dòng)后湘捎,會(huì)創(chuàng)建js代碼URL地址,如下圖所示:
其中jsBundleURLForBundleRoot內(nèi)部會(huì)調(diào)用下圖的方法窄刘,其會(huì)創(chuàng)建一個(gè)完整的URL窥妇,通過(guò)調(diào)試發(fā)現(xiàn)其最終生成這樣的地址:
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false
通過(guò)瀏覽器訪問(wèn)該地址返回得到下面的結(jié)果,是一個(gè)js代碼文件娩践。
搜索其中內(nèi)容找到自己創(chuàng)建的部分活翩,發(fā)現(xiàn)其已經(jīng)被轉(zhuǎn)義成了原生js代碼。
通過(guò)上面的分析欺矫,可以了解其中的原理纱新,我們編寫的React Native js代碼需要在后臺(tái)經(jīng)過(guò)一次轉(zhuǎn)義,將代碼轉(zhuǎn)義成原生的js代碼后穆趴,發(fā)送給客戶端,客戶端再將其放入到j(luò)s引擎中來(lái)運(yùn)行遇汞。服務(wù)器端最終將所有的代碼都整合到一個(gè)js文件當(dāng)中未妹,發(fā)送給客戶端。為了驗(yàn)證這個(gè)猜想空入,我將js代碼保存到本地文件络它,將其放在http服務(wù)器上,通過(guò)http://localhost:8080/examples/index-ios.html來(lái)訪問(wèn)該文件歪赢,通過(guò)對(duì)工程代碼進(jìn)行修改化戳,將返回的url改成上述目標(biāo),發(fā)現(xiàn)工程能夠正常運(yùn)行埋凯。
由此可以整理出React Native的整個(gè)運(yùn)行過(guò)程:
微信小程序
? ? ? 如果微信小程序的確是借鑒了React Native的思想点楼,那么其整體的運(yùn)行原理應(yīng)該如上面分析的一樣。微信有可能會(huì)在此基礎(chǔ)上做一些優(yōu)化或增強(qiáng)白对。例如在上面的測(cè)試過(guò)程中發(fā)現(xiàn)掠廓,下發(fā)的js文件,單只實(shí)現(xiàn)了一個(gè)hello world的功能甩恼,其文件大小就有1.5M蟀瞧,這是由于其包含了React Native的js核心代碼沉颂。如果微信需要減少數(shù)據(jù)交互,則很有可能會(huì)將Native代碼轉(zhuǎn)義原生js代碼的過(guò)程放在客戶端來(lái)完成悦污,或者通過(guò)某些方式铸屉,將重用的核心代碼放在本地,數(shù)據(jù)交互只更新業(yè)務(wù)代碼切端,另外在代碼安全上有可能會(huì)做一些增強(qiáng)工作抬探。從目前透露的消息來(lái)看,微信提供的本地接口還是非常豐富的帆赢,對(duì)絕大部多數(shù)應(yīng)用來(lái)講都是滿足的小压。
小程序的前景:
? ? ? 從功能上講,微信小程序與之前UC椰于、百度推廣的輕應(yīng)用并沒(méi)有很大區(qū)別怠益。但由于微信擁有巨大的流量?jī)?yōu)勢(shì),其所帶來(lái)的影響是不可比擬的瘾婿。本地化在提升運(yùn)行速度的同時(shí)也提供了更多的權(quán)限蜻牢,公司可以開(kāi)發(fā)出各種功能復(fù)雜的應(yīng)用,給用戶更為豐富的體驗(yàn)偏陪。在應(yīng)用推廣上將會(huì)非常方便抢呆,未來(lái)很有可能會(huì)產(chǎn)生多個(gè)超級(jí)小程序。
? ? ? 小程序同時(shí)也面臨著不少挑戰(zhàn)笛谦,像微信需要在apple store通過(guò)審核才能發(fā)布抱虐,如果微信成為了應(yīng)用的入口,這將搶去apple store的市場(chǎng)饥脑,apple也不會(huì)容忍這種情況發(fā)生恳邀。同時(shí),應(yīng)用的發(fā)布將通過(guò)微信來(lái)完成灶轰,應(yīng)用的安全審核谣沸,按理都需要微信來(lái)做,這對(duì)微信來(lái)說(shuō)也是非常大的挑戰(zhàn)笋颤。對(duì)于第三方公司而言乳附,在微信上使用小程序來(lái)帶來(lái)利益的同時(shí),也面臨著微信的審查壓力伴澄,之前就出現(xiàn)過(guò)訂閱號(hào)被封的情況赋除,如果出現(xiàn)這種情況將會(huì)對(duì)公司帶來(lái)致命的打擊,公司也不會(huì)將流量全部分到小程序當(dāng)中秉版。
“小程序”能否代替App
? ? ? HTML5與App還是存著本質(zhì)的區(qū)別:App功能極為復(fù)雜贤重,而HTML5基本上只有簡(jiǎn)單的一個(gè)功能,這種差別就像早年間的flash小游戲和大型單機(jī)游戲之間的差別清焕,“小程序”根本無(wú)法替代App并蝗。
? ? ? “小程序”主打“用完即走”祭犯、無(wú)需安裝和卸載的模式,這對(duì)于用戶來(lái)說(shuō)方便快捷滚停,但對(duì)于產(chǎn)品而言沃粗,卻失去了沉淀用戶最基本的方式。這里可以看到键畴,APP獲取一個(gè)用戶的門檻是高的最盅,但高門檻帶來(lái)的好處是,用戶的二次消費(fèi)門檻低了起惕。
? ? ? 而H5雖然首次消費(fèi)門檻低涡贱,但卻遇到了后續(xù)消費(fèi)門檻無(wú)法降低的問(wèn)題。而這方面正好是APP的優(yōu)勢(shì)惹想。
關(guān)于微信和手機(jī)操作系統(tǒng)
? ? ? 很多人可能會(huì)覺(jué)得微信的未來(lái)就是手機(jī)操作系統(tǒng)问词。但微信基本不可能這么定位自己。因?yàn)猷至唬謾C(jī)操作系統(tǒng)的核心展示是APP收藏夾激挪,而微信是聊天窗口。這個(gè)本質(zhì)不改變锋叨,就很難改變“應(yīng)用APP”和“小程序”在各自體系里的地位垄分。
? ? ? 手機(jī)操作系統(tǒng)未來(lái)依然是APP的天下,側(cè)重重體驗(yàn)娃磺、重交互薄湿、高粘性需求的產(chǎn)品。比如微信就是這樣的產(chǎn)品豌鸡。
? ? ? 設(shè)想微信就是一款基于瀏覽器的H5產(chǎn)品嘿般,估計(jì)你用起來(lái)就很崩潰了。
參考資料: