當前位置:
首頁 > 科技 > Udacity也棄用React Native了!

Udacity也棄用React Native了!

作者|Nate Ebel

編輯|覃雲、無明

不久之前,Airbnb 團隊剛剛宣布放棄使用 React Native,才過了不到一個月,在線教育機構 Udacity 移動團隊最近也宣布從 App 中移除了使用 React Native 開發的最後一批功能。而 6 月中旬,Facebook 宣布將大規模重構 RN,這一系列的事件,讓不少正在使用 React Native 的開發者瑟瑟發抖,陷入了恐慌之中。

在本文章中,Udacity 團隊將告訴大家他們使用 React Native 的歷程以及放棄他們的原因,也希望給一些開發者一些參考和啟發,看自己是否適合使用 React Native。

以下來自 Udacity 移動團隊的自述:

Udacity 移動團隊

Udacity 的移動團隊分為 iOS 和 Android 兩個團隊。

團隊規模

在引入 React Native 時:

1 個 iOS 開發

2 個 Android 開發者

1 個項目經理

1 個設計師

現在:

4 個 iOS 開發者

3 個 Android 開發者

1 個項目經理

1 個設計師

在使用 React Native 的 18 個月中,我們的 iOS 和 Android 團隊規模都有所增長,整個團隊由一名項目經理來領導。

期間,我們還經歷了向多設計師和多設計範式轉型。

開發背景

在引入 React Native 時,我們 iOS 團隊唯一的開發人員非常樂於使用 React Native,這極大豐富了他之前 Javascript 和 Web 的開發經驗。兩位 Android 開發人員中的一位對 Javascript 有豐富的經驗,而另一個只有很少的 Javascript、React 或 Web 經驗。

現在,四個 iOS 開發人員中至少有三個非常樂於使用 Javascript 和 React Native。後來加入團隊的其他 Android 開發人員也只有很少的 Javascript 或 Web 經驗。

Udacity 的 App

用途

Udacity 的移動 app 旨在將 Udacity 的學習體驗帶到用戶的移動設備上。它支持身份驗證、內容發現、程序註冊(在某些情況還支持支付),以及消費各種類型的學習資料。

Udacity 的 App 也作為新的實驗性功能和旨在提升用戶整體學習效果的活動的試驗場。

代碼庫的大小

iOS:97,400 行(.swift、.h、.m)

Android:93,000 行(xml、java、kotlin、gradle)

Udacity 為什麼以及如何採用 RN ?

為什麼要引入它?

當時,Udacity 正準備推出全新的移動端專用功能。我們希望在兩個平台上快速進行實驗和驗證,因此跨平台具有很大的吸引力。

可以總結為以下幾點:

跨平台解決方案具有更高的可行性

大多數(2/3 開發人員)團隊成員非常適應 Javascript 和 Web 開發

可以提高開發速度

來自公司之外其他團隊的成功案例

Udacity 是如何引入的?

React Native 的初始特性是在一個單獨的 GitHub 代碼庫中構建的,然後作為 git 子樹分別併入 iOS 和 Android 代碼庫。

這樣可以進行非常快的原型設計,並且如果有必要,可以將某些功能作為獨立產品發布。

Udacity 團隊設計了很多原型,最終在 React Native 代碼庫中引入了第二個更大的功能。

時間線

2016 年 8 月:為功能 1 創建 React Native 代碼庫

2016 年 11 月:在 Android 上發布了功能 1

2016 年 11 月:開始開發功能 2

2016 年 12 月:設計功能 3 原型

2017 年 1 月:功能 1 開發結束

2017 年 2 月:功能 2 發布

2017 年 3 月:功能 3 原型設計結束

2017 年 11 月:在 Android 上更新功能 2

2017 年 12 月:功能 4 原型作為獨立 app 發布。最終由於性能問題取消了對原生的支持

2018 年 2 月:在 iOS 上更新功能 2

2018 年 4 月:從 Android 中移除功能 1

2018 年 6 月:從兩個 app 中移除功能 2

為什麼要移除 React Native?

原因很簡單。因為剩下的唯一一個 React Native 功能已經沒有用了,我們不再需要支持它。

或許這樣問會更有趣:「為什麼我們不繼續在 React Native 上投入,以便獲得新功能?」

此時,需要考慮幾件事:

1. 同時需要在兩個平台上構建的功能數量越來越少

2.Android 特定需求在增加

3. 對長期維護成本感到沮喪

4.Android 團隊不願繼續使用 React Native

用什麼來取代 React Native?

