Flutter|多業(yè)務(wù)適配LOL社區(qū)SDK總結(jié)

背景

游戲內(nèi)嵌社區(qū)是玩家在游戲內(nèi)社交的重要平臺,現(xiàn)有的社區(qū)SDK在PUBG經(jīng)過三年迭代已具備成熟社交功能,但在拓展新業(yè)務(wù)時面臨著多業(yè)務(wù)界面和功能差異大、通用性不足的問題,為了能靈活滿足不同游戲訴求,需要打造一個功能可插拔、復(fù)用性高、可快速擴展新業(yè)務(wù)的內(nèi)嵌社區(qū)SDK。

選型

綜合考慮了性能、交互體驗、改造成本和后續(xù)擴展性,最終選擇基于SDK1.0升級SDK2.0作為LOL內(nèi)嵌社區(qū)。

方案設(shè)計

1. 模塊化靈活組合

SDK1.0所有功能都在一個模塊與業(yè)務(wù)強耦合,不利于新業(yè)務(wù)定制。因此2.0結(jié)合產(chǎn)品能力和底層實現(xiàn),對項目代碼進行分層和模塊化:

  • 主入口:頂層管理、模塊服務(wù)注冊和初始化
  • 業(yè)務(wù)模塊:劃分遵循單一職責(zé)原則,統(tǒng)一通過模塊服務(wù)管理和通信,面向接口開發(fā),有獨立資源,可獨立運行,可靈活組合打包,是實現(xiàn)多業(yè)務(wù)定制化的重點
  • 通用模塊、第三方庫:公共必需的模塊,向上提供基礎(chǔ)服務(wù)

其中,實現(xiàn)業(yè)務(wù)模塊靈活組合的兩個關(guān)鍵點:

  • 模塊管理標準化(紅線)
    • 以ServiceMgr為核心統(tǒng)一管理業(yè)務(wù)模塊,包括接口列表和注冊、獲取模塊方法
    • 每個業(yè)務(wù)模塊實現(xiàn)各自對外接口,并在初始化時注冊到ServiceMgr
    • 模塊間調(diào)用通過ServiceMgr間接獲取,而不是直接依賴
  • 模塊配置自動化(藍線)
    • 構(gòu)建流水線時,支持配置打包模塊,會在頂層入口.yaml配置文件動態(tài)導(dǎo)入依賴模塊并在ServiceMgr動態(tài)注入注冊代碼
    • 無需修改代碼,一鍵滿足業(yè)務(wù)不同打包需求(如全球包、日韓包),支持并發(fā)打包出包,整體提高研發(fā)效率

2. 差異化精細適配

完成模塊化只解決了定制模塊解耦,對于公共模塊差異還要做精細適配:

  • 上下游適配
    • 通信協(xié)議復(fù)用,表維護后臺服務(wù)及資源配置,動態(tài)生成當(dāng)前配置,實現(xiàn)快速切換環(huán)境
    • 賬號體系完善,國內(nèi)需區(qū)分登錄平臺和系統(tǒng)
  • 視覺還原:除首頁框架調(diào)整,其他頁面交互基本一致,但視覺風(fēng)格不同,需逐個還原以下資源:
    • 本地資源 :維護不同業(yè)務(wù)資源包,動態(tài)生成當(dāng)前資源,實現(xiàn)快速替換同名同格式資源
    • 本地詞條 :保留海外多語言方式,修改默認語言,本地內(nèi)置默認詞條并支持遠端下發(fā),實現(xiàn)快速修改默認詞條
    • 本地字體 :定義字體接口,實現(xiàn)快速滿足不同業(yè)務(wù)對字體、粗細和行間距的要求
    • 顏色:命名顏色值,抽象主題色,統(tǒng)一映射表維護,實現(xiàn)快速修改全局顏色
  • 全局換膚
    • 預(yù)設(shè)配置項在管理端運營,避免通過換圖熱更增加后期開發(fā)成本
    • 使用換膚管理器、換圖組件和換色組件降低接入成本
? Widget框架解耦

以上流程基本實現(xiàn)業(yè)務(wù)層代碼共享、業(yè)務(wù)獨立、資源分離的目標,但開發(fā)中發(fā)現(xiàn)以下問題:

  • Flutter的Widget嵌套式語法導(dǎo)致UI構(gòu)建和事件處理耦合在同一個Widget中,增刪代碼需考慮多業(yè)務(wù)和橫豎屏影響,復(fù)雜度變高、維護性變差
  • 多數(shù)Widget僅UI細節(jié)差異,導(dǎo)致引入大量與UI相關(guān)的if-else,理解成本變高、可讀性變差

