React跨端動態(tài)化之從JS引擎到RN落地詳解_第1頁
React跨端動態(tài)化之從JS引擎到RN落地詳解_第2頁
React跨端動態(tài)化之從JS引擎到RN落地詳解_第3頁
React跨端動態(tài)化之從JS引擎到RN落地詳解_第4頁
React跨端動態(tài)化之從JS引擎到RN落地詳解_第5頁
已閱讀5頁,還剩4頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第React跨端動態(tài)化之從JS引擎到RN落地詳解目錄一為什么跨端動態(tài)化迫在眉睫二首當其沖的為什么是ReactNative三JS引擎讓跨端動態(tài)化成為可能四走進ReactNative的世界五總結

一為什么跨端動態(tài)化迫在眉睫

目前很多互聯(lián)網(wǎng)大廠的移動端開發(fā)都在朝著跨端動態(tài)化方向發(fā)展。由于快速迭代開發(fā)或者對原生包體積要求嚴格,及其對資源成本的把控,實現(xiàn)跨端動態(tài)化迫在眉睫。我們先來看看Native原生開發(fā)的一些不足之處:

1原生開發(fā)周期時間長,審核周期長,會影響到需求發(fā)布和迭代效率,有些場景下會更加棘手,比如修復線上緊急bug,或者是頻繁迭代一些開發(fā)需求。2目前移動端主要的平臺就是Android和iOS,如果一款前端應用想要同時運行在兩個平臺的話,采用Native就需要雙端各自開發(fā)一遍,這樣無疑浪費了資源和提高了維護成本。3Native開發(fā)代碼要打包在客戶端包中,這樣增加了包的體積,用戶下載的時候,會下載更多的資源,輕量級的包會提高運營效率,而且Android和iOS應用平臺也對包體積嚴格把控。

說到跨端化方案,首先想到的就是ReactNative,為什么這么說呢我們往下看。

二首當其沖的為什么是ReactNative

React在跨端領域也有一席之地,功勞來源跨端方案ReactNative,簡稱RN,RN是目前主流的動態(tài)化方案之一,是Facebook在2015年開源的JS框架React在原生移動應用平臺的跨平臺技術,支持安卓和iOS平臺。

RN的受歡迎并不僅僅是支持安卓和iOS平臺,還有一個重要的因素就是動態(tài)化,那么這種動態(tài)化相比于原生客戶端有什么優(yōu)點呢?

RN對于原生開發(fā)有著明顯的優(yōu)點:

1RN是采用運行React的JS作為開發(fā)平臺,這樣可以讓web開發(fā)者也能夠參與到Native開發(fā)中來,還有就是RN讓一套代碼可以運行在兩端,大大減少了開發(fā)和維護成本。2RN是采用原生渲染的,性能和體驗僅次于Native開發(fā)。3還有一點也是最重要的,就是RN是動態(tài)化的方案,也就是RN打出來的應用包,并不是和Native包綁定在一起發(fā)布的,而是在運行Native的時候拉下RN的包,這樣一是減少了Native包體積,二是RN包可以隨時發(fā)布,提高了迭代效率,也讓一些線上問題能夠快速解決。

近兩年,也有一些興起的跨端技術方案,比如Flutter,阿里巴巴開源的Rax等,相比這些動態(tài)化方法,RN也有一定優(yōu)勢:

1生態(tài)成熟,技術社區(qū)活躍,采用React語法,學習成本低。2目前業(yè)界已經(jīng)出現(xiàn)了很多成熟方案,比如京東的JDReact和美團的MRN等。

RN是基于React框架開發(fā)的原生應用,React憑借著JSX語法讓使用者結合多種設計模式使開發(fā)變得非常靈活,React是JavaScript(簡稱JS)框架,那么如果想要運行RN,那么就需要運行JS,在我們的影響中,JS作為腳本語言運行到瀏覽器端,或者運行在Node.js中,那么如今卻能夠作為跨端方案運行到Native應用中,這是為什么呢?

原來能夠讓JS運行到Native中的法寶就是JS引擎,最常見的JS引擎就是v8,v8使用在Chrome瀏覽器和Node.js中,構建了JS運行時,能夠執(zhí)行JS腳本。那么接下來我們就來看一下RN中的JS引擎。