Udacity 移除的 React Native 功能不再受支持,所以不需要進行任何替換。

初次嘗試 React Native 給我們帶來哪些好處?

使用 React Native 進行跨平台構建非常容易

可以引入 React 和 Javascript 生態系統中的庫和工具

能夠同時在兩個平台上對功能進行原型設計

跨職能團隊中的單個開發人員能夠同時為兩個平台構建大部分功能

團隊對 React Native 的整體理解有所改善

遇到了哪些問題?

在使用 React Native 期間,我們遇到了很多問,主要在於流程、使用場景,React Native 本身的問題。

設計和體驗方面的挑戰

平台一致的 UI/UX

因為要往現有的體驗中加入一些新的頁面,所以我們希望新的 React Native 代碼能夠遵循原生平台模式和現有的樣式,這意味著我們不一定能為兩個平台使用相同的 UI 設計。

要在 React Native 中確保每個平台本身的樣式並不困難,但確實需要了解每個代碼庫的設計範式。至少需要對平台以及每個操作系統的自定義小部件進行檢查。

對於我們來說,通常需要與每個平台的開發人員和設計人員溝通,以便了解需求是什麼,否則如果兩個平台使用同一個樣式,有可能會導致在 Android 平台上的新功能體驗與 App 的其他部分截然不同。

在更複雜的情況下,需要使用一些額外的平台特定代碼來自定義 App 體驗。

確保回退圖標的行為是正確的就是一個例子。由於需要將新的 React Native 功能集成到現有的 app 中,要確保回退圖標和後退按鈕按的行為是正確的需要對 Android 原生代碼和 React Native 代碼做出特定的修改。

有一次,Android app 的導航結構發生了變化,我們不得不修改 React Native 代碼,只是為了要改變原生與 React Native 之間的集成方式。

React Native 不需要有自己的 Activity,我們把它們移到 Fragment 中,並放在帶有 BottomNavigationView 的屏幕中,然後在它和其他原生 Fragment 之間協調狀態。

這種類型的變更需要回到各自的代碼庫,做出更改,更新集成,並確保新的變更不會對 iOS App 產生負面影響。

設備特定問題

無論你要把這個叫作「碎片化」還是「多樣化」,我們仍然要面對這樣的事實:越來越多的 Android 設備有自己獨一無二的配置。

很多時候,我們發現布局無法完美匹配不同尺寸的 Android 手機,在最新的 iPhone 或 Pixel 設備上運行流暢的動畫在其他國家(在這些國家 Android 使用更為廣泛)的低端設備上運行不佳。

這些肯定不只是 React Native 的問題,它們是 Android 平台開發常見的問題。但隨著平台檢查方面的工作量以及需要考慮到的因素數量的增加,我們不得不開始考慮,React Native 到底可以為我們節省多少時間。

全球性增長

在我們使用 React Native 期間,國際化成為 Android 團隊的一個焦點。我們的幾個國際辦事處要求對 App 進行本地化,並減少 apk 大小。

React Native 的字元串本地化完全可以實現,儘管確實需要做出一些額外的設置。在我們的例子中,我們需要對代碼庫做出單獨的修改。這增加了本地化的複雜性,因為向其他團隊尋求本地化幫助並非理想的方式,同時也會降低 React Native 功能的本地化頻率。

我們能夠在一段時間內減少 apk 大小,但是 React Native 的大小可能會增加,對此我們無能為力。移除最後一個 React Native 功能後,我們的 apk 大小減少了約 10MB。

集成挑戰

與原生組件和導航結構的集成

根據我們的經驗,對於獨立的功能,將 React Native 集成到現有應用程序中可能非常簡單,但如果要與現有組件緊密集成和交互,則可能會麻煩一些。

我們經常需要大量的橋接代碼在原生和 React Native 組件之間進行通信。在 React Native 組件與現有導航結構集成的地方,每次發生變更時,都需要進行至少一次的橋接代碼更新。

工具 / 構建問題

集成 React Native 需要對每個 App 的構建過程做出變更。我們使用 CircleCI 來構建項目,因此需要對它進行重新配置,以支持額外的 React Native 構建步驟。

而在 Android 方面,它並不像我們所預期的那麼簡單。

在進行重新配置後,CircleCI 的構建時間增加了大約 20%。

從代碼庫中移除最後一個 React Native 功能後,我們看到了以下改進:

CircleCI 構建時間從 15 分鐘減少到 12 分鐘

發布的 apk 大小從 28.4MB 降至 18.1MB

