移動端APP元件化架構實踐
來源:京東技術 導讀
本文透過以下問題來介紹元件化這種開發架構的思想和常見的一些問題:
為什麼需要元件化
元件化過程中會遇到的挑戰和選擇
如何維護一個高質量的元件化專案
導讀
本文透過以下問題來介紹元件化這種開發架構的思想和常見的一些問題:
為什麼需要元件化
元件化過程中會遇到的挑戰和選擇
如何維護一個高質量的元件化專案
對於中大型移動端APP開發來講,元件化是一種常用的專案架構方式。最近幾年在工作專案中也一直使用元件化的方式來開發,在這過程中也積累了一些經驗和思考。主要是來自在日常開發中使用元件化開發遇到的問題以及和其他開發同學的交流探討。
本文透過以下問題來介紹元件化這種開發架構的思想和常見的一些問題:
為什麼需要元件化
元件化過程中會遇到的挑戰和選擇
如何維護一個高質量的元件化專案
提示:本文說的元件化工程是指Multirepo使用獨立的git倉庫來管理元件。
元件化可以帶來什麼
2.1 單一工程架構遇到的問題
多APP專案並存 - 集團內部存在多個APP專案,不同APP希望可以複用現有元件能力快速搭建出新的APP。
功能增多 - 隨著專案功能越來越多,程式碼量增多。同時需要更多的開發人員參與到專案中,這會增加開發團隊之間協作的成本。
多語言/多技術棧 - 引入了更多的新技術,例如使用一種以上的跨平臺UI技術用於快速交付業務,不同的程式語言、音影片、跨平臺框架,增加了整個工程的複雜度。
工程效率
工程程式碼量過大會導致編譯速度緩慢。
單git工程提交同時可能帶來更多的git提交衝突和編譯錯誤。
質量問題
如何將git提交關聯到對應的功能模組需求。發版時進行合規檢查避免帶入不規範的程式碼,對整個功能模組回滾的訴求。
如何在單倉庫中管控這麼多開發人員的程式碼許可權,儘可能避免不安全的提交併且限制改動範圍。
更大範圍的元件複用
基礎元件從支援單個APP複用到支援多個APP複用。
不只是基礎能力元件,對於業務能力元件也需要支援複用。(例如一個頁面元件同時在多個APP使用)
跨平臺容器需要複用底層元件能力避免重複開發,同時不同跨平臺容器API需要儘量保持統一,底層基礎設施向容器化發展支援業務跨APP複用。
跨技術棧通訊
由於頁面導航多技術棧混合共存,頁面路由需要支援跨技術棧。
跨元件通訊需要支援跨語言/跨技術棧通訊。
更好的解耦
頁面解耦。由於頁面導航棧混合共存,頁面自身不再清晰的知道上游和下游頁面由什麼技術棧搭建,所以頁面路由需要做到完全解耦隔離技術棧的具體實現。
業務元件間維持松耦合關係,可以靈活新增/移除,基於現有元件能力快速搭建出不同的APP。
對於同一個服務或頁面可以外掛化方式靈活提供多種不同的實現,不同的APP宿主也可以提供不同的實現並且提供A/B能力。
由於包體積限制和不同元件包含相同符號導致的符號衝突問題,在複用元件的時候需要儘可能引入最小依賴原則降低接入成本。
2.2 元件化架構的優勢
元件化架構通常具備以下優點:
程式碼複用 - 功能封裝成元件更容易複用到不同的專案中,直接複用可以提高開發效率。並且每個元件職責單一使用時會帶入最小的依賴。 降低理解複雜度 - 工程拆分為小元件以後,對於元件使用方我們只需要透過元件對外暴露的公開API去使用元件的功能,不需要理解它內部的具體實現。這樣可以幫助大家更容易理解整個大的專案工程。 更好的解耦 - 在傳統單一工程專案中,雖然可以使用設計模式或者編碼規範來約束模組間的依賴關係,但是由於都存放在單一工程目錄中缺少清晰的模組邊界依然無法避免不健康的依賴關係。元件化以後可以明確定義需要對外暴露的能力,對於模組間的依賴關係可以進行強約束限制依賴,更好的做到解耦。對一個模組的新增和移除都會更容易,並且模組間的依賴關係更加清晰。 隔離技術棧 - 不同的元件可以使用不同的程式語言/技術棧,並且不用擔心會影響到其他元件或主工程。例如在不同的元件內可以自由選擇使用Kotlin或Swift,可以使用不同的跨平臺框架,只需要透過規範的方式暴露出頁面路由或者服務方法即可。 獨立開發/維護/釋出 - 大型專案通常有很多團隊。在傳統單一專案整合打包時可能會遇到程式碼提交/分支合併的衝突問題。元件化以後每個團隊負責自己的元件,元件可以獨立開發/維護/釋出提升開發效率。 提高編譯/構建速度 - 由於元件會提前編譯釋出成二進位制庫進行依賴使用,相比編譯全部原始碼可以節省大量的編譯耗時。同時在日常元件開發時只需要編譯少量依賴元件,相比單一工程可以減少大量的編譯耗時和編譯錯誤。 管控程式碼許可權 - 透過元件化將程式碼拆分到不同元件git倉庫中,可以更好的管控程式碼許可權和限制程式碼變更範圍。 管理版本變更 - 通常會使用CocoaPods/Gradle這類依賴管理工具來管理專案中所有的元件依賴。因為每一個元件都有一個明確的版本,這樣可以透過對比APP不同版本打包時的元件依賴表很清晰的識別元件版本特性的變更,避免帶入不合規的元件版本特性。並且在出現問題時也很方便透過配置表進行回滾撤回。
提示:元件化架構是為了解決單一工程架構開發中的問題。如果你的專案中也會遇到這些痛點,那可能就需要做元件化。
元件化遇到的挑戰
雖然元件化架構可以帶來這麼多收益,但不是隻要使用元件化架構就可以解決所有問題。通常來講當使用一種新的技術方案解決現有問題的時候也會帶來一些新的問題,元件化架構能帶來多少收益主要取決於整個工程元件化的質量。那在元件化架構中如何去評估專案工程的元件化架構質量,需要關注哪些問題。對於軟體架構來講,最重要的就是管理元件實體以及元件間的關係。所以對於元件化架構來講主要是關注以下三個問題:
如何劃分元件的粒度、元件職責邊界在哪裡?
元件間的依賴關係應該如何管理?
元件間應該使用哪種方式呼叫和通訊?
1. 元件拆分的粒度、元件職責邊界在哪裡?
2. 元件間的依賴關係應該如何管理?
3. 元件間松耦合依賴關係應該使用哪種方式呼叫和通訊?
提示:這裡的耦合程度高是相對於耦合程度低的方式進行比較,相比 直接依賴
對應元件依然是一種耦合程度低的依賴關係。
基於以上這些元件化架構的問題,需要一些元件化架構相關的規範和原則來幫助做好元件化架構,後面主要會圍繞以下三點進行介紹:
元件拆分原則 - 拆分思想和最佳實踐指導元件拆分
元件間依賴 - 最佳化元件間依賴關係跨元件呼叫/通訊方式的選擇
質量保障 - 避免在持續的工程演化過程中工程質量逐漸劣化。主要包含安全卡口和CI檢查
4.1 工程例項
接下來以一個典型的電商APP架構案例來介紹一個元件化工程。這個案例架構具備之前所說現有中大型APP架構的一些特點,多元件、多技術棧、業務間需要解耦、複用底層基礎元件。基於這個案例來介紹上面的三點原則。
圖1.
4.2 元件拆分原則
圖2.
4.2.1使用分層思想拆分
基礎層 - 提供核心的與上層業務無關的基礎能力。可以被上層元件直接依賴使用。
業務公共層 - 主要包含頁面路由、公共UI元件、跨元件通訊以及服務介面,可被上層元件直接依賴使用。 業務實現層 - 業務核心實現層,包含原生頁面、跨平臺容器、業務服務實現。元件間不能直接依賴,只能透過呼叫頁面路由或跨元件通訊元件進行使用。 APP宿主層 - 主要包含APP主工程、啟動流程、頁面路由註冊、服務註冊、SDK引數初始化等元件,用於構建打包生成相應的APP。
基礎元件依賴業務元件
例子:APP內業務發起網路請求通常需要攜帶公共引數/Cookie。
沒有元件分層約束 - 網路庫可能會依賴登入服務獲取使用者資訊、依賴定位服務獲取經緯度,引入大量的依賴變成業務元件。 有元件分層約束 - 網路庫作為一個基礎元件,它不需要關注上層業務需要攜帶哪些公共業務引數,同時登入/定位服務元件在網路庫上層不能被反向依賴。這時候會考慮單獨建立一個公共引數管理類,在APP執行時監聽各種狀態的變更並呼叫網路庫更新公共引數/Cookie。
業務元件間依賴方向是否正確
沒有元件分層約束 - 可能會在登入服務內當登入狀態切換時呼叫多個業務邏輯的觸發,導致登入服務引入多個業務元件依賴。
有元件分層約束 - 登入元件只需要在登入狀態切換時發出通知,無需知道登入狀態切換會影響哪些業務。業務邏輯應該監聽登入狀態的變更。
識別基礎元件還是業務元件
雖然很多場景下很容易能識別處理出來一個功能應該歸屬於基礎元件還是業務元件,例如一個UI控制元件是基礎元件還是業務元件。但是很多時候邊界又非常的模糊,例如一個新增購物車按鍵應該是一個基礎元件還是業務元件呢。
基礎元件 - 如果不需要依賴業務公共層那應當劃分為一個基礎元件。
業務元件 - 依賴了業務公共層或者網路庫,那就應該劃分為一個業務元件。
分層思想可以很好地幫助管理元件間的依賴關係,並且明確每個元件的職責邊界。
4.2.2基礎/業務元件拆分原則
劃分基礎/業務元件主要是為了強制約束元件間的依賴關係。以上面的元件分層架構為例:
基礎元件 - 基礎元件可被直接依賴使用,使用方呼叫基礎元件對外暴露API直接使用。基礎層、業務公共層都為基礎元件。 業務元件 - 業務元件不可被直接依賴使用,只能透過間接通訊方式進行使用。APP宿主層和業務實現層都為業務元件。
提示:這裡的業務元件並不包含業務UI元件。
4.2.3基礎元件拆分
使用外掛元件拆分基礎元件擴充套件能力
將核心基礎能力和擴充套件能力拆分到不同的元件。以網路庫為例,除了提供最核心的介面請求能力,同時可能還包含一些擴充套件能力例如HTTPDNS、網路效能檢測、弱網最佳化等能力。但這些擴充套件能力放在網路庫元件內部可能會導致以下問題:
擴充套件能力會使元件自身程式碼變的更加複雜。
使用方不一定會使用所有這些擴充套件能力違反了最小依賴原則。帶來更多的包體積,引入更多的元件依賴,增加模組間的耦合度。 相關的擴充套件能力不支援靈活的替換/插拔。
4.2.4業務元件拆分
業務頁面拆分方式
基於技術棧進行拆分 - 不同的技術棧需要拆分到不同的元件進行管理。
基於業務域進行拆分 - 將同一個業務域的所有頁面拆分一個元件,避免不同業務域之間形成強耦合依賴關係,同一個業務域通常會有更多複用和通訊的場景也方便開發。例如訂單詳情和訂單列表可放置在一起管理。
基於頁面粒度進行拆分 - 單個頁面複雜度過高或需要被單獨複用時需要拆分到一個單個元件管理。
提示:放置在單一元件內的多個頁面之間也應適當降低耦合程度。
4.2.5第三方庫
第三方庫應拆分單獨元件管理
4.2.6一些提示
減少使用通用聚合公共元件
新增一個新功能不知道應當加在哪裡時,就加到公共聚合元件內,時間久了以後公共元件依賴特別多;
公共元件新增了一個非常複雜的能力,導致複雜度變高或者引入大量依賴;
太多能力聚合到一起。例如將網路庫、圖片庫這些能力放在同一個元件內;
基礎/業務UI元件沒有拆分。基礎UI元件通常只提供最基礎的UI和非常輕量的邏輯,業務元件通常會充當基礎UI元件的資料來源以及業務邏輯。
但是也不能完全避免使用聚合公共元件,不然會導致產生更多的小元件增加維護成本。但是將一個能力新增到公共聚合元件時可以根據以下幾個條件來權衡:
是否會引入大量新的依賴
功能複雜度、程式碼數量,太複雜的不應該新增到公共元件
能力是否需要被單獨複用,需要單獨複用就不應該新增到公共元件
第三方庫考慮不直接對外暴露使用
當存在以下情況時可考慮對第三方庫進行適當的封裝避免直接暴露第三方庫:
使用方通常只需要使用少量API,第三方庫會對外暴露大量API增加使用難度,同時可能導致一些安全問題
對外隱藏具體實現,方便後續更換其他第三方庫、自實現、第三方庫發生Break Change變更時升級更容易
需要封裝擴充套件一些能力讓使用方使用起來更容易
以網路庫為例:
1.通常需要對接公司內部的API閘道器能力所以需要適當做一些封裝,例如簽名或者加密策略。
2.使用方通常只需要用到一個通用的請求方法無需對外暴露太多API。
3.為了安全通常需要對業務方隱藏一些方法避免錯誤呼叫,例如全域性Cookie修改等能力。
第三方庫儘可能避免直接修改原始碼
4.3 元件間依賴關係
4.3.1業務元件間通訊方式選擇
松耦合通訊方式對比
圖3.
4.3.2服務介面
服務介面對應的實現和頁面是否需要拆分
服務介面是否需要拆分
一般專案可能至少會有10+個服務介面,這些服務介面應該統一存放在單個元件還是每個介面對應一個元件。
統一存放:優點是一起管理更快捷方便。缺點是所有介面對應一個元件版本,不能支援單一介面使用不同版本,不利於需要跨APP複用的專案。並且使用方可能會引入大量無用的介面依賴。
分開存放:優點是每個介面可使用不同的版本並且使用方只需要依賴特定的介面。缺點是會產生更多的元件倉庫,元件數量也會增加依賴查詢的耗時。
所以大型專案選擇分開存放的方式管理介面相對更合適一點。也可以考慮將大部分最核心的服務介面放置到一起管理。
支援Swift的服務介面實現推薦
使用Swift實現傳統的服務介面模式通常會遇到以下兩個問題:
介面需要同時支援Objective-C和Swift呼叫,同時希望使用Swift特性設計API。如何實現Objective-C和Swift協議可以複用一個例項
Swift對於動態性支援比較弱,純 Swift
類無法支援執行時動態建立只能在註冊時建立例項
基於以上問題,個人推薦使用下面的方式實現介面服務模式:
使用Objective-C協議提供最基礎的服務能力,之後建立Swift協議擴充套件提供部分Swift特性的API 介面實現類繼承NSObject支援執行時動態初始化
// @objc協議
public protocol JDCartService {
func addCart(request: JDAddCartRequest, onSuccess: () -> Void, onFail: () ->)
}
// swift協議
public protocol CartService: JDCartService {
func addCart() async
func addCart(onCompletion: Result)
}
// 實現類
class CartServiceImp: NSObject, CartService {
// 同時實現Objc和Swift協議
}
服務應該中心化註冊還是分散式註冊
中心化註冊是在宿主APP啟動時統一註冊服務介面的對應實現例項,分散式註冊是在元件內元件自身進行註冊。個人推薦中心化註冊的方式在宿主APP啟動時統一進行註冊管理,明確服務的實現方更清晰,同時避免不同元件包含同一個服務介面的不同例項導致的衝突。
4.3.3元件版本相容
謹慎使用常量、列舉、宏
因為元件編譯釋出的時候會生成二進位制庫,編譯器會將依賴的常量、列舉、宏替換成對應的值或程式碼,所以當後續這些常量、列舉、宏發生變更的時候,已生成的二進位制庫並不會改變導致打包的時候依然使用的舊值,必須重新發布使用這些值的元件才行。所以應當儘量避免修改常量、列舉、宏值,如果已知後續可能會變更的情況下應避免使用常量、列舉、宏。
基礎元件API向後相容
對外API需保證向後相容,使用新增API的方式擴充套件現有能力,避免對原有API進行break change改動或移除
使用物件封裝傳遞引數和回撥引數,避免對原有API進行修改
提示:特別是對於
Objective-C
這類動態呼叫的語言來講,打包構建時並不能發現呼叫的方法不存在、引數錯誤這些問題。所以我們應當儘可能避免現有方法的變更。同時也推薦更多使用Swift
編譯器可以發現這些問題提示編譯錯誤。
減少釋出大版本
以Cocoapods
為例,元件釋出大版本會導致依賴此元件的所有元件都必須同時升級到大的版本重新發布,這樣會給元件使用放帶來極大的更新成本。所以元件應該減少釋出大版本,除非必須強制所有元件一定要升級。
優先選擇介面服務減少暴露View類
當只關注API提供的能力並不關注API提供的形態時儘可能透過API的方式來暴露能力。因為暴露介面方法相比檢視View,呼叫方只需要依賴介面方法相比依賴View類可以更小化的依賴,同時介面對於實現方未來擴充套件能力更靈活。以選擇使用者地址API為例,通常呼叫方並不關注實現方以彈窗的方式還是頁面的方式提供互動能力讓使用者選擇,只關注使用者最終選擇的地址資料。並且呼叫方不需要處理彈窗和頁面的展示邏輯使用起來更方便,也便於實現方之後修改互動方式。
使用介面的方法
addressService.chooseAddress { address in
}
使用View的方式
let addressView = AddressView()addressView.callback = { address in ///}addressView.show()
避免使用Runtime反射動態呼叫類
4.3.4第三方庫
第三方庫元件不允許依賴其他元件
4.4 質量保障
圖4.
4.4.1CI檢查
元件釋出
在元件釋出時新增一個安全檢查,避免不符合依賴規範的元件釋出成功。通常可以新增以下依賴檢查規則:
第三方庫不可依賴其他元件
基礎元件不可依賴業務元件
業務元件不可直接依賴業務元件
元件間通常不可相互依賴
不允許元件層級間反向依賴
版本整合規範
打包構建
在宿主APP打包時,提前檢測出介面服務存在的問題,避免帶入到線上。通常可以檢測以下問題:
服務介面對應的實現類不存在
服務介面對應的實現類沒有實現所有方法
使用ObjC Runtime動態呼叫類和方法
元件被依賴但是並沒有被使用到(基於程式碼依賴查詢)
線上異常上報
線上檢查可以幫助我們在灰度釋出的及時發現問題及時修復,通常可以發現以下問題:
路由跳轉對應的頁面不存在
介面服務對應的實現類不存在
介面服務對應的方法不存在
可量化指標
基礎元件依賴數量
元件依賴的所有基礎元件總數,當依賴的基礎元件總數過高時應該及時進行重構。如果大量的業務元件都需要依賴非常多的基礎元件,那可能說明基礎元件的依賴關係出現了很大的問題,這時候需要對基礎元件進行最佳化重構:
考慮使用介面服務對外暴露能力,元件層級需要提升
考慮將部分能力拆分出為獨立的新元件 業務服務依賴數量
錯誤依賴關係數量
錯誤的依賴關係應該及時最佳化改造。
基礎元件應該直接暴露還是使用介面對外暴露
API直接暴露
功能單一/依賴少 - 一些工具類,例如Foundation API複雜 - API非常多如果使用介面需要抽象太多介面,例如網路庫、日誌 UI元件 - 需要直接暴露UIView的UI元件,例如UIKit
介面對外暴露
可擴充套件性 - 基於介面可以靈活替換不同的實現,例如定位能力可以使用系統自帶的API,也可以使用不同地圖廠商的API
減少依賴引入 - 降低使用方的接入成本,提高日常開發/元件釋出效率
可插拔能力 - 對應的能力可移除,同時也不影響核心業務
提示:這些以介面對外暴露的API還有一個優勢是可以抽象成容器化的API,形成統一的標準規範。使用方呼叫同樣的API,不同的APP可以提供不一樣的實現。
小專案是否應該做元件化
單一工程如何改造為元件化工程
一般來講需要使用循序漸進逐步重構的策略對原有專案進行改造,但是有一些模組可以優先被元件化拆分降低整個元件化的難度:
優先拆分出最核心的所有業務模組可能都需要使用的元件,這些元件拆分完成以後才能為之後業務模組拆分提供基礎。例如Foundation、UI元件、網路庫、圖片庫、埋點日誌等最基礎的元件。
優先拆分不被其他元件依賴或被其他元件依賴較少的模組元件,這些模組相對比較獨立拆分起來比較高效並且對現有工程改造較小。例如效能監控、微信SDK這類相對獨立的能力。
元件化帶來的額外成本
元件化架構可能會帶來以下這些額外的成本:
管理更多的元件git倉庫
每次元件釋出都需要重新編譯/釋出
由於元件使用方都是使用相應的元件二進位制庫,所以除錯原始碼會變的更困難
開發元件管理平臺,管理元件版本、版本配置表等能力
每個元件需要有自己的Example工程進行日常開發除錯
處理可能存在的元件版本不一致導致的依賴衝突、編譯錯誤等問題
需求可能會涉及到多元件改動,如何進行Code Review、版本合入檢查
Monorepo
個人並沒有在實際的專案中使用過Monorepo方式管理專案。Monorepo是將所有元件程式碼放在單個git倉庫內管理,然後使用資料夾拆分為不同的元件。不同資料夾中的程式碼不能直接依賴使用,需要配置本地資料夾的元件依賴關係,在實現元件化的同時避免拆分太多的git倉庫。不過個人認為Monorepo同時也需要解決以下幾個問題:
編譯耗時最佳化 - 將所有原始碼放在單個工程中會導致編譯變慢,所以必須最佳化現有工程編譯流程,降低非必要的重複編譯耗時。
元件版本管理 - 在元件化工程中可以透過配置元件的特定版本來管理功能是否合入到版本中,但在Monorepo中只能透過分支Merge Request來管理特性是否合入,回滾也會更加繁瑣。
高質量CI流程 - 在單個倉庫中,當一個開發者有倉庫許可權時他就可以修改該倉庫的任意程式碼。所以必須完善程式碼合入規範,更高標準的Code Review、整合測試檢查、自動化檢查避免問題程式碼帶到線上。
同時工程架構的改變也會一定程度的改變開發人員的分工,對於大型工程來講元件化的程度更高,每個開發人員的工作分工會更細。對於底層基礎元件的開發,需要提供更多高效能/高質量的基礎元件讓上層業務開發人員更加效率的支撐業務,技術深度也會更加深入。對於上層業務開發,更多是使用這些底層基礎元件,同時可能也需要掌握多種跨端UI技術棧快速支撐業務,技術棧會更廣但是不會太深入
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027824/viewspace-2992974/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- iOS 元件化/模組化架構設計實踐iOS元件化架構
- 支付寶移動端動態化方案實踐
- iOS 移動端架構初探心得iOS架構
- 前端架構之移動端混合架構(hybrid)前端架構
- mPaaS 服務端核心元件:移動分析服務 MAS 架構解析服務端元件架構
- mPaaS 服務端核心元件:移動同步服務 MSS 架構解析服務端元件架構
- 移動端架構的幾點思考架構
- 我對移動端架構的思考架構
- iOS 移動端架構的那些事iOS架構
- iOS移動端架構的那些事iOS架構
- 移動端適配-實踐篇
- 移動端防抓包實踐
- Android 基於註解IOC元件化/模組化的架構實踐Android元件化架構
- WebRTC 架構優化及實踐Web架構優化
- 移動APP啟動慢解決實踐APP
- react移動端適配方案實踐React
- 專案實戰之元件化架構元件化架構
- 元件化 構架思路元件化
- vue實戰 | vue移動端專案架構設計(附demo)Vue架構
- 移動端App測試實用指南APP
- iOS架構實踐乾貨:AOP替代基類 + MVVM + ReactiveObjC + JLRoutes元件化iOS架構MVVMReactOBJ元件化
- 搜狐服務架構優化實踐架構優化
- 餓了麼移動APP的架構演進APP架構
- 移動端基於動態路由的架構設計路由架構
- 讓移動開發更輕鬆 閒魚基於Flutter構建跨端APP應用實踐移動開發Flutter跨端APP
- 貨拉拉貨運iOS使用者端架構最佳化實踐iOS架構
- 移動APP卡頓問題解決實踐APP
- 移動端架構師_Android架構師成長體系課程架構Android
- 易盾移動端同構實踐,幾步改善官網互動體驗
- Android客戶端專案元件化實踐Android客戶端元件化
- 實現基於React的移動端Swiper元件React元件
- 移動端日曆元件設計與實現元件
- appium uiautomator 移動端自動化測試工具APPUI
- 關於移動端元件庫元件
- 移動端手勢庫設計與實踐
- Lighthouse與Google的移動端最佳實踐Go
- 全面解密QQ紅包技術方案:架構、技術實現、移動端優化、創新玩法等解密架構優化
- iOS元件化實踐iOS元件化