三JS引擎讓跨端動態(tài)化成為可能

V8引擎簡介

計算機本身并不能讀懂編程語言,計算機只能讀懂二機制文件,但是為了能夠讓編程語法能夠讓計算機讀懂,就必須編譯成二機制文件,這就是編譯語言,比如JAVAGO等都是編譯型的語言,編譯型語法在編譯成二機制文件后,會保存二機制文件,在運行時候,可以直接運行二機制文件,不需要重復編譯。

還有一類語言,不需要編譯成文件,而是需要通過解釋器對語言進行動態(tài)解釋和執(zhí)行,這類語言就是解釋型語言,比如Python,JS等。如下圖就是兩種類型的語言執(zhí)行過程:

編譯型語言啟動需要編譯成二進制文件,所以啟動速度會比很慢,但是執(zhí)行的時候是直接使用編譯好的二進制文件,所以執(zhí)行速度會快一些。

但是相比解釋型語言,啟動會很快,但是執(zhí)行時候,需要通過解釋器解析語法樹,變成中間代碼,執(zhí)行字節(jié)碼,這樣就浪費了時間,使得執(zhí)行速度會變慢。

由于JS是解釋型語言,它的執(zhí)行需要宿主環(huán)境提供,轉成語法樹,并且讀懂語法樹,轉成字節(jié)碼并執(zhí)行的能力,v8引擎的工作就需要有這些能力:

Parser:將JS源碼轉換成抽象語法樹,什么是抽象語法?在計算機科學中,抽象語法樹(abstractsyntaxtree或者縮寫為AST),或者語法樹(syntaxtree),是源代碼的抽象語法結構的樹狀表現(xiàn)形式,這里特指編程語言的源代碼。

Lgniton:interpreter解釋器,負責將AST轉換成指令字節(jié)碼,解釋執(zhí)行指令字節(jié)碼(ByteCode),解釋器執(zhí)行的時候主要有四個模塊:內存中的字節(jié)碼,寄存器,棧和堆。

TurboFan:compiler編譯器,通過Lgniton收集的信息,將指令字節(jié)碼轉換成優(yōu)化匯編代碼。

Orinoco:garbagecollector簡稱GC,垃圾回收模塊,負責將程序不需要的內存空間回收,提升引擎性能。

如上還有一個問題就是如果每一次都通過TurboFan將指令字節(jié)碼轉換成匯編代碼,那么這樣十分浪費性能。在v8出現(xiàn)之前,所有的JS虛擬機所采用的都是解釋執(zhí)行的方式,這是JS執(zhí)行速度過慢的主要原因之一。

而v8率先引入了即時編譯(JIT)的雙輪驅動的設計(混合使用編譯器和解釋器的技術),這是一種權衡策略,給JS的執(zhí)行速度帶來了極大的提升。

那么JIT就是取編譯執(zhí)行語言和解釋執(zhí)行語言的長處,利用解釋器對代碼進行處理,對于頻率高的代碼進行熱區(qū)收集,在之后指令字節(jié)碼編譯成機器碼的時候,儲存高頻率的二機制機器碼,之后就可以復用并執(zhí)行二機制代碼,以減少解釋器和編譯器的壓力。

v8通過優(yōu)化后的工作流程如下:

知道了v8JS引擎的工作流程之后,那么RN應用中用什么JS引擎呢?

RN在0.60版本之前使用JSCore作為默認的JS引擎,JSCore全名JavaScriptCore,JSCore是WebKit默認內嵌的JS引擎,JSCore作為一個系統(tǒng)級Framework被蘋果提供給開發(fā)者,作為蘋果的瀏覽器引擎WebKit中重要組成部分。

所以在iOS應用中默認為JSCore引擎,這使得RN也用JSCore,但是JSCore沒有對Android機型做好適配,在性能,體積,和內存上和v8有著明顯的差別。

基于這個背景,RN團隊提供了JSI(JavaScriptInterface)框架,JSI并不是RN的一部分,JSI可以視作一個兼容層,意在磨平不同JS引擎中的差異性。