Android 團隊也經常遇到 Android/Gradle 構建工具與 React Native 的衝突問題。

iOS 團隊也面臨著相當大的挑戰。

配置構建過程是一個很痛苦的事,因為我們的構建文件結構不是標準的。由於我們使用了單獨的代碼庫,我們在 srcroot/ReactNative 目錄中拉取 React Native 代碼庫,很多現有構建工具假設使用的是默認的 app 結構,即 /ReactNative/ios/…ios。

此外,我們使用 cocoapods 進行依賴管理,最初建議用它來管理 React Native 依賴,但後來被棄用。我們的非標準文件結構也給我們帶來了麻煩,我們不得不在 Podfile 中做一些令人討厭的侵入性修改,讓它從正確的位置讀取配置文件。

由於 cocoapods 不再是標準的 React Native 依賴管理方式,因此 Podfile 的更新只能依賴於社區,而這些更新通常不太同步。比如 css/Yoga 已經推出更新,但 Podfile 引用的卻是不正確的版本。最後,我們不得不做出一些侵入性的修改,使用 sed 和正則表達式來實現版本檢查和安裝。

iOS 項目的 CI 也是一個痛點。我們現在必須添加一個 npm 依賴層,並確保在安裝其他依賴之前它們是最新的。這給我們的構建步驟帶來了額外的時間消耗。

還有一個問題會導致構建崩潰,比如一個版本的 npm 有文件,而另一個版本沒有,這會導致我們在 React Native 升級過程中安裝了不正確的依賴版本。

來自 React Native 的挑戰

文檔

React Native 本身發展得很快,但文檔卻相對缺乏。特別是我們是第一次使用 React Native,我們發現特定版本的文檔多多少少有點不齊全。

那個時候,用於將 React Native 與現有項目集成的文檔似乎很少,因此,在對 CI 做出構建配置時,這無疑增加了我們的難度。

隨著 React Native 不斷發展,文檔和社區得到了改善。如果換到了今天,我們或許會更容易找到一些問題的答案。

導航

我們最初使用的是 NavigationExperimental,它不是最容易使用的導航庫。React Navigation 出現後,迅速在社區中流行開來,在 ReactNavigation 的功能得到真正的完善之前,我們已經棄用了 NavigationExperimental。

不過,如果不把一些東西強行組合在一起(例如在呈現模態流中推送流),有些事情在 ReactNavigation 中是做不到的。

性能

如前所述,我們也會注意到性能問題。

我們能夠製作出一些非常漂亮的動畫,這些動畫在高配置的 iOS 和 Android 設備上看起來很棒,但在一些低配置 Android 設備上表現不佳。

進入 app 的 React Native 部分時,載入時間比我們預期的要長,而且它們看起來不像是無縫的過渡。

在對功能 4 進行原型設計時,圖形渲染性能是一個非常大的問題,我們不得不使用原生體驗取代了 React Native。

滯後於原生平台

因為它不是與 iOS 或 Android 一起構建的,所以 React Native 有時會滯後於原生平台。在很大程度上,它依賴社區來提供新的原生功能。

其中一個例子就是迫切需要為 iPhone X 提供安全區域支持。我們最終選擇在短時間內不使用 SafeArea,因為 React Native 團隊很快就會推出該特性。跨平台開發人員在使用 SafeAreaView 開發兼容性 app 時需要特別注意這個特定於平台的特性。

有時候,React Native 也會在採用新平台需求方面表現滯後,例如 Android app 被要求在 2018 年 8 月之前採用 API Level 26。而在這方面還有幾個未解決的問題。

突破性的更新

React Native 無法向後兼容,這點非常令人沮喪。比如,在 React Native 升級了它的底層 React 庫後,PropType 就被棄用了。

如果我們不維護自己的分支,很多第三方庫就會變得無法使用。

來自維護方面的挑戰

有時候,維護 React Native 代碼庫對我們來說是一個挑戰。如前所述,Android 通常需要額外的工作,無論是與現有代碼集成還是修復 UI 問題。這導致 iOS 和 Android 使用了不同的 React Native 代碼庫分支,這樣才能讓兩個平台之間不互相影響。

由於使用了不同的分支,開始出現代碼分歧,並且用於解決衝突的工作流增加了。結果,對一個平台的更新並不會立即被添加到另一個平台中。

React Native 的演化速度也給我們帶來了挑戰。由於可能會出現突破性變更,因此為了獲得新功能或修復 bug 而進行的依賴更新的速度變慢了。

