透視 Flutter 的 Add-to-App:解鎖我們的生產力


摘要

本文探討了 Flutter 的 Add-to-App 模式如何轉變為一種強大的生產力工具,幫助開發者應對複雜應用的挑戰。 歸納要點:

  • Flutter Add-to-App 的微服務架構能透過 gRPC 等高效通訊協定,實現模組化開發,降低耦合性並提升維護效率。
  • 深入分析 Flutter 與原生程式碼的性能瓶頸,提供具體的優化策略,助力開發者克服效能挑戰。
  • 利用動態配置和 A/B 測試功能,加速產品迭代,同時確保應用安全性與穩定性。
透過有效的架構設計、性能優化及靈活測試策略,Flutter Add-to-App 提供了一個全面且高效的解決方案,以滿足當前快速變化的市場需求。

Flutter 的 Add-to-app 功能使得 Flutter 能夠部分整合進入現有的原生應用程式中。2023年2月,Money Forward ME 在一項新服務發布中採用了 Add-to-app。在超過一年的開發過程中,此方法提升了整體生產力,透過統一 iOS 和 Android 的實現方式,減少了應用規劃和設計等任務。Add-to-app 也增強了 iOS/Android 工程師與其他團隊之間的溝通與合作。本文將詳細說明我們如何成功引導專案完成這一開發過程。

Flutter 是一個由 Google 開發的開源軟體開發工具包(SDK)。它最大的優勢在於能夠從單一程式碼庫中開發可同時執行於 iOS 和 Android 的跨平台應用程式,這樣不僅降低了開發成本,同時也確保了使用者介面和使用體驗的一致性。許多現有應用程式已經作為原生 iOS 或 Android 應用進行開發。在像我們的服務這樣的大型專案中,如果運營已久,完全重新構建所有內容以使用 Flutter 並不是一件容易的事情。在這種情況下,一種可行的方法是透過名為「Add-to-app」的技術,將 Flutter 部分引入現有的原生應用中。


Add-to-app 是 Google 開發的一個官方 Flutter 功能,它使得將基於 Flutter 的功能整合到現有的原生應用程式中成為可能,無論是作為庫還是模組。這項技術允許在不同平台之間共享介面渲染和業務邏輯。我們採用了 Add-to-app 方法,將 Flutter 整合進 Money Forward ME 應用程式中。

在 2022 年夏季,就在我們的新專案啟動之前,我們開始對 Flutter 進行技術驗證,目的是提升開發效率。同時,在那個時候,我們在專案的各個流程中也面臨了一些需要解決的問題,從規劃到測試均存在挑戰。


跨平台App開發:小團隊資源分配與效率提升策略

在規劃過程中,主要挑戰是如何在不同平台間平衡資源分配。我們的行動應用程式工程團隊人數不多,通常每個平台僅有2到3名成員。在這種情況下,為每個專案維持iOS與Android工程師之間的資源均衡分配變得相當困難。曾經有一個專案團隊只有我一位可用的iOS工程師,而沒有任何Android工程師。

在設計階段,各平台的規格是分開管理的。iOS應用程式遵循Apple的人機介面指導原則,而Android應用則依賴Material Design,使得UI/UX有著截然不同的基本指導方針。因此,像Figma檔案這類設計檔案也呈現出差異,加重了設計師的負擔。設計師還必須定期與iOS和Android工程師溝通設計事宜。

跨平台開發策略與資源最佳化:微服務架構與統一設計系統的應用針對文中提及的資源分配挑戰,業界頂尖專家常探討如何利用微服務架構提升效率。將iOS和Android應用程式拆解成獨立的微服務,可以更有效率地分配資源。例如,負責使用者驗證、資料儲存等核心功能的微服務可以共用,而UI/UX呈現則可根據平台差異獨立開發。這能讓小團隊更專注於各自擅長的平台,避免因人員不足導致延遲。匯入統一設計系統(Design System)也能減輕設計師負擔。建立一套涵蓋iOS和Android平台的設計規範、元件庫和樣式指南,可以確保設計的一致性並減少重複性工作。