JSI實現(xiàn)了引擎切換,比如在iOS平臺運行的JSCore,在Andriod中運行的是v8引擎。

JSI同樣提供了抽象的API接口,定義了與各個JS引擎交互的接口。

在JS中調用C++注入到JS引擎中的方法,數(shù)據(jù)載體格式是通過HostObject接口規(guī)范化后的,摒棄了舊架構中以JSON作為數(shù)據(jù)載體的異步機制,讓JS和C++相互感知。

明白了RN內部運轉的背景之后,我們開始正式進入RN的世界。

四走進ReactNative的世界

ReactNative將原生開發(fā)的最佳部分與React相結合,致力于成為構建用戶界面的頂尖JavaScript框架。

ReactNative開發(fā)和傳統(tǒng)的web端React應用開發(fā)類似,并且都是js語言,使得web開發(fā)者上手RN開發(fā)特別簡單。

在Reactweb應用中,打包,部署到上線的產(chǎn)物,是一個html,css,js文件的集合體,最后把這些產(chǎn)物放在服務器上就可以了。

但是在RN中,最后打包產(chǎn)物是一個js文件,叫做jsbundle,在Native端運行RN項目,本質上是遠程拉取了jsbundle,并通過上述的js引擎運行當前jsbundle,每次運行一個bundle就需要外層容器提供一個js引擎。

在React構建的應用為單頁面應用,如果存在多個頁面,可以通過路由的方式實現(xiàn)頁面的跳轉,在RN中,也有一些解決方案,通常的手段是一個jsbundle對應一個頁面,或者是一個jsbundle對應多個頁面,如下圖所示:

如果采用,原生+RN+H5等融合的技術方案開發(fā)的話,單jsbundle對應單頁面的方式比較適合,但是如果是Native作為外層容器,里面都頁面都是RN的話,單頁面多bundle也是一個不錯的選擇。

基礎用法

知道了RN的本質之后,我們看一下RNbundle的注冊,在RN中每一個應用都有一個入口文件,RN中提供了注冊根本應用的方法,那就是AppRegistry,這一點和Reactweb應用會有一些區(qū)別,web應用中,主要依賴于react-dom中提供的api,但是在RN項目中,無需再下載react-dom,取而代之的是react-native包。

我們先來試著注冊一個RN應用:

import{AppRegistry}from'react-native'

/*根組件*/

importAppfrom'./app'

AppRegistry.registerComponent('Root',()=App/)

如上我們注冊了Root,指向了組件App。接下來就可以在App就可以正常開發(fā)了。

在瀏覽器端,可以用DOM標簽或者組件,但是在RN中是沒有DOM的,所以如果想要引入原生的視圖組件,就必須從react-native中引入,下面我們就編寫一下App組件:

importreactfrom'react'

import{View,Text}from'react-native';

functionApp(){

returnView

TextHello,ReactNative!/Text

/View

除了基礎的視圖容器組件之外,RN還提供了一些移動端常用的組件,比如列表組件ScrollView,SectionList等。

事件

對于一些用戶交互事件,RN中也提供了對應事件組件載體,比如點擊事件用的是TouchableOpacity。如下所示

functionApp(){

/*處理點擊事件*/

consthandlePress=()={}

returnTouchableOpacityonPress={handlePress}

Textclick/Text

/TouchableOpacity

樣式

在RN中,是沒有css樣式文件的,RN中的樣式就和CSSINJS類似,都是通過JS來完成的,RN提供了StyleSheet可以創(chuàng)建style對象,如下所示:

import{StyleSheet,View}from"react-native"

conststyles=StyleSheet.create({

container:{

flex:1,

padding:24,

backgroundColor:"#eaeaea"

functionApp(){

returnView>

對于RN的基礎使用,如果參考官方文檔,學習成本不高,上手也很快。

弄明白RN的運行環(huán)境和基礎使用之后,那么都知道RN最終的打包產(chǎn)物只是一個js文件,那么這個js文件是怎么運行到native應用中的,又是怎么和native應用進行交互的呢?

接下來文章中我們會對RN的原理進行探秘,探索一下RN內部運轉的機制。

另一方面,現(xiàn)在的動態(tài)化方案

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論