本文總結:
🔹 運行機制
React Native 的運行機制基於兩個線程之間的通信(JavaScript 線程和 Native 線程),通過 Bridge(橋) 實現數據交互。🌉這使得 JS 邏輯與原生界面可以協同工作,實現流暢體驗。
🔹 優勢 👍
- 學習成本低,JavaScript 和 React 開發者可以快速上手
- 滿足大部分產品需求,適用於多數中小型 App
- 代碼複用性高,節省開發時間與人力成本
- 有大量 開源組件 和社區支持,發展活躍
🔹 哲學與設計理念 🧩
React Native 並不是完全跨平台,而是通過處理 Native 重疊部分來實現最大化複用代碼。它強調 “Learn once, write anywhere” 而不是 “write once, run anywhere”。
🔹 平台選擇的考量 🤔
文章也提到在選擇 React Native 還是原生開發時,需根據產品的實際需求、團隊技術棧、性能要求等因素綜合考慮。例如: - 對性能要求極高的應用建議使用原生開發
- 對開發效率和跨平台需求強烈的項目更適合 React Native
1、React-native的背景
🔹 背景與定義
React Native 是由 Facebook 創建的,基於 JavaScript 的跨平台開發框架,旨在幫助開發者使用一套代碼同時構建 iOS 和 Android 應用。🧠
Facebook 創建了 React-Native(RN)來構建 app。它最初是在2013年的夏天在 Facebook 內部的一個項目,2015年成為開源項目,是因為當時 React 在社區的呼聲很高,他們就覺得 React 是一個很好的UI 框架,那麼如果你想構建一個 native-app,為什麼不直接讓在 React 跑在移動端的操作系統上那!
因此,在同一年,Facebook 將 React分為兩個獨立的庫,也就是 React和 React-dom,可能大夥對這個概念還挺模糊的,我簡單解釋一下。
React: React 是一種用於構建用户界面的 JavaScript 庫。它是一個核心庫,用來創建 React 元素 (elements)、組件 (components) 和虛擬 DOM (Virtual DOM),並在應用程序中管理組件的狀態和生命週期。React 可以在客户端和服務器端使用也包括了React Native。
React-dom: React-DOM 是 React 庫針對瀏覽器的針對 DOM 操作的補充。React-DOM 提供了與 DOM 相關的功能,比如把 React 組件渲染到 DOM 中,處理用户交互等事件。
簡單來説,React 庫提供了一個基礎構建組件樹的庫,而 React-DOM 則為你提供了一些針對 Web 頁面的工具,如將組件渲染到網頁中,並支持通過事件響應來進行交互。
從那時起,React 就不用關心組件的渲染在哪個平台上。Web 平台的渲染由 ReactDOM 承擔,而移動平台的渲染由 RN 承擔。
2、什麼是React-native
RN 是一個基於 javascript 的跨端框架,RN提供了一套代碼多個平台運行的能力。它最開始解決的問題是,在安卓上,開發者需要實現一套Java app,又在ios, 需要實現Swift,我們就需要學習兩門語言,去實現一個完整的app。
那時候就感覺像是這樣的。
web開發者要了解HTML,CSS,JS,React安卓開發者要了解Java,Kotlin SDKios開發者要了解Object-c,Swift,CocoaPods.
而在R系大家庭中,React-native應運而生,引入一個新的platform去平替上者後2。它現在看起來是這樣的
這就是我前面講到的,React僅僅是管理Fiber樹,em或者説組件樹,而渲染交給了react-dom或者react-native。
我們進一步研究一下,究竟是如何在我們的app上跑的,rn其實是用React、Js去調用native組件然後構建app。例如,<Image/>組件代表了另外兩個本地組件, 安卓的ImageView、iOS的UIImageView。在這rn的架構中是由兩個線程控制的,一個js線程、一個native線程。
- 首先我先講一下
js線程的東西,我們先有個概念,舉個例子:我們的瀏覽器用虛擬引擎去執行js代碼就像是v8。意思就是我們的代碼如果要跑在rn上同樣需要一個虛擬引擎,去執行我們的api、處理我們的事件。在最開始就是ios內置的JScore這個引擎,但這個引擎在打包安卓的時候會把包搞大,又用不上,所以就在0.6這個版本後採用Hermes這個新引擎,在0.64後ios也採用這個引擎了,畢竟它確實更好,如下它的優勢。 - 更快的啓動速度。
- 更小的包。
- 內存使用更小。
與瀏覽器中一樣,rn中的JS是在單個線程中實現的。該線程負責執行JS。我們正在編寫的業務邏輯將在這個線程中執行。
這意味着我們所有的通用代碼,如組件、狀態、鈎子和REST API調用,將在應用程序的JS部分中處理。 - 那麼
native線程是做啥那,其實就是執行native代碼的地方,rn它在每個平台(java、oc、ios)上都去實現了這一部分,這個線程絕大部分的內容都是與安卓ios通信的sdk,同時為我們提供統一的api。 - 舉個例子:就是比如我調用一個
alert彈窗,native層就整合了2個平台提供了一個統一的api,然後我們在js線程中去調用他。實際上這是線程的交互,在native線程的角度來看,就我們要彈出個警告,他其實是兩個部分,Native ui去更新頁面,Native Moudles去訪問平台特有的功能。
上面我們説了一下兩個線程分別是幹啥的,緊接着就肯定離不開線程之間的通信,而這兩個線程之間的通信是通過橋(就這麼理解吧),這個橋是用C++寫的,並基於一個異步隊列。當橋從其中一方接收數據時,它將其序列化,將其轉換為JSON字符串,然後把它排在隊列中。
在到達目的地後,數據就被反序列化。
就以上面的alert為例,native接受來自JS的回調並顯示該對話框。實際上,JS方法在被調用時,向橋發送消息,並接收到到消息時,native執行指令。
本機消息也可以被轉發到JS。例如,單擊該按鈕時,native向js發送一個單擊事件消息。就大概像這樣:
大家應該很容易發現問題,就是因為所有的事件都依賴於異步的橋去完成通信,那可能會面臨就是説隊列負載過高,就導致的性能問題,但確實也存在,只能説有利有弊了,我們先留下這個懸念,後面再看看RN的架構中是如何處理這個問題的(下一篇再講新架構內容太多了)。
其實RN 使用就是使用異步回調去操作底層的移動端操作系統,也就是調用原生的api。rn有一個JavaScript引擎,並且RN API與Web的React基本相同,區別在於原生端;Rn是異步調用的原生API,而不是DOM。如圖所示:
RN使用與web上使用的相同React庫(也就是前面提到的React核心庫),並在JavaScriptCore中運行。- 發送到
Native api的消息是異步和批處理的。 -
RN附帶了為移動平台實現的組件,而不是HTML元素的組件.RN其實代表的是通過iOS和Android api渲染組件的方法。它可以用同樣的概念來在tvOS、電視、Windows、macOS,甚至是Web上渲染。
3、使用React-native的優勢
為React去實現一個新的渲染其實還挺難的,就大夥想象一下這就像發明一個可以運行在ios和Android的新的dom難度,但跨端應用還是不得不做,就我想了一下有這幾個原因吧。
- 最重要是還是需求催生了技術,因為移動端的巨大需求,而H5性能的不近人意(就是用户體驗差),而rn這種其實算是變相調用原生的
api會好很多。 - 然後就是
jsx,可能我對flutter的好感不如rn的原因就是因為這個吧,學習成本低了。 -
商業價值洛,這些年客户端混成啥樣不用我多説了吧(但從另外方面來説還是得要人做一些橋接的東西)。
4、自我感覺Rn的哲學
就這裏只談談自己對
RN的感覺。
怎麼説那?就是可能大家覺得rn,應該就是你可以用react的語法寫一個跑在任何原生設備上的應用。
但不行,因為ios和安卓在許多最基本的層面就是不一樣的,甚至它們的UX哲學完全不同(這其實也是ios好很多的原因),所以其實想寫一個不處理兩種情況的單一app其實還真不行。
簡單的説就是,rn不是實現一個組件庫讓你在任何地方跑,它處理的只是native重疊的地方。rn不是寫一次,就可以在任何地方跑(除非你完全不在意用户體驗),它應該説是學習一次,寫在任務地方。你需要在某些情況,用特定ios/安卓組件,去提供更好的UX(但其實rn已經幫你處理很多差異和提供很多通用基礎組件了,只是你可能需要腦子裏對平台差異有個類似於紅線認知的東西)
5、談談產品與app
對於用户來説,Web 應用的使用門檻遠低於 App。如果沒有強需求,大家通常並不願意安裝一個久未使用、圖標發灰的 App,而是更傾向於直接打開瀏覽器獲取信息,儘管 Web 的使用體驗可能不如 App 那麼好。那麼,當我們手頭有一個面向 C 端的產品時,應該如何選擇平台呢?
可選平台:
- PC Web
- 移動端 Web(手機、平板)
- 移動端 App
從產品規模和功能複雜度的角度來看: - 如果是一個功能複雜、邏輯重的大型產品,建議選擇 App,因為它能更好地控制性能、交互體驗與原生能力。
- 如果是功能輕量、單一的工具型產品,使用 移動端 Web 會更加靈活、快捷,也更適合冷啓動。
從技術角度來説,移動端瀏覽器確實缺乏許多移動 App 的能力,主要原因包括以下幾點:
一、UI 與交互差異
瀏覽器中的 HTML 元素無法與原生組件在交互與視覺體驗上保持一致。例如,一些 UI 設計會提出“在移動端展示覆雜表格”的需求,但實際上這違背了移動端輕交互的設計理念,體驗通常很差。
二、缺乏原生能力
移動 Web 無法很好地支持原生 App 中的高級功能,如原生手勢系統。Web 中的點擊事件只是單一的響應,而原生中,用户手指的滑動、長按、按壓等都由專門的系統處理,開發者只需關注邏輯即可。而在 Web 中實現這些,需要自己去監聽 touch 事件、處理手勢的 x/y 座標、時間等,開發成本高,效果也不穩定。
簡單總結:
移動端 Web 在 UI 和交互上難以與原生統一,不適合實現複雜交互,像“移動端上做複雜表格”這類設計在體驗上本身就不合理。
Web 應用缺乏原生能力支持,尤其在交互、手勢、動畫等方面難以還原原生體驗。因此,
平台的選擇要基於產品複雜度、目標用户習慣、開發成本和迭代速度綜合權衡。