低程式碼/無程式碼平台與自動化測試整合應用:加速開發週期與提升品質文中提及的一位單一iOS工程師窘境突顯了開發速度與人力資源之間矛盾,因此最新趨勢是匯入低程式碼/無程式碼(Low-code/No-code)平台搭配自動化測試系統。這些工具允許開發者以更少程式碼完成更多功能,有效縮短開發時間,同時減輕單位工程師所承擔壓力。例如使用Flutter、React Native等框架或特定領域內低程式碼平台,都能顯著提高效能。同時,自動化測試系統非常重要,它可以自動執行測試流程並及早識別潛在問題,以降低錯誤風險,提高軟體品質。這不僅解決了單一工程師所面臨困境,也有效降低因人為錯誤造成風險。因此,相較於傳統方法,此策略提供了一種新穎而高效的方法來最佳化小型團隊在跨平台應用程式中的開發流程。

跨平台行銷資料整合:解決資料不一致性與提升量測精準度

測量行銷成效的過程同樣面臨一定挑戰。過去曾發生過 Firebase 事件日誌在 iOS 上可被測量但在 Android 上無法的情況,反之亦然。這些差異源於行銷人員與工程師之間,以及工程師彼此之間的溝通不足。除了上述資源問題外,工程師的偏好及缺乏有效的溝通也影響了開發的各個方面。在本應該統一結構化的領域中,差異依然存在。例如,iOS 使用 Bitrise 作為持續整合(CI)工具,而 Android 則使用 CircleCI,同時 OpenAPI 僅在 iOS 上引入。在這樣的情況下,建立一種知識共享和互相支援的文化對於工程師來說是相當困難的。

針對跨平台行銷資料收集的不一致性,其根本原因就在於團隊協作與技術架構碎片化。雖然 Firebase 是常用工具,但其本身並不能保證消除所有平台上的差異。因此,更高層次專家需要深入探討如何建立一個統一且一致性的資料收集與分析架構,以超越單一平台工具所帶來的限制。

在資料層面上需要進行標準化:建立涵蓋 iOS 和 Android 的統一資料模型(Data Model),明確定義關鍵行銷指標(KPI)及事件(Event)的標準名稱、屬性和資料型別。還需跨部門合作,共同制定嚴格的資料定義規範並使用統一的資料字典。

在後端基礎架構上,需要整合不同 CI/CD 工具所造成版本差異及資料同步問題,例如避免分別使用 Bitrise 和 CircleCI。理想狀態下應建立統一的 CI/CD pipeline,以實現程式碼、配置及資料的一致性,此舉可能需要採用更強大的雲服務,如利用 Google Cloud Platform (GCP) 或 Amazon Web Services (AWS) 的無伺服器架構以達到跨平台資料整合和分析。

要實現即時監控資料流:必須搭建即時資料流管道,以監控資料收集中的完整性和一致性。一旦發現任何資料差異,系統應自動發出警報,使得工程師和行銷人員能夠立即處理此問題。在這方面,可運用先進的資料監控技術,例如 Prometheus、Grafana 等工具。

引入先進分析技術也是不可或缺的一環,不僅要超越簡單 Firebase 的事件追蹤,更需匯入更精細化的資料分析技術,如機器學習模型,自動偵測潛在資料偏差及異常情況。

在解決因工程文化導致的不一致性方面,我們應當著手從兩個層面入手:首先是建立知識共享的平台以及標準化流程,引入知識管理系統(如 Confluence、Notion),鼓勵工程師分享程式碼、檔案和經驗;同時設立標準化開發流程、程式碼審查機制以及資料驗證流程,以減少人工錯誤與主觀偏見。OpenAPI 的引入不僅是一項技術選擇,更是提升團隊溝通效率的重要步驟,有助於促進資料的一致性。

另外,也要培養以資料驅動為核心的工程文化,把資料資訊融入日常工作中,使得每位工程師都能夠利用資料評估其工作成果,並根據反饋持續改進。這要求設立明確目標與指標,並定期進行評估與回顧。同時,將營銷部門代表納入每日站會,可以促進直接溝通,從而提前發現並解決問題。

