Categories
程式開發

Shopify:用React Native打造移動應用開發的未來


Shopify開發原生移動應用多年之後,我們決定完全轉向React Native來構建所有新的移動應用。做出這個決定並非易事,下面我會做具體解釋。

無論是哪個季度,大多數消費者都是在移動設備上下單的(去年第三季度,我們有71%的顧客通過移動設備下單)。黑色星期五(Black Friday)和電商星期一(Cyber​​ Monday)(兩者以下合稱BFCM)是Shopify平台商家一年中最繁忙的日子,這期間消費活動最為活躍。在今年的BFCM中,Shopify商家在移動設備上的購買量又增加了3%,​​​​平均佔銷售額的69%

那麼為什麼要切換到React Native?為什麼現在切換?這一變化是如何融入我們的原生移動開發流程的?答案很複雜,我在回答這些問題之前需要先交代一些背景情況。

Shopify在2019年之前的移動開發情況

Shopify的工程文化之一,是押注某些早期技術來幫助我們快速發展。

總體而言,我們更喜歡選擇少數技術打造工程基礎。這為我們提供了很多好處:

  • 我們在少數幾種深度技術中建立了非常突出的專業能力(我們經常成為核心貢獻者);
  • 每種技術選擇都有其怪癖,但我們都能深度了解這些怪癖;
  • 非早期團隊成員也能貢獻、傳遞和維護他人編寫的代碼;
  • 新人上手更快。

與此同時,新技術層出不窮,為我們提供了逐漸提升生產力或能力的機會。我們做了很多嘗試,找機會獲得大幅度的改進——但到頭來,我們在核心工程中很少採用這些改進。

當我們採用這些處於早期階段的語言或框架時,我們就是在下經過計算的賭注。我們沒有逃避風險,而是根據自身的一系列條件來精心研究、探索和評估此類風險。新技術的風險往往是隱藏其中的,與此類似,許多未開發的機遇也需要我們去探索。我們考慮的是該如何減輕這些風險的威脅:

  • 如果某項技術不再被其核心團隊支持怎麼辦?
  • 如果遇到無法修復的錯誤該怎麼辦?
  • 如果產品的發展方向與我們的利益衝突怎麼辦?

當Tobi(我們的首席執行官)於2004年成為Ruby on Rails的核心貢獻者時,Ruby on Rails還是一個年輕且難用的框架。過去很多年,Ruby on Rails都被視為一種不夠嚴肅且性能不佳的語言。儘管它不是一種主流的技術選擇,但早期階段投下的賭注使Shopify擁有了超越競爭對手的能量。選擇Ruby on Rails後,團隊就可以使用比傳統編程語言和框架更現代、更抽象的工具來更快地構建軟件,並吸引眾多不同領域的人才。 Paul Graham也談到了他決定使用Lisp構建Viaweb的決策,這一決策產生了類似的效果;另外,當今10家最有價值的Y Combinator孵化​​企業中有6家都在使用Ruby on Rails(不過要再說一遍,它還是很不受歡迎)。相比之下,前十大最有價值的Y Combinator孵化​​企業中沒有一家在使用Java,而Java被廣泛認為是久經沙場的企業級語言。

兩年前Shopify又做出了類似的選擇,決定轉向Google Cloud。對於在2019年美國排行第三大的電子商務零售網站來說,這又是一項令人恐懼的提案——從我們自己的數據中心遷移到雲已經是艱難的決定,而選擇一家處於早期階段的雲提供商則同樣危險。當時我們看到了產業價值鏈中的技術發展趨勢,所以開始專注自己所擅長的工作——也就是發揚企業家精神來改進業務,而讓其他人(在這裡指的是Google Cloud)負責維護物理硬件、電力、安全性和操作系統更新等同質化的繁重勞動。

React Native是什麼?

2015年,Facebook發布並開源了React Native,當時它已經在FB內部被用於移動工程了。 React Native是使用React構建原生移動應用程序的框架。這意味著你可以使用一流的JavaScript庫(React)來構建自己的原生移動用戶界面。

