JSPatch 是 iOS 平臺上的一個開源庫,只需接入極小的三個引擎文件,即可以用 JavaScript 調(diào)用和替換任意 Objective-C 方法,也就是說可以在 App 上線后通過下發(fā) JavaScript 腳本,實時修改任意 Objective-C 方法的實現(xiàn),達(dá)到修復(fù) Bug 或動態(tài)運營的目的。目前 JSPatch 被大規(guī)模應(yīng)用于熱修復(fù)(Hotfix),已有超過 2500 個 App 接入。
雖然 JSPatch 目前大部分只用于熱修復(fù),但因為其可以調(diào)用任意 Objective-C 方法,實際上它也可以做熱更新的工作,也就是動態(tài)為 App 添加功能模塊,并對這些功能模塊進(jìn)行實時更新,可以起到跟 React Native 一樣的作用。我們從學(xué)習(xí)成本、接入成本、開發(fā)效率、熱更新能力和性能體驗這幾個方面來對比一下使用 React Native 和 JSPatch 做熱更新的差異。
React Native 是從 Web 前端開發(fā)框架 React 延伸出來的解決方案,主要解決的問題是 Web 頁面在移動端性能低的問題,React Native 讓開發(fā)者可以像開發(fā) Web 頁面那樣用 React 的方式開發(fā)功能,同時框架會通過 JavaScript 與 Objective-C 的通信讓界面使用原生組件渲染,讓開發(fā)出來的功能擁有原生APP的性能和體驗。
這里會有一個學(xué)習(xí)成本的問題,大部分 iOS 開發(fā)者并不熟悉 Web 前端開發(fā),當(dāng)他們需要一個動態(tài)化的方案去開發(fā)一個功能模塊時,若使用 React Native,就意味著他需要學(xué)習(xí) Web 前端的一整套開發(fā)技能,學(xué)習(xí)成本很高。所以目前一些使用 React Native 的團(tuán)隊里,這部分功能的開發(fā)是由前端開發(fā)者負(fù)責(zé),而非終端開發(fā)者。
但前端開發(fā)者負(fù)責(zé)這部分功能也會有一些學(xué)習(xí)成本的問題,因為 React Native 還未十分成熟,出了 Bug 或有性能問題需要深入 React Native 客戶端代碼去排查和優(yōu)化。也就是說 React Native 是跨 Web 前端開發(fā)和終端開發(fā)的技術(shù),要求使用者同時有這兩方面能力才能使用得當(dāng),這不可避免地帶來學(xué)習(xí)成本的提高。
而 JSPatch 是從終端開發(fā)出發(fā)的一種方案,JSPatch 寫出來的代碼風(fēng)格與 Objective-C 原生開發(fā)一致,使用者不需要有 Web 前端的知識和經(jīng)驗,只需要有 iOS 開發(fā)經(jīng)驗,再加上一點 JavaScript 語法的了解,就可以很好地使用,對終端開發(fā)來說學(xué)習(xí)成本很低。
可以看一下同樣實現(xiàn)一個簡單的界面,React Native 和 JSPatch 代碼的對比:
//React Native class HelloWorld extends Component {
render() { return ( <View style={styles.btnArea}> <View style={styles.btnWrapper}> <TouchableHighlight underlayColor="#ED5F37” onPress={this.login}
activeOpacity={0.7}>
<Text style={styles.btn}>登錄</Text>
</TouchableHighlight>
</View>
</View>
);
}
login(){
};
}
var styles = StyleSheet.create({
btnArea: {
justifyContent: 'center',
marginLeft: 20,
marginRight: 20,
marginTop: 100,
flexDirection: 'row',
},
btnWrapper: {
backgroundColor: '#FC6E50',
borderRadius: 5,
flex: 1
},
btn: {
paddingTop: 10,
paddingBottom: 10,
color: '#ffffff',
textAlign: 'center',
},
});
//JSPatch require('UIColor, UIScreen, UIButton')
defineClass('HelloWord : UIView', {
initWithFrame: function(frame) { if(self = super.initWithFrame(frame)){ var screenWidth = UIScreen.mainScreen().bounds().width var loginBtn = UIButton.alloc().initWithFrame({x: 20, y: 50, width: screenWidth - 40, height: 30});
loginBtn.setBackgroundColor(UIColor.greenColor())
loginBtn.setTitle_forState("Login", 0)
loginBtn.layer().setCornerRadius(5)
loginBtn.addTarget_action_forControlEvents(self, 'handleBtn', 1<<6);
self.addSubview(loginBtn);
} return self;
},
handleBtn: function() { }
})
接入成本上,React Native 是比較大的框架,據(jù)統(tǒng)計目前核心代碼里 Objective-C 和 JavaScript 代碼加起來有 4w 行,接入后安裝包體積增大 1.8M 左右。而 JSPatch 是微型框架,只有 3 個文件 2k 行代碼,接入后增大 100K 左右。另外 React Native 需要搭建一套開發(fā)環(huán)境,有很多依賴的庫,環(huán)境的搭建是一個痛點。而 JSPatch 無需搭建環(huán)境,只需拖入三個文件到工程中即可使用。
React Native 是大框架,維護(hù)起來成本也會增大,在性能調(diào)優(yōu)和 Bug 查找時,必須深入了解整個框架的原理和執(zhí)行流程,此外 React Native 目前還未達(dá)到穩(wěn)定狀態(tài),升級時踩坑不可避免。相對來說 JSPatch 接入后的維護(hù)成本會低一些,因為 JSPatch 只是作為很薄的一層轉(zhuǎn)接口,沒有太多規(guī)則和框架,也就沒有太多坑,本身代碼量小,需要深入了解去調(diào)試 Bug 或性能調(diào)優(yōu)時成本也低。
在 UI 層上目前 HTML + CSS 的方式開發(fā)效率是比手寫布局高的,React Native 也是用近似 HTML+CSS 去繪制 UI,這方面開發(fā)效率相對 JSPatch 會高一些,但 JSPatch 也可以借助 iOS 一些成熟的庫去提高效率,例如使用 Masonry,讓 UI 的開發(fā)效率不會相差太多。邏輯層方面的開發(fā)效率雙方是一樣的。
此外,React Native 在開發(fā)效率上的另一個優(yōu)勢是支持跨平臺,React Native 本意是復(fù)用邏輯層代碼,UI 層根據(jù)不同平臺寫不同的代碼,但 UI 層目前也可以通過 ReactMix 之類的工具做到跨平臺,所以UI層和邏輯層代碼都能得到一定程度的復(fù)用。而 JSPatch 目前只能用于 iOS 平臺,沒有跨平臺能力。
實際上跨平臺有它適用和不適用的場景,跨平臺有它的代價,就是需要兼顧每個平臺的特性,導(dǎo)致效果不佳。
跨平臺典型的適用場景是電商活動頁面,以展示為主,重開發(fā)效率輕交互體驗,但不適用于功能性的模塊。對 Android 來說目前熱更新方案十分成熟,Android 十分自由,可以直接用原生開發(fā)后生成 diff 包下發(fā)運行,這種無論是開發(fā)效率和效果都是好的。所以若是重體驗的功能模塊,Android 使用原生的熱更新方案,iOS 使用 JSPatch 開發(fā),會更適合。
JSPatch 也做了一些事情嘗試提高開發(fā)效率,例如做了 Xcode 代碼提示插件 JSPatchX,讓用 JavaScript 調(diào)用 Objective-C 代碼時會出現(xiàn)代碼提示,另外跟 React Native 一樣有開發(fā)時可以實時刷新界面查看修改效果的功能,目前仍在繼續(xù)做一些措施和工具提高開發(fā)效率。
React Native 和 JSPatch 都能對用其開發(fā)出來的功能模塊進(jìn)行熱更新,這也是這種方案大的好處。不過 React Native 在熱更新時無法使用事先沒有做過橋接的原生組件,例如需要加一個發(fā)送短信功能,需要用到原生 MessageUI.framework 的接口,若沒有在編譯時加上提供給 JavaScript 的接口,是無法調(diào)用到的。而 JSPatch 可以調(diào)用到任意已在項目里的組件,以及任意原生 framework 接口,不需要事先做橋接,在熱更新的能力上,相對來說 JSPatch 的能力和自由度會更高一些。
使用 React Native 和 JSPatch 性能上會比原生差點,但都能得到比純 H5 頁面或 hybrid 更好的性能和體驗。
JSPatch 的性能問題主要在于 JavaScript 和 Objective-C 的通信,每次調(diào)用 Objective-C 方法都要通過 Objective-C Runtime 接口,并進(jìn)行參數(shù)轉(zhuǎn)換。runtime 接口調(diào)用帶來的耗時一般不會成為瓶頸,參數(shù)轉(zhuǎn)換則需要注意避免在 JavaScript 和 Objective-C 之間傳遞大的數(shù)據(jù)集合對象。JSPatch 在性能方面也針對開發(fā)功能做了不少優(yōu)化,盡力減少了 JavaScript 和 Objective-C 的通信,GitHub 項目主頁上有完整的小 App Demo,目前來看并沒有碰到太多性能問題。
React Native 的性能問題會復(fù)雜一些,因為框架本身的模塊初始化/React 組件初始化/JavaScript 渲染邏輯等會消耗不少時間和內(nèi)存,這些地方若使用或優(yōu)化不當(dāng)都會對性能和體驗造成影響。JavaScript 和 Objective-C 的通信也是一個耗性能的點,不過這點上 React Native 優(yōu)化得比較好,沒有成為主要消耗點。
在性能和體驗問題上,兩者有不同的性能消耗點,從終效果來看兩者差別不大。
| 框架 | 學(xué)習(xí)成本 | 接入成本 | 熱更新能力 | 開發(fā)效率 | 性能體驗 |
|---|---|---|---|---|---|
| React Native | 高 | 高 | 中 | 高,跨平臺 | 高 |
| JSPatch | 低 | 低 | 高 | 中,不跨平臺 | 高 |
總的來說,JSPatch在學(xué)習(xí)成本、接入成本、熱更新能力上占優(yōu),而 React Native 在開發(fā)效率和跨平臺能力上占優(yōu)(見表 1),大家可以根據(jù)需求的不同選用不同的熱更新方案。JSPatch 目前仍在不斷發(fā)展中,后續(xù)會致力于提高開發(fā)效率,完善周邊支持,歡迎參與這個開源項目的開發(fā)。
本站文章版權(quán)歸原作者及原出處所有 。內(nèi)容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負(fù)責(zé),本站只提供參考并不構(gòu)成任何投資及應(yīng)用建議。本站是一個個人學(xué)習(xí)交流的平臺,網(wǎng)站上部分文章為轉(zhuǎn)載,并不用于任何商業(yè)目的,我們已經(jīng)盡可能的對作者和來源進(jìn)行了通告,但是能力有限或疏忽,造成漏登,請及時聯(lián)系我們,我們將根據(jù)著作權(quán)人的要求,立即更正或者刪除有關(guān)內(nèi)容。本站擁有對此聲明的最終解釋權(quán)。