透過以上幾點,我們可以全面提升跨平台行銷成效量測效率與準確度,不僅解決表面的技術問題,更加深刻地改善團隊協作與組織文化。

我們的原生應用程式越來越難以採用新技術。即使現在,為了滿足我們多樣化客戶群的需求,我們仍需支援多個作業系統版本,這導致最新原生作業系統技術的採用延遲了 2 到 3 年。由於我們的服務 Money Forward ME 自公司成立以來便一直存在,因此在某些時候維護舊有程式碼——例如 iOS 的 Objective-C 和 Android 的 Java——仍然是必要的。這些挑戰不僅對工程師的職業發展造成困難,也影響到招聘工作。

測試問題與設計相似,因為測試場景必須針對 iOS 和 Android 進行區分。質量保證工程師需要諮詢每位工程師以了解詳細規格,以掌握不同平台之間的差異。當我們考慮作為移動工程師如何解決上述問題時,我們意識到跨平台開發——最初被視為提高開發生產力的手段——在解決所有這些問題上將會是有效的。


大型軟體開發的挑戰與 DevOps、AI 驅動的解決方案

單純增加工程師人數或許能提升開發生產力,但這並不會輕易解決在開發階段之外出現的問題。跨平台開發也不是一件容易的事。根據我的經驗,在技術驗證階段看似無法察覺的問題,往往會在生產開發開始後浮現。像 Money Forward ME 這樣的大型服務中,不僅僅是工程師,還有許多其他團隊成員參與其中,而新功能不斷釋出。在這種環境下,如果選擇全盤替換而不加仔細考量,很可能會導致其他正在進行中的專案停滯。

因此,業界正積極推動 DevOps 與平台工程的整合,以應對上述挑戰。這項策略不再僅聚焦於開發階段,而是將開發、測試、部署及監控等各個環節串連起來,形成一個自動化且持續整合/持續交付(CI/CD)的流程。透過平台工程建立內部開發平台,可以提供標準化的基礎設施、工具和流程,使得工程師能更快速且一致地交付軟體,有效降低跨平台開發時所面臨的複雜性與風險。

針對大型服務如 Money Forward ME,此方案可透過模組化設計和微服務架構,使不同團隊能夠平行進行開發、部署及維護,從而減少新功能釋出對其他專案造成的影響。成功實施此方案關鍵在於組織文化和流程的深刻變革,需要強大的 DevOps 文化支援,以及持續投入資源以建設和維護相關的平台。

在多團隊協作之下,新功能釋出的風險亦不可忽視。因此結合 AI 技術進行預測性維護和風險管理已成為重要趨勢。透過機器學習模型分析大量歷史資料,例如程式碼提交、測試結果、錯誤日誌及使用者回饋,可以預測潛在程式碼錯誤與效能瓶頸,以及新功能釋出後可能帶來的不良影響。

AI 驅動的預測性維護可以提前識別高風險程式碼,以降低後續修復成本;同時評估系統穩定性,以便早期偵測潛在問題並制定相應策略;最終量化新功能釋出的風險,使團隊能做出更明智的決策。對於像 Money Forward ME 這樣的大型服務而言,此方法能有效減少意外停機時間,提高服務穩定性,同時降低新功能釋出帶來的系統風險。要確保此方法成功執行則需依賴資料品質及模型準確度,因此需要專家團隊持續最佳化模型並進行驗證。同時,也必須注意的是 AI 並非萬靈丹,其效用仍需結合人工專業判斷才能最大限度地展現。


Money Forward ME:Flutter Add-to-App 整合最佳實踐與效能提升策略

因此,為了在短期內解決專案問題,同時確保中長期的成功,我們決定採用 Add-to-app 方法引入 Flutter。由於 Add-to-app 並不是一種標準的開發方法,因此官方文件中的資訊有限,我們必須自行構建並驗證。在 Money Forward ME 的專案中,我們重點驗證以下幾個關鍵點:

1. 使用 Flutter 建立的螢幕和商業邏輯可以從原生應用程式呼叫。
2. 重要資料,例如登入會話,可以與原生應用程式共享。
3. 需要特別在原生應用程式上實現的 UI 元件可以在 Flutter 螢幕上呈現。
4. 在除錯過程中,可以像標準的 Flutter 應用開發一樣使用熱過載和熱重新啟動。