另外,有時這會導致摩擦力增加,從而降低了代碼的維護速度。由於團隊規模小,帶寬有限,如果不是簡單的、可以快速修復的問題,那麼問題就不太可能很快得到解決,因為這可能需要額外的開發工作量。

因為引入了 React Native,所以我們並不總能清楚地知道 bug 處於什麼級別。它是否存在於兩個平台中?還是只在一個平台上出現?如果只在一個平台上出現,是在原生代碼中還是在 React Native 代碼中?這些問題所帶來的複雜性有時候會減慢 QA 過程。

當需要修復 React Native 代碼庫中的問題時,我們現在必須同時考慮 iOS 和 Android,並且可能需要使用 3 個開發棧,而不是 1 個。

此外,不是所有人都覺得 React Native 效率很高,能夠迅速上手並修復問題的開發人員的數量也減少了。

我們本該可以做哪些事情?

我相信,我們遇到的一些問題是我們的場景所固有的,但是我們其實可以做些不一樣的事情來緩解其中的一些問題。

減少代碼分歧

我們本可以更好地讓 React Native 代碼庫中的變更與每個平台的 App 保持同步。我相信保持這些更新同步將有助於增強我們的跨平台開發意識。

多在設備上進行測試,特別是在 Android 上,可能可以在早期就發現更多的 UI 和性能問題,並在發布之前修復它們。在開發新功能之前解決舊問題,可以減少代碼分歧的數量。

更一致的設計

如果從一開始就設計更具體方案可能有助於改善功能的原生外觀。比如使用與原生 App 一致的文本和邊值,而不是使用新值,並在兩個平台上使用它們。

團隊成員需要學習

對 React Native 不太熟悉的團隊成員可以更努力地嘗試融入新的開發棧,這樣就會有更多的人能夠快速解決問題。

適用 React Native 的場景?

我相信,我們團隊中沒有人會認為 React Native 一無是處。我當然相信 React Native 有它適合的場景。

你是否需要在兩個平台上從頭開始快速地構建新 app?

你是否正在開發一個 App 或功能,要求在不同的平台上具有相同的外觀和行為?

你的 Javascript 開發人員是不是有多餘的時間可用於開發移動應用?

如果對這些問題中的任何一個答案「是」,那麼 React Native 很可能適合你。

特別是如果你有 Javascript 和 React 經驗,並且正在尋找一個不需要太多原生代碼就能構建的應用程序,那麼 React Native 是一個非常有吸引力的選擇。這樣你就能夠馬上開始開發,而無需去學習 2 種不同的技術棧。

對於新開發的完全跨平台的 app,React Native 也是一個很好的選擇。

還會再次使用 React Native 嗎?

OS 和 Android 團隊有不同的意見。

iOS

有可能。iOS 團隊通常很樂意使用 React Native,並考慮使用它開發新功能。此外,在產品方面,我們的 PM 對在 iOS 上運行 React Native 比對 Android 更有信心。

Android

不會。理想情況下,Android 團隊將來不會繼續在 React Native 上投入。我們發現與 React Native 組件集成的過程很麻煩,並且在 Android 設備上的體驗達不到預期。

此外,還有一種傾向,堅持使用單一的開發棧,而不是在 Android 框架之上添加新的抽象層,或引入可能的錯誤。

我們的印象是,使用 React Native 開發 Android 新功能的速度更快,但長期來看,新功能從早期階段到能夠完美髮布需要更長的時間。

關於使用另一種跨平台解決方案?

從團隊方面來看,在不久的將來,我們可能不會在跨平台開發上繼續投入。iOS 團隊可以使用 React Native 構建一些特定於 iOS 的東西,因為他們通常更喜歡這種體驗。

就個人而言,團隊的成員將繼續關注 React Native 和 Flutter。隨著 React Native 和 Flutter 等解決方案的不斷發展,我們也將繼續對它們做出評估。

我們對 React Native 是否適合我們的團隊和路線圖有了更好的理解。在進行技術選型時,我們可以利用這些信息做出更加明智的決策。

我們看到了 React Native 的優點以及局限性。我們能否明確地給出 React Native 是否適合你的定論?

不能。

但是,在評估 React Native 是否可用在你們的項目中時,希望我們的經驗可以作為參考。

英文原文

https://engineering.udacity.com/react-native-a-retrospective-from-the-mobile-engineering-team-at-udacity-89975d6a8102


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 InfoQ 的精彩文章:

業務要衝向國際化,我們能做哪些最佳準備
Pivotal應用無憂Spring實戰營

TAG:InfoQ |