因此,將Widget中的UI和邏輯解耦,實現(xiàn)不同業(yè)務(wù)子類對UI或邏輯的獨立維護,職責(zé)清晰,避免相互影響。其中三個關(guān)鍵元素:

  • Cell:組件的最小單位,由View和ViewModel構(gòu)成
  • View:負責(zé)布局界面,從ViewModel獲取展示數(shù)據(jù)和事件
  • ViewModel:負責(zé)業(yè)務(wù)邏輯,數(shù)據(jù)變化時通知依賴View刷新數(shù)據(jù)

3. 體驗和性能優(yōu)化

? 內(nèi)存優(yōu)化
  • 大圖壓縮優(yōu)化
    • 問題 :用戶上傳的各種頭像通常以小圖呈現(xiàn),直接加載原圖會導(dǎo)致內(nèi)存占用高和流量浪費,而簡單壓縮無法解決不同場景顯示尺寸不一發(fā)生頻繁加載的問題
    • 解決方案 :實際裁剪尺寸采用分組策略,尺寸定義上符合設(shè)計習(xí)慣,最大程度復(fù)用緩存圖像,減少內(nèi)存占用和流量消耗,且保證圖像質(zhì)量
    • 性能提升 :首頁內(nèi)存峰值降低30MB,平均節(jié)約45%流量


? 幀率優(yōu)化
  • 動圖渲染優(yōu)化
    • 問題 :首頁滾動卡頓明顯,經(jīng)PerfDog測試比半年前版本掉了4幀
    • 解決方案 : 使用Flutter DevTools監(jiān)測性能發(fā)現(xiàn)UI線程Paint耗時明顯增加,借助Highlight repaints定位是Lottie和Gif影響整個頁面發(fā)生頻繁重繪。辦法是使用RepaintBoundary組件包裹動圖,利用Flutter圖層合成機制,將動圖繪制結(jié)果緩存到單獨圖層,發(fā)生變化只自重繪而不影響頁面其他圖層
  • 視頻啟播優(yōu)化
    • 問題 :測試首頁快滾FPS時發(fā)現(xiàn),滾動中發(fā)生視頻加載
    • 解決方案 :快滾時手指反復(fù)按下抬起(發(fā)現(xiàn)每次按下的ScrollStart會先調(diào)用前一次的ScrollEnd)導(dǎo)致多次回調(diào)ScrollEnd誤觸視頻加載,而Flutter無法準確描述快滾停止事件。辦法是ScrollEnd后延時加載,確保頁面穩(wěn)定,且避免和曝光檢測任務(wù)同時競爭資源,經(jīng)線上實驗測試延時最少30ms對提高FPS有效且不影響啟播體驗
    • 性能提升 :經(jīng)PerfDog測試首頁快滾30s FPS提升5幀
? Flutter組件優(yōu)化
  • 多平臺滾動體驗優(yōu)化
    • 問題 : Flutter原生滾動實現(xiàn)有差異,導(dǎo)致iOS視頻起播較慢
    • 解決方案 :結(jié)合iOS減速運動曲線、模擬摩擦停止效果,擴展Flutter滾動物理屬性,增加速度衰減率以加快減速、提高速度停止閾值以加快停止,實現(xiàn)更快啟播
  • 多語言字符顯示優(yōu)化
    • 部分泰語提前換行或打點 。經(jīng)查由泰語中顯示在基礎(chǔ)字符上的聲調(diào)字符(Combining Character)造成,有幾個超出顯示,若在文本末尾則導(dǎo)致實際寬度溢出。辦法是擴展Flutter Text組件,針對性追加空格補齊寬度
    • 部分阿拉伯字符顯示亂碼 。經(jīng)查是阿語某種組合字符(Hamza),在Flutter文本引擎LibTxt處理多語言字形時,針對阿語進行了字符連接的調(diào)整,和非阿語字符組合則無法正常渲染。方法是插入零寬度空格\u200B,確保能和空白正確組合顯示

總結(jié)與展望

通過LOL社區(qū)適配,完成對社區(qū)SDK的通用化改造,和對基礎(chǔ)體驗的整體升級。盡管在后續(xù)迭代中,考慮到國內(nèi)和國外應(yīng)用在底層邏輯存在較大差異,進行了分支管理獨立運行的技術(shù)調(diào)整,但仍然保留通用化做法,以便未來作為國內(nèi)和國外社區(qū)的模版繼續(xù)擴展。


相關(guān)簡書文章:
Flutter|解耦初實踐
Flutter|頁面換膚實踐
Flutter流暢度優(yōu)化之過度繪制
Flutter滑動停止事件ScrollEndNotification
Flutter|滑動體系之ScrollPyhsics
Flutter Text組件和國際化-阿語
Flutter Text組件和國際化-泰語

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容