僅僅引入 Flutter 並不會自動提高開發生產力。只要我們作為團隊合作,確保每個人都能寫出盡可能一致的程式碼是至關重要的,無論技術能力或經驗年限如何。為此,我們根據特定架構和共通規則建立了開發模板檔案。

**1. Add-to-App 的效能與穩定性最佳化策略及跨平台差異探討:** 文中提及使用 Add-to-App 方法將 Flutter 整合到原生應用程式,但此方法的效能及穩定性往往是開發者關注的焦點。我們需要深入探討 Money Forward ME 如何針對 Add-to-App 方法進行效能調校,例如原生程式碼與 Flutter 程式碼之間通訊機制選擇(例如:MethodChannel 的最佳化、Platform Channels 的效率提升)、記憶體管理策略(避免記憶體洩漏、最佳化資源釋放),以及針對不同平台(iOS 和 Android)的效能差異進行分析與最佳化,並提供具體資料或案例說明其最佳化成果。需要探討不同通訊機制在效能和複雜度上的權衡,以及其選擇依據,例如考慮使用更輕量級的通訊機制如共享記憶體(Shared Memory)的可行性及限制,以及其對安全性的影響。

**2. Flutter Add-to-App 架構下的程式碼風格規範及團隊協作最佳實務:** 雖然文章中提到建立開發模板檔案以確保程式碼一致性,但這只是表面。我們需深入探討 Money Forward ME 如何制定並實施其程式碼風格規範,包括採用哪些架構(如 MVVM、BLoC、Provider 等)以及詳細說明選擇理由,還有如何確保這些架構在原生應用程式與 Flutter 模組之間無縫銜接。也需探索團隊協作最佳實務,例如利用 Git 的分支策略管理程式碼變更、進行有效的程式碼審查,以及如何利用 CI/CD 流程自動化構建和測試。另外,也要運用靜態程式碼分析工具確保程式碼品質,更進一步地評估這些做法有效性的指標,如程式碼複雜度、缺陷密度和開發效率等,以具體資料支援其成效。結合最新趨勢,可討論如何利用 AI 輔助於程式碼風格檢查與自動化最佳化,以進一步提升團隊效率及程式碼品質。


這些模板涵蓋了建立單一畫面所需的所有基本類別,並詳細規範了諸如 API 請求等基本功能的技術規格。它們同時也作為拉取請求(pull requests)期間程式碼審查的一個有用參考。

我們還決定從一開始就引入 OpenAPI。透過啟用與網路 API 相關的類別自動生成,我們能夠降低開發成本,這與開發模板的效果相似。使用 YAML 檔案編寫的檔案作為 OpenAPI 生成的來源,成為所有利益相關者共享的資源,作為 API 規範檔案。這對於我們這些行動工程師來說尤其有幫助,有助於我們與伺服器端工程師之間達成共識。

在完成上述準備工作後,我們也專注於將原生應用程式工程師轉型為 Flutter 工程師。


Flutter跨平台開發:效能最佳化與團隊協作策略

作為入職過程的一部分,他們獲得了使用開發模板和 OpenAPI 的實際編碼經驗,並且參與了實際的小任務。在這個過程中,我們作為原生應用工程師進行了意見交流,促進了對開發模板的改進,並加深了我們對 Add-to-app 的理解。這是一個寶貴的機會,因為 iOS 和 Android 原生應用工程師在單一技術上合作,使團隊內部的溝通逐漸改善。

另一方面,由於 Flutter 程式碼庫與 iOS 和 Android 的加入,使得開發和運營變得有些複雜。我們旨在透過工具自動化來提高效率並保持生產力。隨著專案規模擴大,如何有效管理開發模板和 OpenAPI 的版本迭代及協作顯得至關重要,因此建議採用基於 GitOps 的 DevOps 實踐來提升團隊效率。