在Shopify,這個想法在當時(並且現在仍然)面臨許多質疑,但是許多人看到了它的前景。在公司的下一個Hackday中,全公司都抽時間來研究React Native。儘管早期團隊看到了這個框架的很多好處,但他們判斷我們在2015年無法使用React Native製作出足以讓我們自豪的應用來。這主要是因為性能表現不佳和缺少一流的Android支持。而我們當時了解到的事實是,我們的確喜歡響應式編程模型和GraphQL。另外,開始使用React Native之後我們為iOS構建並開源了一個函數式渲染器。在2015年,我們將這些技術加入了自己的原生移動開發技術棧,但沒有將React Native用在完整的移動開發工作中。 《環球郵報》在介紹我們初代移動應用的深度報導中提到了我們的願景

到目前為止,Shopify上所有移動開發的標準都是原生移動開發。我們建立了分別專注於iOS和Android的移動工具鏈和基礎團隊,以加快我們的開發工作。儘管這些團隊和產出的應用程序都取得了成功,但也有人認為如果我們能夠做到下列事項,那麼團隊效率可能會提高:

  • 將JavaScript和Web的力量帶入移動開發領域;
  • 在所有客戶端應用程序中採用響應式編程模型;
  • 將我們的iOS和Android開發工作整合到一個技術棧中。

React Native的工作機制

React Native提供了一種使用JavaScript構建原生跨平台移動應用程序的方法。 React Native與React類似,它允許開發人員在JavaScript中創建聲明式用戶界面,為此它在內部創建一個UI元素的層次結構樹,用React術語來說就是創建一個虛擬DOM。儘管ReactJS的輸出以瀏覽器為目標,但React Native使用平台原生綁定將虛擬DOM轉換為移動原生視圖,這些平台原生綁定使用JavaScript對接應用程序邏輯。就我們的需求而言,目標平台只有Android和iOS,但是RN社區已努力將React Native引入了其他平台,例如Windows、macOS和Apple tvOS等。

Shopify:用React Native打造移動應用開發的未來 1

ReactJS的目標是瀏覽器,而React Native的目標可以是移動API。

在什麼情況下我們不會選擇React Native?

在某些情況下,React Native並不是Shopify構建移動應用的默認選項。比如說如果我們有以下需求:

  • 在較舊的硬件(CPU <1.5GHz)上部署
  • 複雜的處理過程
  • 超高性能
  • 許多後台線程

提醒一句:包括許多開源SDK在內的底層庫還會是純原生的。需要接近硬件層時,我們都可以創建自己的原生模塊。

為什麼現在轉向React Native?

這三大因素決定了現在是做出這一決策的好時機:

  1. 我們在2018年收購了Tictail(一家移動優先的公司,完全專注於React Native),從中了解到了React Native的發展情況,並在2019年進行了3項深度產品投資;
  2. Shopify在Web端廣泛使用React,現在這一部分的知識就可以在移動端利用上了;
  3. 我們看到性能曲線是向上彎曲的(想想現在Google Docs和桌面端Microsoft Office中的能力對比),並且我們可以像在Ruby、Rails、Kubernetes和Rich Media中那樣對React Native進行長期投資。

2019年Shopify的移動開發情況

Shopify擁有許多移動平台,供買賣雙方通過Web和我們的移動應用進行交互。去年,我們花了一些時間由三支獨立的團隊在三款應用上針對React Native進行了實驗:這三款應用分別是Arrive、Point of Sale和Compass。

從這些實驗中我們了解到:

  • 在React Native中重寫Arrive應用時,團隊認為自己的生產力是使用原生開發時的兩倍——即使只在一個移動平台上對比也是如此;
  • 在Android硬件的低功耗配置上測試Point of Sale應用時,我們設置的CPU閾值比之前想像的還要低(1.5GHz對2GHz);
  • 我們之前估計iOS和Android之間約有80%的代碼可以共享,結果實踐中的超高水平震撼了我們——95%(Arrive)和99%(Compass);

順便說一句,即使我們決定使用React Native來構建所有新應用,這並不意味著我們會自動開始在React Native中重寫那些舊應用。

Arrive

在2018年底,我們決定用React Native重新編寫我們最受歡迎的消費類應用之一,Arrive。 Arrive是一款評價頗高、表現出色的應用,在iOS上擁有數百萬的下載量。它是很好的候選者,因為它之前沒有Android版本。這一努力將幫助我們滿足所有渴望獲得Arrive的Android用戶的期待。現在,iOS和Android上的Arrive都是基於React Native開發的,並且共享95%的代碼。我們將在以後的博客文章中深入探討Arrive。

到目前為止,這次重寫帶來了以下結果:

  • 與原生iOS應用相比,新版本在iOS上的崩潰次數更少;
  • 推出了Android版本;
  • 由移動+非移動開發人員組成的團隊。

