從開始到如今,筆者接觸RN已經接近半年,適逢各類變化的發生,因而,簡單的遐想了一下RN的將來。javascript
Airbnb在今年早些時候,宣佈了放棄繼續使用RN,而且發佈了一篇「React Native at Airbnb: The Technology」的長篇博客,詳細的講了在airbnb中,使用RN的過程當中,本身的總結的一些經驗和一些痛點,鑑於國內網絡環境的緣由,筆者也簡單的轉載一下(限於筆者的英文水平,翻譯不確切之處還請批評指正):html
作得好的地方:前端
跨平臺、統一的設計語言系統(DLS)、React(特別是組件體系、簡單的生命週期和聲明式的寫法)、迭代速度、基礎設施上的額外開銷(如網絡、設備信息、i18n等)、性能、Redux、以native爲支撐(更強大的native能力)、靜態分析、動畫、js/React的開源、伸縮盒模型(基於yoga)、web端的合做。java
作得不是那麼好的地方:react
React Native的不成熟:雖然rn發展得很快,可是有欠成熟的它在某些具體的方面作得並很差,並且這種不成熟,沒法避免;android
維護React Native的分支:因爲rn的不成熟,須要咱們去fork本身並維護rn的代碼,可是這對於升級RN版原本說是很是恐怖的;ios
js的可用性:因爲js是一門弱類型語言,這致使在其餘工程師在學習和使用的時候很不便利,雖然咱們嘗試使用了flow和ts,可是效果並不理想(咱們將會繼續在web中使用ts);git
重構:js的弱類型特性致使了再項目重構時很是困難;github
JSC(javascriptCore)的不一致性:ios會使用統一的jsc,這並無什麼問題,可是在android上,因爲各廠商使用的jsc都不同,你頗有可能會使用默認的jsc(版本很是古老),web
並且,在調試的時候咱們一般都會使用chrome開發者工具,雖然這在99%的狀況下都是沒問題的,因爲在調試時js是跑在chrome的v8引擎中的,這致使了android調試時,其實運行的環境與咱們所指望的並不相同,這很大程度上增長了調試的難度;(筆者也曾碰到過Date對象的實現不一致的問題);
RN的開源庫:由於RN須要對各個平臺的熟悉,可是一般的用戶僅瞭解一到兩個平臺,這也致使了RN的開源庫在實際使用時,總會或多或少的碰到一些問題;(筆者也在切換打包工具時碰到了依賴庫模塊規範不規範的問題);
平行的基礎設施和功能:咱們積累大量的native基礎設施,可是在RN,這一切都須要從零開始,在很長的一段時間內,這其實對於咱們的工程師的開發效率是有很大的影響的;
crash監控:由於RN在行業中的特殊性,咱們不得不開發不少上報的基礎設施(如上傳sourcemap)等工具去幫助本來已經成熟的工具(如Bugsnag)來進行crash報告統計;
native bridge:因爲js的弱類型特性,致使在與native通訊時,本來的整形會被轉換爲字符串,而這些操做頗有可能會引發某個平臺的調用失敗或者崩潰,但在上層卻沒法得知;
初始化時間:在RN開始渲染前,你必須先初始化運行時,但這會花費至少幾秒的時間,這也使得RN APP的初始化時間很長;
初始化渲染時間:不像native的渲染,RN的渲染須要從主線程->js->yoga layout線程->主線程,才能完成渲染,而這一般又會消耗(P90 280ms in iOS 440ms in Android),
致使咱們須要採起一些hack手段來避免出現意料以外(顯示白屏)的狀況
app包大小:RN在包大小上也有一些無法忽略的影響,在Android上,整個RN的包大小(Java + js + native庫 + js runtime)已經接近8mb,再加上x86和arm,就已經12mb了;
64位:因爲這個issue,咱們至今未能在android上完成;
手勢:咱們一般都會避免在RN的應用裏使用複雜的手勢,由於iOS和Android對不一樣手勢是的實現和識別都有差別,且沒辦法統一;
長列表:雖然RN已經對長列表作了一些優化,好比FlatList,可是仍然有許多由於線程的緣由帶來的限制沒法解決;(好比快速滾動時view沒辦法同步刷新,Text元素無法預先計算高度等)
升級RN:RN升級過程當中,新版的RN有時候會依賴React的beta或者alpha版本,可是大部分的第三方庫並不會去支持這些「預發佈」的版本,這個升級也帶來了很大的麻煩;
無障礙訪問:RN無障礙訪問的API存在的很多問題,使得咱們不得不爲了一個很小的改動而須要fork一個獨立的RN版原本進行修改;
難以修復的crash:在使用中,咱們還碰到了一些沒法修復的crash;
跨進程保存實例狀態:在android上,因爲Android本身的機制它會根據設備的內存狀態結束位於後臺的進程(好比你的RN應用),當從新喚起的時候,你的app使用狀態將得不到保存,這一特性雖然能夠用redux的技術來fix,可是他並不能徹底結局問題,並且在某些狀況,甚至會引發崩潰。
其實Airbnb碰到的問題筆者大部分也碰到了,以前的文章也有說起《rn踩坑實踐——從輸入框「們」開始》、《RN持續踩坑實踐》、《RN心路歷程》,這裏就再也不贅述了。
總的來講,對筆者而言,RN更適合用在那種內嵌H5的且交互不會太複雜,並且並不要求全平臺一致的場景,而整個APP都要推RN,其實就筆者的經歷而言,並不算是一個很好的選擇。
另外,近幾個月flutter也進入了你們的視野,並且它所推崇的全平臺一致性也是一個很吸引人的特性。不過它是基於Dart的,固然對於native的同窗不用再寫js的也是件好事情,不過也因爲不在依賴js,也就摒棄了RN一直使用的jsc的一整套架構,而取而代之使用了基於google本身實現的渲染層api,來達到一致性的效果。甚至令筆者產生了一種「flutter纔是將來」的錯覺。
固然一切在沒有實踐以前都是霧裏看花,畢竟生態纔是一門技術是否可以持續發展的關鍵,如今談這些也許,還有點早。
其實整個前端圈子發展得愈來愈好,新事物層出不窮,將來,說不定Firefox OS相似的技術方案也會成爲主流也說不定。