在跨平台開發框架選型時,需要深入探討效能問題,不僅要考慮 Flutter 與原生之間的直接比較,更需要針對特定模組進行細緻的效能分析,例如利用 Systrace、Instruments 等工具分析 Flutter UI 渲染、網路請求和資料庫操作中的效能瓶頸。同時也需考量 Flutter 引擎版本、Dart 編譯器設定,以及應用程式架構設計對效能的影響。當前業界趨勢偏向混合式開發策略:針對效能要求極高的部分仍然使用原生開發,而較不影響 UI/UX 體驗的功能則採用 Flutter 開發,以達成效率與效能之間的平衡。

為此,有必要建立一套嚴謹的效能評估指標與基線,持續追蹤並最佳化 Flutter 應用程式效能,同時將這些效能資料納入持續整合/持續部署(CI/CD)流程中。


Add-to-app 的 Git 儲存庫是 iOS 和 Android 儲存庫的子模組,當 Add-to-app 的 Git 儲存庫合併了一個拉取請求後,我們引入了 GitHub Actions 自動生成對 iOS 和 Android Git 儲存庫中子模組更新的拉取請求。


對於 OpenAPI,GitHub Actions 也會自動生成拉取請求,以便在 Add-to-app Git 儲存庫中更新 OpenAPI 客戶端,當 YAML 檔案(由另一個 Git 儲存庫管理)被更新時。我們新增了一個除錯選單,允許直接導航到每一個 Flutter 螢幕,並能夠更改連線目標至任何伺服器,同時提供 API 日誌的訪問。


這個工具的優勢在於它是一個獨立的 Flutter 應用程式。在除錯時,這個畫面會首先開啟,便於導航至每一個畫面,使得使用 Add-to-App 的常規開發與典型的 Flutter 應用開發並無二致。這樣的設定讓我們能夠充分利用 Flutter 開發所帶來的好處,例如熱過載(hot reload)和熱重啟(hot restart)。為了進一步提升我們的開發效率,我們決定將單一畫面視為引入 Add-to-App 的最小單位。


Flutter 增效:獨立 API 與資料同步策略

換句話說,我們使用 Flutter 建立了新的畫面或替換現有的畫面,透過降低 Flutter 與原生畫面之間的耦合度來增強靈活性和可維護性。雖然在原生畫面中渲染 Flutter 檢視在技術上是可行的,但這會使資料處理變得複雜,並且需要為 iOS 和 Android 上每個檢視執行更多獨立的程式,從而削弱了採用 Flutter 的好處。因此,我們選擇這次不實施此方案。我們為 Add-to-app 建立了一個獨立的 API 客戶端,與原生 API 客戶端分開,並建立了一種機制,以同步父級原生應用程式與 Add-to-app 之間的會話資訊及其他資料。


雖然重用原生 API 客戶端是個選項,但在我們的案例中並不需要重用原生端點。考慮到作為獨立的 Flutter 應用程式進行除錯,擁有自己的 API 客戶端是正確的做法。在設計方面,它之前遵循了每個作業系統的標準指導方針。對於使用 Add-to-app 開發的螢幕,我們則將其統一為 Material Design 風格。


設計系統整合:量化效益、AI應用與多指南一致性挑戰

由於這一統一,設計師的工作負載較之前有所減少,促進了與工程師之間更順暢的溝通,同時建立了一種頻繁交流以對齊對顏色定義、UI元件設計等方面理解的文化。如今,iOS應用程式包括遵循兩套不同指南的設計:一套是針對現有的iOS應用程式,另一套則是為Add-to-App所設計。透過將字型和顏色等元素調整至單一設計,我們在原生與Add-to-App畫面之間實現了最小的不適感。我們最近也開始嘗試運用生成式AI,例如進行簡單的拉取請求審查以及自動生成一些測試程式碼。

這段文字描述了設計系統統一後帶來的正面效應,但缺乏具體的量化資料支撐。頂尖設計師和工程師更關注的是:工作負載究竟減少了多少百分比?溝通效率提升了多少倍?例如,可以透過追蹤設計師在不同階段的工作時間、工程師修復與設計相關Bug所需時間,以及溝通次數和回應時間等資料,來量化前後差異。同時,「更順暮的溝通」和「頻繁溝通文化」具體如何體現?我們需要考慮匯入哪些協作工具或流程,以及如何衡量這些工具或流程的有效性。