團隊還想出了一種很酷的方法來立即測試進行中的拉取請求。你只需從手機上掃描一條自動Github註釋中的QR碼,JavaScript包就會更新到你的應用中,現在你運行的就是從這個拉取請求中獲得的最新代碼。我們的首席技術官JML最近在Twitter上分享了這一過程

Point of Sale

在2019年初,我們在自己的旗艦級Point of Sale(POS)應用上展開了為期6週的實驗,想要知道它是否適合用React Native重寫。我們學到了很多東西,其中包括我們的零售商家期望的POS響應能力幾乎是之前的兩倍,因為使用這款應用時會養成肌肉記憶,需要邊操作應用邊同顧客交流。

為了給我們的零售商提供最好的服務,並在實體零售環境中了解React Native的能力,我們決定在iOS上原生構建新版POS,並在Android上使用React Native。

我們選擇由兩支團隊並行推進,主要出於以下原因:

  1. 我們已經有了一支具備iOS專業知識的團隊,其中有許多成員參與構建了原始POS應用;
  2. 我們希望能與原生iOS這一黃金標準對比,對React Native的工程速度以及應用性能進行基準測試;
  3. 為了滿足商家的高性能需求,我們覺得應該在項目啟動前等待Facebook對React Native做完所有架構更新(事實證明,這些更新對我們的性能場景而言並不重要)。在兩個平台上擁有兩支團隊,降低了我們啟動項目時面臨的風險。

我們在Unite 2019上宣布了開始對POS做全面重構。預計原生iOS和React Native Android應用都將在2020年發布!

Compass

Shopify Start團隊的任務是幫助創業新人。在公司做出全面決策,準備在React Native中編寫所有移動應用之前,這支團隊深入研究了原生、Flutter和React Native這些可能的技術選項。他們最後選擇了React Native,並在應用商店中上線了iOSAndroid應用(測試版)。

Compass的第一批版本(iOS和Android)只用了不到3個月就發布了,iOS和Android版本之間共享約99%的代碼。

Shopify在2020年之後的移動開發規劃

我們在2020年有很多計劃。

我們會重寫那些原生應用嗎?不,這是需要由每個應用團隊獨立做出的決定。

我們會繼續僱用原生開發工程師嗎?是的,需要很多!

我們希望為React Native內核做出貢獻,構建平台特定的組件,並繼續了解每個平台的精妙之處。這需要深厚的原生專業知識。

合作與開源

我們認為構建軟件是一項團隊運動。我們認同開放Web、開放源碼和開放標準。

我們正在讚助Software Mansion和Krzysztof Magiera(Android 版React Native的共同創始人),支持他們圍繞React Native進行開源工作。

我們正在與William Candillon(Can It Be Done in React Native的主持人)合作進行架構審查和性能改進。

我們將與Facebook的React Native團隊緊密合作,研究自動化、第三方庫以及通過Lean Core管理某些模塊主題。

我們正在與Discord合作,以加快FastList for React Native(一個僅渲染視口中列表項的庫)的開源進程,並針對Android進行優化。

React Native的開發工具鍊和基礎

當你下註一項技術並深入研究它時,你希望從這一選擇中獲得最大的效用。為了使我們快速構建並獲得最大效用,我們設置了兩種類型的團隊來幫助Shopify的其他團隊快速構建。第一個類型是工具鏈團隊,可以幫助他人進行工程設置、集成和部署。第二個類型是基礎團隊,專注於SDK、代碼重用和開源。進入2020年,我們已經開始讓這兩支隊伍都轉變方向,專注於React Native。

Shopify Ping應用僅在iOS平台上就處理了數十萬次客戶對話。 2020年,我們將在舊金山辦公室使用React Native構建它的Android版本,目前正在為此招聘人員)。

在2019年,Twitter使用稱為React Native Web的東西發布了他們的桌面和移動Web應用。雖然這項技術有點令人困惑,不過它允許你為Web應用使用相同的React Native技術棧。 Facebook為該項目聘請了首席工程師Nicolas Gallager。在Shopify,我們將在2020年進行一些React Native Web的實驗。

作者介紹:

Farhan Thawar是Shopify的渠道和移動業務副總裁。

原文鏈接

https://engineering.shopify.com/blogs/engineering/react-native-future-mobile-shopify