另一方面,在多指南下管理一致性也是一個挑戰。如文中提到iOS App同時遵循兩種指導方針。在此情境下,高效能設計不僅需要平衡兩套指南的一致性與差異性,以確保使用者體驗連貫,更需建立嚴謹的設計原則和規範。明確規定哪些元素必須保持一致(如字型及顏色),哪些可有所差異並管理這些差異,以避免使用者在不同螢幕之間產生認知衝突。

有關生成式AI輔助開發,我們亦需探討其潛在挑戰。例如,AI生成測試程式碼質量該如何保障?如何避免引入新的錯誤或漏洞?又該如何確保AI決策過程透明且可追蹤?這些都是評估AI輔助開發實際效益及潛在風險的重要議題,也為未來發展方向提供可靠參考依據。


特別地,我們發現自動生成的測試程式碼具有高覆蓋率,並且在顯著降低實施成本方面貢獻良多。透過整合之前分開針對 iOS 和 Android 的專案流程,工作量減半,有效地將開發生產力提高了一倍。


雖然仍需進行一些原生端的修改,例如從原生呼叫 Add-to-App 畫面,但這些通常只需幾行程式碼變更即可解決。


就我個人而言,我認為在每個開發階段解決溝通問題,而不僅僅是提高開發生產力,是引入 Add-to-app 最重要的成果。我們這些 iOS 和 Android 工程師之前並不太了解彼此的工作內容。隨著 Add-to-app 的引入,我們開始更密切地合作,自然增加了溝通的機會。以前與產品經理或市場行銷人員討論的任務,有時只會傳達給某一平台的工程師,但現在這種情況不再發生。


新服務的推出已成功完成,並且使用 Add-to-app 進行團隊開發的模式已建立。自那時以來,大部分替換或更新現有介面以及發布新服務的開發工作都是採用這種方法進行的。


自去年夏天以來,隨著我們公司的全球化及英語作為工作場所的官方語言的採用,開發團隊變得更加多元。感謝已建立的 Add-to-App 開發環境,包括對 Flutter 和 Dart 的共同知識、高效的入職流程、開發模板以及 OpenAPI 的使用,我們能夠在不損失生產力的情況下繼續開發,即使面對語言障礙。在未來,其中一個需要解決的問題將是決定何時停止使用 Add-to-App。


Add-to-App開發策略:平衡原生與Flutter,邁向高效能與可擴充套件性

目前,使用 Add-to-app 的開發持續增長,但如果我們在沒有考量的情況下繼續進行,Add-to-app 的比例未來可能會超過原生程式碼。在適當的時機,我們需要檢視與原生程式碼的平衡,並考慮最佳化整個專案。例如,我們可能需要考慮轉型到新階段,比如將 Add-to-App 專案轉換為主要應用程式專案,並將當前的主要原生專案作為 Flutter 外掛整合。這將需要初步驗證和開發。

透過引入 Add-to-App 並相應地最佳化開發環境,我們不僅顯著提高了開發生產力,也解決了各種專案問題。Add-to-App 只是一種方法,目前對於我們的專案而言是最佳選擇。若繼續以這樣的方式進行開發,也可能導致技術負債,如我之前提到的。我們希望在繼續開發的同時,考慮最適合該專案的技術與方法。

從長遠規劃來看,在處理 Add-to-App 策略及其所帶來的技術負債時,我們必須超越單純比例的考量,以探討動態模組化與微服務架構之間更深層次的整合。而在 Flutter 與原生碼整合方面,分析 Add-to-App 轉換成單一應用程式時效能評估與風險管理,包括平台差異與資料遷移策略,也是不可或缺的一環。只有如此,我們才能確保在快速變化且競爭激烈的市場中保持靈活性與創新能力。

這篇文章作為 2024 冬季 Money Forward 技術部落格馬拉松的一部分發表。我希望您能檢視並享受即將推出的文章。祝工程愉快!


JH

專家

相關討論

❖ 相關專欄