<ruby id="9ue20"></ruby>

  1. 
    

      国产午夜福利免费入口,国产日韩综合av在线,精品久久人人妻人人做精品,蜜臀av一区二区三区精品,亚洲欧美中文日韩在线v日本,人妻av中文字幕无码专区 ,亚洲精品国产av一区二区,久久精品国产清自在天天线
      網(wǎng)易首頁(yè) > 網(wǎng)易號(hào) > 正文 申請(qǐng)入駐

      Unity小游戲優(yōu)化簡(jiǎn)譜 | 吃透底層邏輯,告別掉幀與流失

      0
      分享至

      做Unity小游戲的開發(fā)者,大概都遇到過(guò)這樣的困境:明明在編輯器里跑得好好的,打包成WebGL上線后,卻出現(xiàn)掉幀、發(fā)熱、啟動(dòng)慢、甚至閃退的問(wèn)題。用戶一卡就流失,好不容易拉來(lái)的流量也留不住。這篇文章,就從小游戲的底層原理講起,幫你一步步定位性能瓶頸,把這些“隱形殺手”逐個(gè)擊破。


      01

      前言

      本章從“什么是小游戲”出發(fā),簡(jiǎn)要介紹小游戲的概念、適用范圍與開發(fā)原理,并梳理Unity小游戲性能優(yōu)化的必要性及問(wèn)題定位的基本思路,為后續(xù)各章節(jié)的深入討論提供背景框架。

      1.1 什么是小游戲

      “小游戲”是一個(gè)較為寬泛的概念。廣義上,它通常指輕量、上手快、適合碎片化時(shí)間游玩的游戲;而對(duì)開發(fā)者而言,它更多是指依托于特定平臺(tái)運(yùn)行的游戲應(yīng)用。例如微信在2017年推出的爆款小游戲“跳一跳”,無(wú)需額外安裝,直接在微信內(nèi)即可游玩。如今,微信、抖音、快手、QQ、支付寶等多個(gè)平臺(tái)都提供了小游戲入口,品類也日益豐富。

      這類基于常用平臺(tái)的小游戲往往無(wú)需下載、安裝或卸載,即點(diǎn)即玩,體驗(yàn)更輕便。除即時(shí)體驗(yàn)外,小游戲還能借助平臺(tái)的賬號(hào)體系、好友關(guān)系等能力,具備較強(qiáng)的社交屬性,例如排行榜與邀請(qǐng)等功能。相較于APP手游,小游戲在類型上更偏輕松休閑,但也不乏玩法更復(fù)雜的重度產(chǎn)品。近年來(lái),不少APP游戲也移植了小游戲版本,借助平臺(tái)流量實(shí)現(xiàn)快速獲量與更高的用戶留存。

      1.2 適用范圍

      本文主要針對(duì)Unity WebGL轉(zhuǎn)微信小游戲(下文簡(jiǎn)稱微小)的性能優(yōu)化場(chǎng)景,文中的經(jīng)驗(yàn)數(shù)據(jù)、工具鏈說(shuō)明和優(yōu)化建議大多基于此方案。部分結(jié)論(如性能差異倍數(shù)、內(nèi)存閾值、WASM編譯內(nèi)存估算等)不一定適用于Cocos/Laya/Godot等其他引擎,也不一定適用于抖音、快手等非微信平臺(tái)。讀者在參考時(shí)請(qǐng)結(jié)合自身項(xiàng)目的引擎、宿主平臺(tái)和運(yùn)行環(huán)境具體分析。

      1.3 小游戲的開發(fā)原理

      各類小游戲平臺(tái)通常面向多樣化的開發(fā)需求,支持開發(fā)者使用不同的游戲引擎或技術(shù)方案進(jìn)行開發(fā),常見(jiàn)包括Unity、Cocos、Godot、Laya等。小游戲平臺(tái)并不直接綁定具體的游戲引擎,而是以引擎構(gòu)建的產(chǎn)物作為接入與運(yùn)行的基礎(chǔ)。各引擎均有對(duì)小游戲的適配與支持,能輸出合適的產(chǎn)物在小游戲環(huán)境中運(yùn)行,具體適配原理可參考對(duì)應(yīng)引擎的官方文檔,此處不再展開。當(dāng)前簡(jiǎn)譜主要針對(duì)使用Unity引擎開發(fā)并轉(zhuǎn)換的小游戲項(xiàng)目。

      以上常見(jiàn)的游戲引擎可分為兩類:基于JavaScript/TypeScript的HTML5游戲引擎,以及原生目標(biāo)的游戲引擎,Unity屬于后者。兩種類型的適配方式有所不同。對(duì)于Unity項(xiàng)目而言,適配方式基于WebAssembly技術(shù),將游戲代碼導(dǎo)出為WASM代碼,通過(guò)膠水層代碼運(yùn)行在瀏覽器環(huán)境中。這種方式的優(yōu)勢(shì)在于保持原有引擎工具鏈和技術(shù)棧不變,開發(fā)者無(wú)需重寫游戲核心邏輯,通過(guò)轉(zhuǎn)換工具即可完成小游戲適配。

      1.4 為什么要關(guān)注Unity小游戲的性能

      玩家遇到掉幀、卡頓、發(fā)熱、閃退等性能問(wèn)題時(shí),無(wú)論游戲美術(shù)是否精良、玩法是否有趣,體驗(yàn)都會(huì)直接變差,黏性隨之下降。小游戲易上手、節(jié)奏快,遭遇性能問(wèn)題后玩家流失會(huì)更快。

      此外,相比于APP,小游戲即開即用的特點(diǎn)使玩家對(duì)啟動(dòng)耗時(shí)更加敏感 —— 從點(diǎn)開到進(jìn)入正式場(chǎng)景的時(shí)間過(guò)長(zhǎng),用戶流失的可能性就會(huì)越大。

      從技術(shù)角度來(lái)看,Unity小游戲以WebAssembly(WASM)+ WebGL為核心技術(shù)方案,運(yùn)行性能會(huì)極大影響可承載的游戲內(nèi)容玩法。開發(fā)者需要關(guān)注不同技術(shù)棧帶來(lái)的性能差異,以及不同系統(tǒng)平臺(tái)(Android、iOS、Windows PC)之間的性能差異。

      1.4.1 Unity WebGL與APP的運(yùn)行性能差異

      CPU性能差異:

      • Unity WebGL以WASM虛擬機(jī)的形式運(yùn)行在類瀏覽器環(huán)境中,CPU算力受限于虛擬機(jī)的執(zhí)行效率。

      • 在多數(shù)小游戲運(yùn)行環(huán)境和Unity WebGL轉(zhuǎn)小游戲方案中,常規(guī)C# 多線程/Job多線程能力受限,不能按原生APP的線程模型使用,導(dǎo)致AI、動(dòng)畫、渲染等模塊無(wú)法獲得多線程加速。新版Unity Web平臺(tái)已提供WebAssembly threads支持入口,但標(biāo)準(zhǔn)C# 多線程仍有限制,且依賴瀏覽器/宿主對(duì)SharedArrayBuffer等能力的支持。

      這是導(dǎo)致Unity WebGL與APP存在性能差距的最主要因素。作為常見(jiàn)經(jīng)驗(yàn)值/保守預(yù)算,Unity WebGL通常約為APP手游性能的1/3,開發(fā)者應(yīng)特別關(guān)注CPU側(cè)的性能瓶頸。但需明確,不同機(jī)型、Unity版本、是否開啟iOS高性能模式、業(yè)務(wù)瓶頸在CPU還是GPU,都會(huì)顯著影響這一比例。

      GPU性能差異:

      • Unity以WebGL API進(jìn)行渲染,其中WebGL 1.0相當(dāng)于OpenGL ES 2.0,WebGL 2.0相當(dāng)于OpenGL ES 3.0。

      • WebGL在原生渲染API之上封裝存在少量開銷,但基本渲染能力與原生APP接近。

      • GPU Instancing、SRP Batcher等渲染特性需要WebGL 2.0。當(dāng)APP手游使用了這些特性而小游戲未開啟WebGL 2.0時(shí),性能差距會(huì)進(jìn)一步拉大。

      1.4.2 WASM與JS的運(yùn)行差異

      • WASM是靜態(tài)類型的二進(jìn)制指令格式(虛擬機(jī)字節(jié)碼),其類型系統(tǒng)使JIT優(yōu)化能更準(zhǔn)確地預(yù)判運(yùn)行期類型,因此能更快達(dá)到JIT指令優(yōu)化后的峰值。在計(jì)算密集型、類型穩(wěn)定的場(chǎng)景中,WASM通常更容易獲得穩(wěn)定性能,但具體差距依賴引擎、宿主、代碼形態(tài)和平臺(tái),不能簡(jiǎn)單以固定倍數(shù)對(duì)比。

      • Unity引擎目前未針對(duì)瀏覽器環(huán)境做充分優(yōu)化(如WASM與宿主接口互調(diào)頻次偏高、未做充分的代碼路徑裁剪),整體較為臃腫,部分應(yīng)用場(chǎng)景反而遜于JS的輕量實(shí)現(xiàn)。

      因此,兩者在實(shí)際使用中不能簡(jiǎn)單以語(yǔ)言算力對(duì)比,需以實(shí)測(cè)游戲?yàn)闇?zhǔn)。

      1.4.3 系統(tǒng)平臺(tái)之間的性能差異

      • Android與Windows PC:Android平臺(tái)(以微信小游戲?yàn)槔ǔ;赬Web/Chromium體系,WASM虛擬機(jī)內(nèi)核大體可理解為V8)與Windows PC均使用V8作為WASM虛擬機(jī)內(nèi)核,均支持JIT,在相同算力條件下兩者性能接近。但需注意移動(dòng)平臺(tái)散熱更差,對(duì)性能要求更苛刻。不同平臺(tái)和宿主版本的實(shí)際內(nèi)核可能存在差異,不宜一概而論。

      • iOS:iOS默認(rèn)為普通模式,不支持JIT,可用于超休閑游戲;中重度游戲建議開啟iOS高性能模式以支持JIT,但該模式需要更多精力進(jìn)行調(diào)優(yōu),尤其在啟動(dòng)發(fā)燙與內(nèi)存方面。

      iOS高性能模式:

      https://developers.weixin.qq.com/minigame/dev/guide/game-engine/unity-webgl-transform/Design/iOSOptimization.html

      1.5 如何確定問(wèn)題

      定位思路

      發(fā)現(xiàn)性能問(wèn)題后的第一步就是確定問(wèn)題。如果閱讀過(guò)UWA提供的Unity移動(dòng)端性能優(yōu)化簡(jiǎn)譜,讀者可能已對(duì)Unity常見(jiàn)性能問(wèn)題有一定認(rèn)知。在小游戲側(cè),移動(dòng)端的知識(shí)體系大部分仍然適用,但也有不少小游戲獨(dú)有的問(wèn)題需要特別留意。總之,確定問(wèn)題本身也是一項(xiàng)挑戰(zhàn)。

      可用工具

      工欲善其事必先利其器,直接精確的性能數(shù)據(jù)能更直觀地反映性能瓶頸,事半功倍。從小游戲角度,可用工具主要分為三個(gè)層面:

      • 平臺(tái)層:各小游戲官方平臺(tái)基本都提供自帶的性能調(diào)試與監(jiān)控工具(如微信/抖音開發(fā)者工具)。

      • 引擎層:Unity Profiler、Memory Profiler等,用于定位引擎內(nèi)部的CPU與內(nèi)存瓶頸。

      • 系統(tǒng)層:Android Studio Profiler、Xcode Instruments等,用于從進(jìn)程視角分析整體資源消耗。

      此外,UWA已對(duì)微信、抖音等小游戲平臺(tái)提供支持。UWA GOT Online工具可通過(guò)SDK快速集成到測(cè)試項(xiàng)目中,真機(jī)測(cè)試完成后在極短時(shí)間內(nèi)完成數(shù)據(jù)上傳與解析,自動(dòng)生成一系列可視化圖表。同時(shí),基于UWA豐富的優(yōu)化經(jīng)驗(yàn)和數(shù)據(jù)庫(kù)進(jìn)行評(píng)分,針對(duì)各性能模塊提供分析建議和參數(shù)變化趨勢(shì)。

      通用原則——PC開發(fā)者工具 vs 真機(jī)測(cè)試:小游戲開發(fā)中,PC端開發(fā)者工具的便捷性很容易讓人依賴其數(shù)據(jù)進(jìn)行性能判定,但工具環(huán)境與真機(jī)環(huán)境在多方面存在顯著差異,貫穿CPU、內(nèi)存、GPU、啟動(dòng)耗時(shí)等所有性能維度。例如:紋理壓縮格式(ASTC等)在PC上會(huì)回退為RGBA32導(dǎo)致內(nèi)存虛高、WASM編譯與JIT行為在iOS/Android真機(jī)上與PC模擬差異明顯、PC的高性能CPU會(huì)掩蓋真機(jī)上更易暴露的瓶頸。因此,任何時(shí)候都應(yīng)優(yōu)先以真機(jī)測(cè)試數(shù)據(jù)為最終依據(jù),PC開發(fā)者工具僅用于初步調(diào)試和功能驗(yàn)證。后續(xù)各章節(jié)中也會(huì)反復(fù)強(qiáng)調(diào)這一原則。

      問(wèn)題定位檢查清單

      • 確認(rèn)問(wèn)題現(xiàn)象:掉幀/卡頓/發(fā)熱/閃退/啟動(dòng)慢,明確優(yōu)化目標(biāo)

      • 使用平臺(tái)調(diào)試工具(微信/抖音開發(fā)者工具)獲取初步性能數(shù)據(jù)

      • 使用Unity Profiler/Memory Profiler定位引擎層瓶頸

      • 真機(jī)測(cè)試(Android + iOS),勿僅依賴PC開發(fā)者工具數(shù)據(jù)

      • 借助UWA GOT Online等第三方工具獲取深度分析報(bào)告與優(yōu)化建議

      • 對(duì)比APP版本與原生性能基線,區(qū)分通用問(wèn)題與小游戲特有問(wèn)題

      02

      啟動(dòng)耗時(shí)

      啟動(dòng)耗時(shí)是玩家對(duì)小游戲最直接的性能第一印象。本章圍繞啟動(dòng)流程中的三個(gè)核心環(huán)節(jié) —— 首包資源下載、WASM代碼下載與編譯、引擎初始化及首幀邏輯 —— 逐一分析各階段的優(yōu)化方法,并匯總可落地的檢查清單。

      2.1 啟動(dòng)流程概覽

      當(dāng)玩家上手一款小游戲時(shí),最先影響到體驗(yàn)的性能指標(biāo)就是啟動(dòng)耗時(shí)。在小游戲快節(jié)奏的環(huán)境下,啟動(dòng)過(guò)長(zhǎng)可能導(dǎo)致玩家尚未體驗(yàn)游戲內(nèi)容就已流失。根據(jù)微信小游戲官方數(shù)據(jù),普通小游戲啟動(dòng)時(shí)間為7~10s,不經(jīng)優(yōu)化的Unity WebGL游戲啟動(dòng)可達(dá)該時(shí)間的2~3倍以上。優(yōu)化目標(biāo)是將首屏啟動(dòng)耗時(shí)控制在5~10s甚至更短。

      以微信小游戲(以下簡(jiǎn)稱微小)為例,Unity WebGL轉(zhuǎn)換的微信小游戲主要依靠Unity Loader進(jìn)行初始化,其工作流程如下:


      不同平臺(tái)小游戲的啟動(dòng)細(xì)節(jié)可能略有差異,但總體可歸納為三個(gè)核心環(huán)節(jié):首包資源下載、WASM代碼下載和編譯、引擎初始化與開發(fā)者首幀邏輯。

      此外,UWA GOT Online的小游戲報(bào)告中也提供了啟動(dòng)耗時(shí)的相關(guān)指標(biāo)、推薦值和優(yōu)化建議,可幫助快速定位耗時(shí)較高的階段:



      2.2 首包資源下載

      首包是什么:一般名稱為xxx.webgl.data.unityweb.bin.txt,存放在CDN服務(wù)器上。首次進(jìn)入游戲時(shí)下載、解壓后保持在內(nèi)存,二次啟動(dòng)可直接走緩存。因此對(duì)啟動(dòng)耗時(shí)而言,主要關(guān)注首次下載或首包更新時(shí)的下載耗時(shí)。

      首包內(nèi)容構(gòu)成:首包文件大小直接影響下載耗時(shí),可使用AssetStudio查看其中包含的資源,通常包括:

      • Unity Default Resources — 引擎默認(rèn)資源(Arial字體、默認(rèn)Mesh、紋理等)

      • IL2CPP Meta Data — C# 代碼經(jīng)IL2CPP生成的類、方法等元信息

      • unity_builtin_extra — Always Included的Shader

      • BuildSettings中所有Active的場(chǎng)景

      • Resources文件夾中的資源及其引用的其他資源

      • 全局設(shè)置及引用到的資源(如Splash圖片等)

      優(yōu)化方法:

      1. 排查與精簡(jiǎn):結(jié)合AssetStudio查看首包內(nèi)容,排查其中內(nèi)存占用較高或不符合預(yù)期出現(xiàn)的資源,盡量只保留首場(chǎng)景中的必要資源。下圖為AssetStudio中看到的部分首包內(nèi)容。


      舉例來(lái)說(shuō),加載過(guò)程的提示文字可能會(huì)使用自定義字體,如果用全量字體其內(nèi)存占用對(duì)于首包來(lái)說(shuō)可能過(guò)大。然而實(shí)際在加載過(guò)程中用到的文字量有限,可考慮單獨(dú)拆分出一個(gè)更小的字體專門用于首包。

      2. 轉(zhuǎn)化工具設(shè)置:勾選轉(zhuǎn)換工具面板的“壓縮首包資源”選項(xiàng),可對(duì)首包進(jìn)行進(jìn)一步br壓縮。微信還提供了首包資源優(yōu)化功能,可清理首包中項(xiàng)目并未實(shí)際使用的資源,進(jìn)一步瘦身。


      3. 目標(biāo)值:一般建議將首包資源大小控制在5MB以下

      2.3 WASM代碼下載與編譯載

      代碼包是什么:一般名稱為xxx.webgl.wasm.code.unityweb.wasm.br,默認(rèn)進(jìn)行br壓縮。在啟動(dòng)階段,wasmcode與首包資源并行下載,共同占用下載帶寬;下載完成后進(jìn)行編譯,編譯過(guò)程本身也消耗CPU資源。綜合來(lái)看,核心優(yōu)化方向是降低WASM代碼體積,一般建議將原始代碼包控制在30MB以下

      優(yōu)化方法:

      1. 代碼分包(最常用):在開發(fā)者工具中安裝wasmCodeSplit插件,原理是將原WASM拆分為主包(啟動(dòng)加載)和子包(延遲加載)。小游戲先加載較小的主包進(jìn)入主場(chǎng)景,再異步加載剩余分包,可大幅降低下載與編譯耗時(shí)。具體操作可參考官方文檔。


      2. 代碼裁剪:Unity未針對(duì)WebGL平臺(tái)做特別裁剪,默認(rèn)會(huì)將引擎、業(yè)務(wù)代碼、第三方插件全部編譯為WASM二進(jìn)制。建議勾選“Strip Engine Code”并將“Managed Stripping Level”設(shè)為High,可有效縮減代碼包體積。


      3.IL2CPP Size選項(xiàng):使用Unity 2021以上版本時(shí),可在PlayerSettings中將IL2CPP選項(xiàng)設(shè)為更小尺寸(SIZE),減少函數(shù)量。


      4.刪除多余插件:排查項(xiàng)目使用的第三方插件,手動(dòng)移除不必要的Unity模塊(如物理模塊、Unity數(shù)據(jù)統(tǒng)計(jì)等),從源頭減少代碼量。

      2.4 引擎初始化與開發(fā)者首幀邏輯

      該階段做什么:引擎自身模塊與數(shù)據(jù)初始化、首個(gè)場(chǎng)景加載以及MonoBehaviour的Awake/Start流程。此階段CPU處理密集,但網(wǎng)絡(luò)處于空閑狀態(tài),可利用預(yù)下載功能提前緩存后續(xù)資源(詳見(jiàn)第3章資源加載)。

      優(yōu)化要點(diǎn):

      • MonoBehaviour腳本在首幀的Start/Awake中應(yīng)盡量少做邏輯,優(yōu)先把畫面呈現(xiàn)出來(lái)

      • 初始場(chǎng)景不宜過(guò)大,通常只呈現(xiàn)Splash場(chǎng)景即可

      • 初始場(chǎng)景中如需加載后續(xù)主場(chǎng)景或配置,建議采用分幀策略,切勿在Start/Awake中阻塞

      調(diào)試工具 —— Android CPU Profiler

      微信提供了Android CPU Profiler功能,可用于排查此階段的CPU邏輯開銷。使用方法如下:

      1. 從右上角“…”打開菜單 → 開發(fā)調(diào)試 → 選擇Start CPU Profile開始采集

      2. 采集一段時(shí)間后點(diǎn)擊Stop CPU Profiler,生成.cpuprofile文件

      3. 文件路徑通常為:Android/data/com.tencent.mm/MicroMsg/appbrand/trace

      4. 數(shù)據(jù)可通過(guò)Chrome、Edge,或開發(fā)者工具中的JavaScript探測(cè)器打開分析

      注意:若希望在堆棧中看到可讀函數(shù)名,需勾選Profiling-funcs或使用Development模式,但會(huì)帶來(lái)一定性能開銷。否則函數(shù)僅顯示數(shù)字ID,需借助symbols文件進(jìn)行映射(微信提供Python替換腳本可自動(dòng)處理)。此外,若要排查啟動(dòng)階段,可手動(dòng)修改game.js,讓游戲在啟動(dòng)時(shí)增加一段黑屏等待時(shí)間,便于在啟動(dòng)期間打開調(diào)試。

      2.5 啟動(dòng)耗時(shí)檢查清單

      • 首包資源<5MB,僅包含首場(chǎng)景必要資源

      • WASM原始代碼包<30MB

      • 開啟代碼分包(wasmCodeSplit插件)

      • 勾選“Strip Engine Code”,Managed Stripping Level設(shè)為High

      • Unity 2021 + 設(shè)置IL2CPP選項(xiàng)為更小尺寸(SIZE)

      • 首場(chǎng)景只保留Splash,Awake/Start不阻塞主線程

      • 初始場(chǎng)景中后續(xù)加載采取分幀策略,不在首幀同步完成

      03

      資源加載

      啟動(dòng)耗時(shí)章節(jié)提到首包內(nèi)容應(yīng)盡可能精簡(jiǎn),其余資源需放在CDN中延遲加載,因此資源的按需加載是小游戲中至關(guān)重要的環(huán)節(jié)。本章從加載方案選擇、緩存機(jī)制、AssetBundle適配三個(gè)維度展開,幫助開發(fā)者在加載效率與內(nèi)存占用之間找到平衡。

      3.1 常規(guī)加載方案

      三種方案對(duì)比:目前常見(jiàn)的加載策略有三種 —— Addressable方案、AssetBundle方案、Unity Instant Game方案。無(wú)論哪種方案,微信小游戲環(huán)境均不支持本地Bundle加載,最終都采用上傳CDN方式在游戲運(yùn)行時(shí)異步按需下載。

      • Addressable(AA):Unity官方推薦的資源管理方案,支持遠(yuǎn)程加載與本地緩存,適合大多數(shù)項(xiàng)目。

      • AssetBundle(AB):傳統(tǒng)分包方案,在內(nèi)存和加載效率方面優(yōu)于AA,尤其適合相對(duì)重度的游戲。目前UWA接觸的小游戲項(xiàng)目中使用AB方案的偏多。

      • Instant Game:Unity官方提供的自動(dòng)加載方案,僅適合原生APP未使用資源按需加載、總包體較小的輕度游戲,具體參考團(tuán)結(jié)引擎文檔(https://docs.unity.cn/cn/tuanjiemanual/Manual/Wechat.html)。

      對(duì)于AA和AB兩種方案,一般可以沿用原APP游戲工程的管理方案,轉(zhuǎn)化工作量相對(duì)較小。后續(xù)討論以AssetBundle方案為主,其余方案可參考官方文檔。

      AB打包參數(shù)建議:使用AssetBundle進(jìn)行資源打包時(shí),推薦以下設(shè)置:

      • BuildAssetBundleOptions.AppendHashToAssetBundleName:開啟后Bundle名會(huì)攜帶Hash,是小游戲中資源緩存及緩存淘汰機(jī)制的重要依據(jù)(詳見(jiàn)3.2節(jié))。

      • BuildAssetBundleOptions.ChunkBasedCompression:LZ4壓縮方式,加載速度與包體大小更均衡。

      • DisableWriteTypeTree:如無(wú)新老Unity版本兼容需求,建議開啟以提升加載速度并降低內(nèi)存。

      加載接口:小游戲不支持AssetBundle本地加載,從服務(wù)器下載Bundle主要使用以下接口:

      • UnityWebRequestAssetBundle.GetAssetBundle

      • UnityWebRequest

      不建議使用WWW.LoadFromCacheOrDownload或WWW等帶Cache接口,WebGL模式下會(huì)通過(guò)JS模擬文件系統(tǒng),帶來(lái)額外內(nèi)存消耗。

      3.2 資源緩存

      緩存機(jī)制:Unity Loader插件已內(nèi)置資源緩存與淘汰功能,無(wú)需開發(fā)者自行實(shí)現(xiàn)。UnityWebRequest和UnityWebRequestAssetBundle接口均會(huì)自動(dòng)觸發(fā)緩存,業(yè)務(wù)側(cè)無(wú)需關(guān)心資源是否有緩存,正常調(diào)用API即可。可通過(guò)Loader插件返回的Log判斷當(dāng)前是走下載還是緩存。

      預(yù)下載:Loader插件提供預(yù)下載功能,目的是充分利用網(wǎng)絡(luò)帶寬。啟動(dòng)流程中「引擎初始化與首場(chǎng)景準(zhǔn)備」階段CPU處理密集,但網(wǎng)絡(luò)處于空閑,利用預(yù)下載可在此階段提前下載并緩存資源,后續(xù)即可直接走本地緩存。預(yù)下載文件總體積建議控制在3~5MB以內(nèi),文件數(shù)量不超過(guò)10個(gè)(此階段最多10個(gè)并發(fā),超出將排隊(duì))。

      緩存過(guò)濾:并非所有文件都適合緩存。可在導(dǎo)出面板中配置不自動(dòng)緩存的文件類型(如默認(rèn)不緩存.json文件),也可在minigame/unity-namespace.js中手動(dòng)處理緩存邏輯。

      版本管理:若資源文件已緩存到本地但后續(xù)版本更新,不特殊處理會(huì)繼續(xù)加載舊緩存。需要以Hash區(qū)分資源版本 —— 本地有舊緩存時(shí)先清理再寫入新版本。只需將資源URL攜帶Hash作為版本依據(jù)即可,默認(rèn)Hash長(zhǎng)度為32;若游戲自行計(jì)算CRC,也可設(shè)為CRC長(zhǎng)度。注意Hash必須以‘-’或‘_’作為分隔符,其他符號(hào)無(wú)法正確處理版本信息。

      緩存上限與淘汰:緩存體積隨游戲進(jìn)程逐漸增大,默認(rèn)上限為200MB。可通過(guò) maxStorage調(diào)整上限,也可前往微信后臺(tái)申請(qǐng)空間提升,最高可達(dá)1GB。達(dá)到上限后Loader按LRU規(guī)則清理早期緩存。為避免頻繁觸發(fā),默認(rèn)額外多清理30MB(可通過(guò)defaultReleaseSize修改)。清理時(shí)支持忽略指定文件使其不被自動(dòng)清理,僅可主動(dòng)刪除,具體通過(guò)minigame/unity-namespace.js中isErasableFile函數(shù)控制。

      常用接口:

      • public string WX.PluginCachePath:獲取自動(dòng)緩存的文件存儲(chǔ)路徑,返回值:${wx.env.USER_DATA_PATH}/__GAME_FILE_CACHE

      • public string WX.GetCachePath(string url):傳入U(xiǎn)RL或文件相對(duì)路徑,返回緩存路徑(無(wú)緩存則返回空字符串)

      • public void CleanAllFileCache(Action action):清理所有自動(dòng)緩存的文件

      • public void CleanFileCache(int fileSize, Action action):從緩存目錄中釋放指定大小的文件

      • public void RemoveFile(string path, Action action):從緩存目錄中刪除指定文件

      3.3 小游戲中的AssetBundle

      AB內(nèi)存差異:AssetBundle打包后的文件由文件頭(屬性數(shù)據(jù)、Asset信息、依賴關(guān)系等)和主數(shù)據(jù)(平臺(tái)對(duì)應(yīng)的Asset數(shù)據(jù))兩部分組成。在Standalone、Android、iOS等具有本地文件系統(tǒng)的平臺(tái)上,只需加載文件頭,運(yùn)行時(shí)按需讀取資產(chǎn)數(shù)據(jù)。而WebGL平臺(tái)受瀏覽器權(quán)限限制不能直接訪問(wèn)本地IO,加載AB時(shí)需將兩部分全部加載到內(nèi)存中。因此,原生APP只需關(guān)注AB文件頭內(nèi)存,但小游戲還需額外關(guān)注AB文件本身的內(nèi)存占用。

      WXAssetBundle方案:小游戲平臺(tái)提供了專用AB接口來(lái)解決上述問(wèn)題。以微信小游戲?yàn)槔褂肳XAssetBundle將文件系統(tǒng)接口橋接到微信的文件系統(tǒng),使AB可讀寫到小游戲緩存目錄,從而避免AB文件整體進(jìn)入內(nèi)存。經(jīng)測(cè)試,使用Unity原生AB接口時(shí),AB文件本體內(nèi)存會(huì)進(jìn)入U(xiǎn)nityHeap并被Reserve;更換為WXAssetBundle后,該內(nèi)存不再出現(xiàn)在UnityHeap中,而是進(jìn)入本地緩存(仍需關(guān)注默認(rèn)200MB上限)。

      在UWA GOT Online小游戲報(bào)告中,也專門統(tǒng)計(jì)了WXAssetBundle接口的內(nèi)存數(shù)據(jù)。下圖為同一AssetBundle、不同加載接口的對(duì)照測(cè)試 —— 前半段為WXAB接口加載/卸載,后半段為Unity原生AB接口。可見(jiàn)前者幾乎不會(huì)使Reserved Total升高,后者則有明顯變化。



      打包策略:無(wú)論使用哪種AB接口,打包策略都值得關(guān)注。分包粒度太大,單個(gè)AB下載易卡頓;粒度太小則文件數(shù)量過(guò)多,IO和下載效率下降。建議根據(jù)資源使用頻率和生命周期采用混合策略 —— 常更新的資源(如UI元素)打包至較小Bundle便于熱更新,不常更新的資源(如場(chǎng)景資源)可打包至較大Bundle。通常單個(gè)AB包建議控制在10MB以內(nèi),總體AB駐留數(shù)量在1000個(gè)以內(nèi)。

      AB利用率:UWA提出了AB利用率的概念 —— 在特定測(cè)試流程中,某AB文件被加載進(jìn)內(nèi)存但真正用到的資產(chǎn)(含主動(dòng)加載與被動(dòng)依賴)比例很低,則判定為低利用率。這類AB的打包策略可能存在浪費(fèi),定位到具體AB后可進(jìn)一步排查,對(duì)包內(nèi)資產(chǎn)進(jìn)行更精細(xì)的劃分。

      3.4 資源加載檢查清單

      • 打包參數(shù):開啟AppendHashToAssetBundleName,使用ChunkBasedCompression (LZ4)

      • 非跨版本兼容需求時(shí),開啟DisableWriteTypeTree

      • 使用UnityWebRequest/UnityWebRequestAssetBundle加載(不用WWW等帶Cache接口)

      • 預(yù)下載文件總體積控制在3~5MB,文件數(shù)≤10個(gè)

      • 單個(gè)AB包<10MB,總體AB駐留數(shù)量<1000 個(gè)

      • 檢查AB利用率,避免大量未使用資產(chǎn)進(jìn)入內(nèi)存

      • 關(guān)注緩存上限(默認(rèn)200MB,可申請(qǐng)?zhí)嵘?GB),必要時(shí)調(diào)整maxStorage

      04

      內(nèi)存

      內(nèi)存是小游戲中與閃退直接掛鉤的核心性能指標(biāo),其分布結(jié)構(gòu)、擴(kuò)容機(jī)制和平臺(tái)限制均與原生APP存在顯著差異。本章從小游戲進(jìn)程視角出發(fā),梳理內(nèi)存的整體構(gòu)成與各子模塊的優(yōu)化要點(diǎn),并對(duì)比iOS不同運(yùn)行模式下的內(nèi)存分布差異。

      4.1 進(jìn)程視角的內(nèi)存限制

      Android:小游戲通常運(yùn)行在獨(dú)立進(jìn)程中(如微信小游戲?yàn)?com.tencent.mm:appbrand0/1/2),內(nèi)存相對(duì)寬松。一般建議低端機(jī)<1.2GB,中高端機(jī)<1.5GB。可通過(guò)ADB或UWA Gears工具查看進(jìn)程內(nèi)存,下圖為Gears采集到小游戲運(yùn)行時(shí)的PSS內(nèi)存走勢(shì)。


      iOS:整體限制更嚴(yán)格,建議低端機(jī)<1GB,中高端機(jī)<1.4GB,最終需結(jié)合Xcode Instruments實(shí)際數(shù)據(jù)具體分析,微小通常關(guān)注com.apple.WebKit.WebContent進(jìn)程。


      iOS根據(jù)運(yùn)行模式的不同,內(nèi)存限制也有所差異:

      • 普通模式(默認(rèn)):WASM運(yùn)行無(wú)JIT,計(jì)算性能受限。小游戲進(jìn)程與微信綁定,同在WeChat進(jìn)程中。

      • 高性能模式:CPU算力明顯提升,但內(nèi)存限制更嚴(yán)格 —— 2GB內(nèi)存設(shè)備上限約1GB,3GB及以上設(shè)備上限約1.5GB,工程上建議控制在1.2~1.3GB以內(nèi)。此時(shí)小游戲運(yùn)行在獨(dú)立進(jìn)程com.apple.WebKit.WebContent中。

      • 高性能+模式:在高性能模式基礎(chǔ)上進(jìn)一步升級(jí),保留游戲獨(dú)立進(jìn)程的同時(shí)將渲染重新挪回微信進(jìn)程,渲染效果和渲染內(nèi)存消耗均得到改善。推薦使用WebGL2、內(nèi)存壓力大的游戲開啟該模式。

      4.2 小游戲內(nèi)存結(jié)構(gòu)

      Unity WebGL以WebAssembly+WebGL技術(shù)為基礎(chǔ),游戲內(nèi)存分配完全托管在瀏覽器環(huán)境中。適配到小游戲后,進(jìn)程成為“容器”,內(nèi)存組成結(jié)構(gòu)基本一致。典型游戲的內(nèi)存分布如下圖所示:


      各內(nèi)存區(qū)域簡(jiǎn)要說(shuō)明:

      • UnityHeap:托管堆、本機(jī)堆與原生插件底層內(nèi)存,初始值為轉(zhuǎn)化面板中的“UnityHeap預(yù)留內(nèi)存”,運(yùn)行時(shí)只增不減且存在內(nèi)存碎片。這是大部分小游戲項(xiàng)目中最主要的內(nèi)存來(lái)源,是排查與優(yōu)化的重點(diǎn)。

      • WASM編譯:代碼編譯與運(yùn)行時(shí)指令優(yōu)化產(chǎn)生的內(nèi)存,占比相對(duì)較高。一般無(wú)工具直接檢測(cè)該部分精確占用。常見(jiàn)經(jīng)驗(yàn)上可按未壓縮WASM代碼包的約8~12倍進(jìn)行數(shù)量級(jí)估算,但實(shí)際比例受平臺(tái)內(nèi)核(iOS/Android)、是否開啟JIT、分包策略及編譯優(yōu)化等級(jí)影響較大,以真機(jī)實(shí)測(cè)為準(zhǔn)

      • GPU內(nèi)存:紋理或模型Upload GPU后的顯存占用。壓縮紋理格式支持受宿主、瀏覽器、設(shè)備GPU和轉(zhuǎn)換方案影響,PC開發(fā)者工具中可能回退為RGBA32,必須以真機(jī)實(shí)測(cè)為準(zhǔn)

      • 音頻:Unity將音頻傳遞給容器后,播放時(shí)占用的內(nèi)存。

      • 基礎(chǔ)庫(kù)+Canvas:小游戲公共庫(kù)、Canvas畫布等固定開銷,基本無(wú)法針對(duì)性優(yōu)化。

      • 其它:Emscripten文件系統(tǒng)模擬等相關(guān)占用。

      4.2.1 UnityHeap

      擴(kuò)容機(jī)制:UnityHeap是為實(shí)際使用的內(nèi)存部分提前預(yù)留的上限,實(shí)際占用指標(biāo)為DynamicMemory。當(dāng)DynamicMemory接近預(yù)留上限時(shí)(如初始500MB,達(dá)到約490MB以上),會(huì)觸發(fā)擴(kuò)容 —— 在內(nèi)存中新分配一個(gè)更大的堆空間(如550MB),將舊內(nèi)容復(fù)制過(guò)來(lái)后再釋放舊堆。短時(shí)間內(nèi)產(chǎn)生內(nèi)存塊復(fù)制導(dǎo)致的內(nèi)存尖峰,極易造成閃退,尤其在iOS上更為嚴(yán)重。

      初始值設(shè)定:不宜過(guò)小(頻繁擴(kuò)容導(dǎo)致尖峰),也不宜過(guò)高(≥1024MB直接導(dǎo)致啟動(dòng)失敗)。官方參考值:輕度游戲(休閑類)256MB,中度游戲(模擬經(jīng)營(yíng)、卡牌成長(zhǎng))496MB,重度游戲(SLG、MMO)768MB

      DynamicMemory構(gòu)成:DynamicMemory=MonoHeap+NativeReserved+原生插件內(nèi)存,需分別關(guān)注各部分走勢(shì),避免泄漏。

      Mono堆內(nèi)存是C# 腳本托管對(duì)象(string、List、自定義類實(shí)例、委托等)的核心內(nèi)存區(qū)域。GC會(huì)正常回收對(duì)象,Mono使用量可以有增有降;但受WebAssembly內(nèi)存沙箱機(jī)制影響,堆容量一旦被峰值撐高便難以回縮,表現(xiàn)為峰值保持。因此在小游戲上要特別關(guān)注Mono的分配,避免單幀內(nèi)出現(xiàn)大量分配把峰值頂上去。

      NativeReserved由Unity Native產(chǎn)生,屬于引擎內(nèi)部對(duì)象。動(dòng)畫、字體、Shader等資源類內(nèi)存均包含在此。紋理、網(wǎng)格等傳給GPU的資源原本計(jì)入GPU內(nèi)存,但若開啟了Read/Write Enable選項(xiàng),CPU端還會(huì)額外存儲(chǔ)一份,計(jì)入NativeReserved。此外,使用Unity原生AssetBundle接口時(shí)AB文件本體內(nèi)存也會(huì)進(jìn)入NativeReserved,使用WXAssetBundle可將其轉(zhuǎn)移至本地緩存。

      從WXAB和原生AB的加載對(duì)比測(cè)試數(shù)據(jù)中可以看到:使用原生AB接口會(huì)使NativeReserved明顯上升,連帶推高DynamicMemory;即使卸載后NativeReserved回落,DynamicMemory也已被撐高,剩余空間相當(dāng)于被預(yù)留住了。


      針對(duì)Native部分的排查可使用Unity Memory Profiler工具,需開啟Development Build及AutoConnect。

      第三方原生插件內(nèi)存(如Lua)通常沒(méi)有單獨(dú)數(shù)值展示,可觀察DynamicMemory與Mono、Native部分的差值是否偏大。若對(duì)插件管理較明確,可通過(guò)對(duì)比測(cè)試(開關(guān)插件觀察內(nèi)存變化)進(jìn)一步定位來(lái)源。

      4.2.2 WASM編譯

      小游戲啟動(dòng)時(shí)下載WASM代碼包并進(jìn)行編譯,編譯后占據(jù)的內(nèi)存很大。常見(jiàn)經(jīng)驗(yàn)上可按未壓縮WASM代碼包的約8~12倍進(jìn)行數(shù)量級(jí)估算(如微信官方數(shù)據(jù):iOS上30MB未壓縮代碼約需300MB運(yùn)行時(shí)編譯內(nèi)存),但實(shí)際比例受平臺(tái)內(nèi)核、是否開啟JIT、分包策略及編譯優(yōu)化等級(jí)影響較大,以真機(jī)實(shí)測(cè)為準(zhǔn)

      最常見(jiàn)有效的優(yōu)化方案是代碼分包 —— 將原WASM代碼包拆分為主包和子包:

      • 主包(wasmcode):啟動(dòng)時(shí)首先加載,大小約為原包的1/3~1/2,建議控制在3~5MB,需盡量覆蓋大多數(shù)游戲場(chǎng)景和流程。

      • 子包(wasmcode1/wasmcode2):分別對(duì)應(yīng)Android和iOS平臺(tái),約7~15MB,在游戲運(yùn)行一段時(shí)間后自動(dòng)加載或缺失函數(shù)時(shí)再加載。

      分包后總大小可能比原包更大(因多出復(fù)制文件),但只有主包一定加載,其余延遲或按需下載,對(duì)運(yùn)行幾乎無(wú)影響。

      4.2.3 常見(jiàn)資源類型內(nèi)存

      對(duì)于Unity開發(fā)者而言,更直觀、更容易上手修改的是紋理、網(wǎng)格、動(dòng)畫、字體等常見(jiàn)資源類型。各類資源在小游戲內(nèi)存中的歸屬如下:

      • GPU內(nèi)存:紋理、網(wǎng)格、RenderTexture

      • NativeReserved(UnityHeap內(nèi)):動(dòng)畫、字體、Shader、開啟了Read/Write的紋理/網(wǎng)格、使用原生AB接口的AB文件本體

      • 獨(dú)立內(nèi)存:音頻資源

      《Unity移動(dòng)端游戲性能優(yōu)化簡(jiǎn)譜》中對(duì)各類資源內(nèi)存優(yōu)化已有系統(tǒng)介紹,以下僅提煉各類型的核心優(yōu)化要點(diǎn):

      紋理:內(nèi)存大戶,重點(diǎn)關(guān)注三個(gè)方面 —— ①格式:避免RGBA32/ARGB32等未壓縮格式,優(yōu)先使用ASTC/ETC2等移動(dòng)端壓縮格式(注意小游戲中格式支持因宿主和真機(jī)而異,務(wù)必真機(jī)驗(yàn)證);②分辨率:1024以上的紋理需評(píng)估是否必要,高分辨率在小屏幕上往往看不出差異卻占4倍內(nèi)存;③Read/Write Enabled:開啟后CPU端額外存一份,計(jì)入NativeReserved,非必要一律關(guān)閉。此外,開啟Mipmap會(huì)使紋理內(nèi)存增至約1.33倍,需權(quán)衡帶寬收益后決定。

      網(wǎng)格:關(guān)注頂點(diǎn)數(shù)和面片數(shù)是否超出實(shí)際表現(xiàn)需求,頂點(diǎn)屬性(UV2、Color、Tangent等)在不必要時(shí)可剝離以減小數(shù)據(jù)量。網(wǎng)格同樣存在Read/Write Enabled問(wèn)題,開啟后CPU端多存一份。

      動(dòng)畫:動(dòng)畫Clip本身占用內(nèi)存,且播放時(shí)涉及骨骼Transform更新等CPU開銷。關(guān)注Animation Clip數(shù)量與時(shí)長(zhǎng),適當(dāng)壓縮關(guān)鍵幀或降低采樣率。大量Animator處于Active狀態(tài)還會(huì)額外增加CPU負(fù)擔(dān)。

      音頻:小游戲中音頻內(nèi)存獨(dú)立于UnityHeap,但也需關(guān)注。建議使用壓縮格式(如MP3/Vorbis),并根據(jù)音頻類型選擇Loader(Decompress On Load會(huì)將完整數(shù)據(jù)常駐內(nèi)存,Streaming則按需讀取但CPU開銷更高)。

      字體:使用TextMeshPro時(shí),SDF Atlas以Alpha8格式存儲(chǔ),內(nèi)存較低;但若使用動(dòng)態(tài)字體(.ttf直接渲染),會(huì)產(chǎn)生較大內(nèi)存占用。建議優(yōu)先使用TMP靜態(tài)字體方案。首包中使用的字體應(yīng)盡可能精簡(jiǎn)字符集。

      粒子系統(tǒng):粒子數(shù)量、發(fā)射器復(fù)雜度直接影響CPU端計(jì)算和內(nèi)存分配,中低端機(jī)上應(yīng)限制Max Particles并精簡(jiǎn)粒子層級(jí)。

      以上資源內(nèi)容可以在UWA GOT Online小游戲報(bào)告中進(jìn)行詳細(xì)排查,在Resource模式中可獲取具體的資源列表。



      注意:新上手小游戲平臺(tái)的開發(fā)者常遇到紋理內(nèi)存遠(yuǎn)超預(yù)期的現(xiàn)象 —— 明明做了紋理壓縮,測(cè)試數(shù)據(jù)卻顯示很高。這通常是PC開發(fā)者工具中ASTC等壓縮格式回退為RGBA32所致,紋理壓縮格式務(wù)必以真機(jī)測(cè)試為準(zhǔn)(詳見(jiàn)1.5節(jié)關(guān)于PC工具與真機(jī)測(cè)試的原則說(shuō)明)。

      4.3 iOS高性能與高性能+模式對(duì)比

      iOS的高性能模式和高性能+模式中內(nèi)存分布存在明顯差異,UWA通過(guò)對(duì)比測(cè)試幫助讀者形成更直觀的認(rèn)識(shí)。

      高性能模式:小游戲運(yùn)行在獨(dú)立進(jìn)程com.apple.WebKit.WebContent中。幾乎所有類型的內(nèi)存都會(huì)進(jìn)入WebContent進(jìn)程(不會(huì)使WeChat進(jìn)程內(nèi)存上升),僅音頻資源例外。真正導(dǎo)致閃退的進(jìn)程是WebContent進(jìn)程。內(nèi)存分布大致如下:


      高性能+模式:官方描述為“開創(chuàng)性地在保留游戲獨(dú)立進(jìn)程的基礎(chǔ)上將渲染重新挪回了微信進(jìn)程”。測(cè)試結(jié)果顯示,屬于GPU的紋理、網(wǎng)格、RT不再進(jìn)入WebContent進(jìn)程,而是進(jìn)入WeChat進(jìn)程。但開啟了Read/Write的紋理/網(wǎng)格在CPU端仍有一份內(nèi)存位于NativeReserved中,屬于WebContent進(jìn)程。

      再次驗(yàn)證,小游戲閃退只與WebContent進(jìn)程有關(guān),一般建議控制在1.3GB以內(nèi);WeChat進(jìn)程即使大幅超過(guò)這個(gè)范圍也不會(huì)閃退。內(nèi)存分布如下:


      可見(jiàn)高性能+模式的內(nèi)存占用相比高性能模式確有下降,若高性能模式下內(nèi)存吃緊可考慮開啟高性能+。但具體仍需自行評(píng)估客戶端版本、是否存在新的畫面或性能問(wèn)題。

      4.4 內(nèi)存檢查清單

      • UnityHeap初始值合理設(shè)置(參考:輕度256MB/中度496MB/重度768MB,避免<256MB或≥1024MB)

      • 關(guān)注DynamicMemory走勢(shì),避免泄漏和頻繁擴(kuò)容引發(fā)的內(nèi)存尖峰

      • Mono堆避免單幀內(nèi)大量分配

      • 紋理避免開啟Read/Write Enable(否則CPU端多存一份計(jì)入NativeReserved)

      • 考慮使用WXAssetBundle代替原生AssetBundle接口,避免AB本體進(jìn)入U(xiǎn)nityHeap

      • WASM代碼包按約8~12倍體積數(shù)量級(jí)估算編譯期內(nèi)存,以真機(jī)為準(zhǔn),關(guān)注分包效果

      • 紋理壓縮格式以真機(jī)測(cè)試為準(zhǔn),勿依賴PC開發(fā)者工具數(shù)據(jù)

      • 內(nèi)存壓力大的游戲考慮開啟iOS高性能+模式

      05

      CPU壓力

      受限于WASM虛擬機(jī)的執(zhí)行效率以及常規(guī)C# 多線程/Job多線程能力受限,小游戲上CPU性能約為原生APP的1/3(實(shí)際比例因機(jī)型、Unity版本、iOS模式、瓶頸類型等因素而異),是小游戲平臺(tái)上最易出現(xiàn)高壓?jiǎn)栴}的維度。本章聚焦小游戲中獨(dú)有或更容易放大的CPU瓶頸場(chǎng)景,通用排查思路可參考《Unity移動(dòng)端游戲性能優(yōu)化簡(jiǎn)譜》中的CPU相關(guān)章節(jié)。

      5.1 蒙皮動(dòng)畫

      小游戲中較常見(jiàn)的CPU性能壓力來(lái)自蒙皮動(dòng)畫(Skinned Mesh Renderer)。在原生APP上,蒙皮計(jì)算可在工作線程處理,對(duì)主線程影響較小;而在小游戲中常規(guī)多線程能力受限,MeshSkinning.Update的耗時(shí)直接影響主線程,不經(jīng)處理可能成為瓶頸。下圖為某款SLG項(xiàng)目在Mi 10上的運(yùn)行數(shù)據(jù),在小怪較少的戰(zhàn)斗場(chǎng)景中也會(huì)有持續(xù)4ms的MeshSkinning.Update開銷,相對(duì)偏高。


      優(yōu)化方向有兩個(gè):

      • GPU Skinning:將蒙皮計(jì)算從CPU移至GPU處理。團(tuán)結(jié)引擎已內(nèi)置該功能,也可使用第三方GPU Skinning方案。上述SLG場(chǎng)景中替換為GPU Skinning方案后,在小怪?jǐn)?shù)量更多、更復(fù)雜的戰(zhàn)斗場(chǎng)景開銷也僅有1~2ms,且表現(xiàn)無(wú)明顯差別。

      • 控制蒙皮規(guī)模:進(jìn)一步限制骨骼數(shù)量和頂點(diǎn)數(shù)量,適當(dāng)犧牲表現(xiàn)精度以換取性能。


      5.2 邏輯代碼

      部分在APP上運(yùn)行穩(wěn)定的計(jì)算邏輯,直接移植到小游戲中效率可能明顯偏低,需要適量精簡(jiǎn)。這一部分與項(xiàng)目業(yè)務(wù)邏輯強(qiáng)相關(guān),難以給出統(tǒng)一方案,但可遵循以下排查與優(yōu)化思路:

      • 配合Profiler打點(diǎn)定位耗時(shí)的函數(shù),優(yōu)先處理耗時(shí)最高的熱點(diǎn)

      • 關(guān)注每幀都在執(zhí)行的邏輯(Update/FixedUpdate),檢查是否有不必要的重復(fù)計(jì)算

      • WebGL中Lua不支持JIT,避免將Lua用于重度計(jì)算邏輯

      • 回顧1.5節(jié)中關(guān)于PC工具與真機(jī)測(cè)試的原則:PC端CPU性能遠(yuǎn)超真機(jī),務(wù)必以真機(jī)Profiler數(shù)據(jù)為準(zhǔn)

      5.3 UI模塊

      UGUI是許多Unity項(xiàng)目中CPU開銷的重要來(lái)源,在小游戲單線程環(huán)境下影響更為明顯。主要關(guān)注以下幾個(gè)高耗時(shí)函數(shù):

      EventSystem.Update:UGUI事件系統(tǒng)的每幀更新,耗時(shí)偏高時(shí)通常與兩個(gè)因素有關(guān) —— 一是輸入回調(diào)中掛載了耗時(shí)過(guò)高的邏輯函數(shù),可通過(guò)Profiler打點(diǎn)進(jìn)一步定位;二是大量UI元素默認(rèn)開啟了Raycast Target選項(xiàng),而實(shí)際上多數(shù)Image、Text并不需要響應(yīng)點(diǎn)擊事件,關(guān)閉該選項(xiàng)可直接降低事件遍歷開銷。

      Canvas.SendWillRenderCanvases:Canvas的渲染重建入口,當(dāng)UI元素的Transform、顏色、層級(jí)等發(fā)生變化時(shí)觸發(fā)。該函數(shù)耗時(shí)與發(fā)生變化的UI元素?cái)?shù)量成正比。優(yōu)化方向包括:將動(dòng)態(tài)UI和靜態(tài)UI拆分到不同Canvas中,避免靜態(tài)元素被頻繁連帶重建;減少不必要的Layout Group、Content Size Fitter等自動(dòng)布局組件使用。

      Canvas.BuildBatch:UI元素合批為Mesh的主要耗時(shí)點(diǎn),通常緊隨SendWillRenderCanvases之后。合并批次時(shí)若發(fā)生打斷(如同一Canvas下使用了不同材質(zhì)/圖集),會(huì)顯著增加重建耗時(shí)。規(guī)劃好UI的圖集和材質(zhì)共用策略、保持合批連續(xù)性,可有效降低該開銷。

      CanvasRenderer.SyncTransform:當(dāng)UI元素的Transform發(fā)生變更時(shí)觸發(fā),頻繁調(diào)用時(shí)會(huì)連帶導(dǎo)致渲染更新開銷增高。需注意某些動(dòng)畫或邏輯中對(duì)UI元素Transform的頻繁修改。

      通用建議:動(dòng)態(tài)/靜態(tài)UI分離到不同Canvas、關(guān)閉不需要的Raycast Target、減少自動(dòng)布局組件使用、謹(jǐn)慎使用UI Particle(會(huì)作為UI元素高頻更新并重建Mesh)。

      5.4 實(shí)例化與銷毀

      在游戲運(yùn)行過(guò)程中,頻繁的Instantiate和Destroy操作在小游戲上開銷明顯,原因在于單線程環(huán)境下內(nèi)存分配與對(duì)象初始化的耗時(shí)直接阻塞主線程。

      場(chǎng)景/模塊切換:進(jìn)入新場(chǎng)景或新界面時(shí),建議采用分幀加載策略,避免在一幀內(nèi)完成大量對(duì)象的Instantiate導(dǎo)致明顯卡頓。可結(jié)合對(duì)象池(Object Pool)復(fù)用高頻創(chuàng)建銷毀的對(duì)象(如子彈、特效、UI列表項(xiàng)),減少頻繁的內(nèi)存分配與回收。

      Activate/Deactivate vs Instantiate/Destroy:對(duì)于需要頻繁顯隱的對(duì)象,使用SetActive的代價(jià)遠(yuǎn)低于Instantiate/Destroy,但大量同時(shí)處于Active狀態(tài)的對(duì)象仍會(huì)增加Update等邏輯開銷,需要在兩者之間平衡。

      Resources.UnloadUnusedAssets:卸載未使用資源是一項(xiàng)耗時(shí)操作,建議在場(chǎng)景切換完成后的靜默期執(zhí)行,避免在游戲流程中頻繁調(diào)用。

      5.5 CPU壓力檢查清單

      • 關(guān)注SkinnedMeshRenderer數(shù)量和MeshSkinning.Update耗時(shí)

      • 考慮使用GPU Skinning(團(tuán)結(jié)引擎已支持)或第三方方案

      • 控制蒙皮骨骼數(shù)和頂點(diǎn)數(shù),適當(dāng)犧牲精度換取性能

      • 邏輯代碼配合打點(diǎn)定位高耗時(shí)函數(shù),針對(duì)性精簡(jiǎn)

      • WebGL中避免用Lua處理重度邏輯(不支持JIT)

      • UI:動(dòng)態(tài)/靜態(tài)分離到不同Canvas,關(guān)閉非必要的Raycast Target

      • UI:減少自動(dòng)布局組件使用,規(guī)劃好圖集合批策略

      • 頻繁創(chuàng)建銷毀的對(duì)象使用對(duì)象池,場(chǎng)景切換采用分幀加載

      06

      GPU壓力

      小游戲上GPU運(yùn)行效率與APP接近,相對(duì)于CPU較不容易成為性能瓶頸,但GPU壓力同樣關(guān)系到幀率、發(fā)熱與功耗。本章提煉《Unity移動(dòng)端游戲性能優(yōu)化簡(jiǎn)譜》中GPU章節(jié)的核心要點(diǎn),并補(bǔ)充微信小游戲平臺(tái)在iOS上經(jīng)驗(yàn)證的幾個(gè)GPU壓力關(guān)鍵來(lái)源(HDR、RT使用、紋理精度等)。

      注意:1.5節(jié)中關(guān)于PC開發(fā)者工具與真機(jī)測(cè)試的原則在GPU側(cè)尤為重要 —— ASTC等壓縮紋理格式在PC上可能回退為RGBA32,WebGL 2.0特性(GPU Instancing、SRP Batcher)在PC與真機(jī)上的表現(xiàn)也可能存在差異,GPU數(shù)據(jù)務(wù)必以真機(jī)實(shí)測(cè)為準(zhǔn)。

      6.1 判斷GPU壓力

      當(dāng)整體幀耗時(shí)明顯超出目標(biāo)幀,但CPU側(cè)各模塊耗時(shí)之和與之存在較大差距時(shí),通常傾向于判定存在GPU壓力。在原生APP上可借助GPU Clocks或同步等待函數(shù)標(biāo)記輔助判斷,但小游戲環(huán)境下渲染線程模型存在差異,更建議結(jié)合實(shí)際表現(xiàn)綜合評(píng)估 —— 例如CPU耗時(shí)已優(yōu)化到位而幀率仍不達(dá)標(biāo)、或降低渲染分辨率后幀率明顯回升,均可作為GPU Bound的佐證。

      6.2 頂點(diǎn)階段壓力

      頂點(diǎn)階段壓力取決于渲染面片數(shù)與頂點(diǎn)著色器復(fù)雜度。GPU Primitive參數(shù)中,若剔除圖元占比高達(dá)70-80%,說(shuō)明存在大量浪費(fèi),需排查模型制作是否合理、大模型是否未拆小導(dǎo)致整體提交GPU、網(wǎng)格是否過(guò)于精細(xì)而屏占比有限等。

      優(yōu)化方法包括:LOD分級(jí)控制遠(yuǎn)距離面片數(shù)、精簡(jiǎn)復(fù)雜模型、CPU端提前剔除不可見(jiàn)物體、在中低端機(jī)上關(guān)閉多光源/陰影/多Pass等使面片數(shù)翻倍的特性。

      6.3 片元階段壓力

      片元階段的計(jì)算量取決于每幀繪制的像素?cái)?shù),由渲染分辨率和Overdraw共同決定。

      渲染分辨率:分級(jí)控制分辨率是最實(shí)用的GPU優(yōu)化手段。低端機(jī)降至0.7-0.8倍,像素?cái)?shù)可減半,3D場(chǎng)景通常可接受輕微模糊。需注意實(shí)際渲染分辨率與設(shè)備DPR(Device Pixel Ratio)相關(guān) —— 高DPR屏幕即使設(shè)置較低倍率仍可能產(chǎn)生高像素負(fù)擔(dān),建議按像素總數(shù)而非固定比例制定分檔標(biāo)準(zhǔn)。URP項(xiàng)目中可利用Camera Stack將3D場(chǎng)景渲染到低分辨率RT中,避免UI同時(shí)變模糊。

      Overdraw:指像素被重復(fù)繪制的次數(shù)。不透明物體應(yīng)通過(guò)Render Queue調(diào)整渲染順序來(lái)控制;粒子系統(tǒng)和UI是半透明Overdraw的主要來(lái)源 —— 中低端機(jī)精簡(jiǎn)粒子層級(jí)、限制Max Particles、裁剪純透明貼圖面積、考慮動(dòng)畫幀烘焙替代;UI側(cè)注意全屏遮擋時(shí)關(guān)閉底層、Mask替換為RectMask2D等。此外,后處理、Blit、Copy等操作同樣會(huì)產(chǎn)生全屏級(jí)別的Overdraw。特別地,開啟HDR會(huì)引入額外的全分辨率RT拷貝操作以及額外的顯存開銷,在小游戲環(huán)境下對(duì)GPU壓力影響顯著,建議謹(jǐn)慎評(píng)估是否必要。

      6.4 著色器與后處理

      著色器:優(yōu)先關(guān)注屏占比較高、Shader相對(duì)復(fù)雜的渲染對(duì)象(地表、建筑、特效),而非屏占比低的角色。項(xiàng)目中“萬(wàn)能Shader”常導(dǎo)致GPU對(duì)大量未使用特性進(jìn)行全額計(jì)算,應(yīng)通過(guò)關(guān)鍵字開關(guān)或拆分Shader優(yōu)化。

      后處理:是GPU壓力的常見(jiàn)來(lái)源 —— Bloom中低端機(jī)可從1/4分辨率開始下采樣;SMAA開銷較高不建議在中低端使用;DOF移動(dòng)端開銷大需謹(jǐn)慎;盡量使用Local Volume按需開啟而非全局常駐。

      6.5 GPU帶寬

      GPU帶寬主要影響能耗發(fā)熱而非幀率。Mali官方數(shù)據(jù)顯示約1GB/s帶寬造成80-100mW功率開銷,在游戲總功率中占比可觀。在小游戲中,渲染產(chǎn)生的GPU帶寬開銷在DRAM帶寬中占絕大部分,主要來(lái)自:頻繁的RT使用與切換、高精度紋理資源的采樣、以及HDR或后處理引入的額外RT拷貝。

      優(yōu)化手段包括:盡量復(fù)用RT減少切換、使用合理壓縮格式降低單像素傳輸量、3D場(chǎng)景務(wù)必開啟Mipmap(改善效果遠(yuǎn)超紋理壓縮)、避免全局強(qiáng)制各向異性過(guò)濾、減少不必要的Copy和后處理采樣。

      6.6 GPU壓力檢查清單

      • 關(guān)注渲染面片數(shù),排查剔除圖元占比過(guò)高的場(chǎng)景

      • 按像素總數(shù)分檔控制渲染分辨率,中低端機(jī)可降至0.7-0.8倍

      • 排查Overdraw(粒子系統(tǒng)、UI、后處理),定位熱點(diǎn)資源

      • 關(guān)注屏占比高且Shader復(fù)雜的渲染對(duì)象,拆分“萬(wàn)能Shader”

      • 后處理效果分級(jí)取舍,中低端機(jī)關(guān)閉開銷較高的效果

      • 關(guān)注GPU帶寬 —— 紋理壓縮、Mipmap、減少不必要的Copy和采樣

      • GPU數(shù)據(jù)(紋理格式、WebGL 2.0特性等)務(wù)必以真機(jī)測(cè)試為準(zhǔn)

      07

      功耗優(yōu)化

      小游戲的功耗優(yōu)化整體上可參考移動(dòng)端的優(yōu)化思路與經(jīng)驗(yàn),且由于移動(dòng)設(shè)備散熱條件有限,功耗問(wèn)題在小游戲上同樣不容忽視。功耗不僅關(guān)乎設(shè)備續(xù)航,更與發(fā)熱直接掛鉤 —— 當(dāng)設(shè)備溫度超過(guò)系統(tǒng)溫控閾值后,會(huì)觸發(fā)CPU/GPU降頻,導(dǎo)致幀率驟降,形成“高功耗→發(fā)熱→降頻→卡頓”的惡性循環(huán)。因此功耗優(yōu)化本質(zhì)上也是性能穩(wěn)定性優(yōu)化,核心手段與CPU、GPU章節(jié)的優(yōu)化思路一脈相承。

      7.1 幀率對(duì)功耗的影響

      首先要明確一個(gè)基本規(guī)律:在其它條件不變的情況下,幀率與功耗近似成正比,60FPS的功耗約為30FPS的兩倍。這意味著高端機(jī)型上若不加限制地跑滿幀率,反而可能因?yàn)楣倪^(guò)高導(dǎo)致發(fā)熱更嚴(yán)重。建議根據(jù)項(xiàng)目類型制定合理的目標(biāo)幀率(如休閑游戲30FPS,中度游戲30~60FPS),也可對(duì)不同場(chǎng)景動(dòng)態(tài)調(diào)整 —— 例如主界面、掛機(jī)場(chǎng)景降低幀率,核心戰(zhàn)斗場(chǎng)景再恢復(fù)到目標(biāo)幀率,從而有效控制整局功耗。

      7.2 功耗的來(lái)源

      小游戲運(yùn)行時(shí)的功耗主要來(lái)自以下幾個(gè)方面:

      • CPU:邏輯計(jì)算、蒙皮、動(dòng)畫、物理、腳本等,是小游戲功耗最主要的來(lái)源。

      • GPU:頂點(diǎn)處理、片元著色、紋理采樣、帶寬傳輸?shù)取?/p>

      • 屏幕顯示:屏幕亮度與分辨率直接關(guān)聯(lián)功耗,但開發(fā)者通常無(wú)法直接控制。

      • 網(wǎng)絡(luò)傳輸:持續(xù)的網(wǎng)絡(luò)請(qǐng)求與數(shù)據(jù)收發(fā)也會(huì)產(chǎn)生額外功耗。

      對(duì)于開發(fā)者而言,能夠直接著手優(yōu)化的主要是CPU與GPU兩部分。

      7.2.1 CPU側(cè)功耗優(yōu)化

      在原生APP上,通常需要分別排查CPU主線程與子線程中的壓力來(lái)源。但小游戲環(huán)境下常規(guī)多線程能力受限,因此重點(diǎn)關(guān)注CPU主線程上各模塊的耗時(shí)即可。排查思路與本文「CPU壓力」章節(jié)一致:通過(guò)Profiler定位高耗時(shí)模塊(渲染、UI、物理、動(dòng)畫、邏輯腳本等),找到項(xiàng)目中壓力較大的模塊并予以針對(duì)性優(yōu)化。由于功耗與CPU占用正相關(guān),降低主線程耗時(shí)本身就是在降低功耗。

      7.2.2 GPU側(cè)功耗優(yōu)化

      GPU側(cè)功耗主要從GPU計(jì)算壓力與GPU帶寬兩個(gè)維度進(jìn)行排查,與本文「GPU壓力」章節(jié)的思路一致:控制同屏面片數(shù)、合理設(shè)置渲染分辨率、減少Overdraw、精簡(jiǎn)Shader復(fù)雜度,同時(shí)關(guān)注紋理采樣次數(shù)與帶寬占用。降低GPU負(fù)載同樣直接降低功耗。

      7.3 功耗優(yōu)化檢查清單

      • 根據(jù)項(xiàng)目類型制定合理的目標(biāo)幀率,避免高端機(jī)無(wú)限制跑滿

      • 對(duì)不同場(chǎng)景動(dòng)態(tài)調(diào)整幀率(主界面/掛機(jī)降幀,核心玩法恢復(fù)目標(biāo)幀率)

      • 通過(guò)CPU主線程Profiler定位高耗時(shí)模塊并針對(duì)性優(yōu)化

      • 從GPU計(jì)算壓力與GPU帶寬兩個(gè)維度排查GPU側(cè)功耗

      • 將高溫環(huán)境(戶外、充電時(shí)游玩)納入測(cè)試覆蓋范圍

      • iOS高性能模式下尤其關(guān)注啟動(dòng)階段的發(fā)熱,避免長(zhǎng)時(shí)間連續(xù)高負(fù)載

      08

      APP轉(zhuǎn)小游戲經(jīng)驗(yàn)分享:同步轉(zhuǎn)異步功耗優(yōu)化

      本章分享一個(gè)實(shí)際項(xiàng)目中將APP遷移到小游戲時(shí)遇到的典型問(wèn)題 —— AssetBundle同步加載的兼容性改造,以及我們?cè)趯?shí)戰(zhàn)中摸索出的一套低成本解決方案。

      8.1 問(wèn)題背景

      在原生APP項(xiàng)目中,同步加載與異步加載在實(shí)際運(yùn)行時(shí)的體驗(yàn)差異通常不大,開發(fā)團(tuán)隊(duì)在早期也不一定會(huì)嚴(yán)格區(qū)分兩者的使用場(chǎng)景。但在小游戲環(huán)境中,AssetBundle文件本身不支持同步加載(從已加載的AssetBundle中加載具體資源仍可使用同步接口),這意味著原本在APP中大量使用的同步加載邏輯都需要逐一改造。如果項(xiàng)目在原生APP階段沒(méi)有提前做好這方面的規(guī)范和管理,后續(xù)轉(zhuǎn)換時(shí)的工作量會(huì)相當(dāng)可觀。

      8.2 快速定位方法

      在Unity編輯器中將小游戲工具面板的Play Mode切換為Web Play Mode,此時(shí)在Editor中運(yùn)行游戲,一旦觸發(fā)AssetBundle的同步加載就會(huì)直接拋出WebGL platform not support sync load method這類報(bào)錯(cuò),幫助快速發(fā)現(xiàn)哪些加載鏈路存在問(wèn)題。



      進(jìn)一步地,還可以在同步加載接口的報(bào)錯(cuò)位置額外增加一條報(bào)空日志,顯式輸出對(duì)應(yīng)資源的路徑信息,這樣每次報(bào)錯(cuò)時(shí)就能直接看到是哪個(gè)AB文件在哪個(gè)時(shí)機(jī)被同步加載了,排查效率大幅提升,不必逐個(gè)翻看代碼調(diào)用鏈。


      8.3 集中預(yù)加載方案

      從已加載的AssetBundle中加載具體資源仍然可以使用同步接口。基于這一點(diǎn),核心思路就清晰了:只要在使用同步接口加載資源之前,確保對(duì)應(yīng)的AssetBundle已經(jīng)通過(guò)異步方式加載到內(nèi)存中且未被卸載,那么原來(lái)的同步資源加載邏輯就完全可以保持不變。

      按照這個(gè)思路,我們的做法是在游戲流程中找到一個(gè)統(tǒng)一的、早于所有實(shí)際資源加載的時(shí)機(jī)點(diǎn),把所有會(huì)被同步加載使用的AssetBundle提前用異步接口統(tǒng)一加載一遍。只要保證后續(xù)真正使用同步接口加載資源時(shí)這些AB仍在內(nèi)存中且未被卸載,整個(gè)項(xiàng)目中原有的同步加載邏輯就不需要逐一修改,也不會(huì)在小游戲環(huán)境中觸發(fā)報(bào)錯(cuò)。

      例如原先在Initialize階段使用了同步加載會(huì)導(dǎo)致報(bào)錯(cuò),我們找到了一個(gè)更早的時(shí)機(jī)點(diǎn),通過(guò)PreloadAsync先用異步接口集中加載了timeConfig在內(nèi)的多個(gè)后續(xù)會(huì)用同步加載的資源,那么后續(xù)的邏輯無(wú)需修改也不會(huì)報(bào)錯(cuò)了。



      這種方式本質(zhì)上是將“同步改異步”的改造工作從散落在各處的資源加載點(diǎn)集中收攏到了一個(gè)統(tǒng)一的預(yù)加載節(jié)點(diǎn),既降低了修改工作量,也避免了逐處改造時(shí)容易遺漏或引入新問(wèn)題的風(fēng)險(xiǎn)。

      09

      結(jié)束語(yǔ)

      這篇文章之所以稱為簡(jiǎn)譜,實(shí)在是因?yàn)檫@些筆墨遠(yuǎn)不能達(dá)到面面俱到,很多內(nèi)容還未涉及到,或者限于篇幅和重點(diǎn)不能深入討論。它更多的是立足于如何以用好一套完善完整的性能工具為基礎(chǔ),構(gòu)建發(fā)現(xiàn)問(wèn)題-解決問(wèn)題-監(jiān)控問(wèn)題的優(yōu)化思維和優(yōu)化體系,使得性能優(yōu)化的工作事半功倍。更多的優(yōu)秀內(nèi)容,歡迎在UWA社區(qū)中進(jìn)行搜索。

      參考

      《Unity移動(dòng)端游戲性能優(yōu)化簡(jiǎn)譜》

      https://edu.uwa4d.com/lesson-detail/430

      本文內(nèi)容就介紹到這里啦,更多內(nèi)容可以前往UWA學(xué)堂進(jìn)行閱讀。

      特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。

      Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

      相關(guān)推薦
      熱點(diǎn)推薦
      《主角》爆火卻遭大量棄劇,觀眾理由出奇一致,一手好牌被打稀爛

      《主角》爆火卻遭大量棄劇,觀眾理由出奇一致,一手好牌被打稀爛

      嫹筆牂牂
      2026-05-13 07:10:16
      逆襲晉級(jí)!中國(guó)隊(duì)3-1挺進(jìn)U17亞洲杯8強(qiáng),日本全勝出線

      逆襲晉級(jí)!中國(guó)隊(duì)3-1挺進(jìn)U17亞洲杯8強(qiáng),日本全勝出線

      冷桂零落
      2026-05-13 10:31:16
      特朗普登機(jī)前,美國(guó)兩黨議員聯(lián)手,通告白宮,不許和中方達(dá)成協(xié)議

      特朗普登機(jī)前,美國(guó)兩黨議員聯(lián)手,通告白宮,不許和中方達(dá)成協(xié)議

      黑鷹觀軍事
      2026-05-13 20:09:42
      罰球41-21!2-1淘汰廣東!3人滿分1人嚴(yán)重拉胯 北京晉級(jí)還收2利好

      罰球41-21!2-1淘汰廣東!3人滿分1人嚴(yán)重拉胯 北京晉級(jí)還收2利好

      后仰大風(fēng)車
      2026-05-12 21:52:10
      國(guó)乒公布亞運(yùn)會(huì)選人方案,有八人已經(jīng)確定入選,樊振東不在其中

      國(guó)乒公布亞運(yùn)會(huì)選人方案,有八人已經(jīng)確定入選,樊振東不在其中

      寒士之言本尊
      2026-05-13 20:10:34
      河南將有中到大雨,局部暴雨!

      河南將有中到大雨,局部暴雨!

      大象新聞
      2026-05-13 18:50:39
      欠了快400億,罵了整十年,華西村硬是靠一筆意外投資活過(guò)來(lái)了

      欠了快400億,罵了整十年,華西村硬是靠一筆意外投資活過(guò)來(lái)了

      小莜讀史
      2026-05-07 19:10:59
      太猖狂!四川凌晨追打案再爆猛料,6人一鍋端,女子襲警細(xì)節(jié)曝光

      太猖狂!四川凌晨追打案再爆猛料,6人一鍋端,女子襲警細(xì)節(jié)曝光

      閱微札記
      2026-05-13 11:30:43
      官宣奇跡出現(xiàn)不足1個(gè)月,蔡磊最新?tīng)顟B(tài)曝光,他已提前規(guī)劃好退路

      官宣奇跡出現(xiàn)不足1個(gè)月,蔡磊最新?tīng)顟B(tài)曝光,他已提前規(guī)劃好退路

      觀史搜尋著
      2026-05-13 19:33:36
      終于瞞不住了!周迅王驍?shù)恼鎸?shí)關(guān)系曝光,與陳坤領(lǐng)證傳聞?wù)嫦啻蟀?>
    </a>
        <h3>
      <a href=街上的行人很刺眼
      2026-05-13 15:58:50
      郭大杰被免去廣東旅控集團(tuán)黨委書記、董事長(zhǎng)職務(wù)

      郭大杰被免去廣東旅控集團(tuán)黨委書記、董事長(zhǎng)職務(wù)

      經(jīng)理人雜志
      2026-05-13 10:09:37
      誰(shuí)都惹不起!滿載油輪穿行霍爾木茲,美伊全程隱忍不開火

      誰(shuí)都惹不起!滿載油輪穿行霍爾木茲,美伊全程隱忍不開火

      咣當(dāng)?shù)厍?/span>
      2026-05-13 17:32:36
      500噸物資已運(yùn)抵中國(guó)?白宮興奮宣布,特朗普或帶800多人赴華

      500噸物資已運(yùn)抵中國(guó)?白宮興奮宣布,特朗普或帶800多人赴華

      石江月
      2026-05-13 19:35:14
      伊朗:美方漫天要價(jià)不可接受,已準(zhǔn)備好應(yīng)對(duì)突發(fā)局勢(shì)

      伊朗:美方漫天要價(jià)不可接受,已準(zhǔn)備好應(yīng)對(duì)突發(fā)局勢(shì)

      澎湃新聞
      2026-05-13 18:49:06
      黃金一夜驚魂140美元!發(fā)生了什么?

      黃金一夜驚魂140美元!發(fā)生了什么?

      口袋貴金屬官方
      2026-05-13 17:41:32
      色情和毒品是兩大招牌,“傘”為其開綠燈,衡陽(yáng)天上人間覆滅記

      色情和毒品是兩大招牌,“傘”為其開綠燈,衡陽(yáng)天上人間覆滅記

      漢史趣聞
      2026-05-13 15:16:50
      互相取關(guān)!5年感情就這么結(jié)束了

      互相取關(guān)!5年感情就這么結(jié)束了

      柚子說(shuō)球
      2026-05-13 12:16:23
      當(dāng)伊朗亮出海底光纜底牌時(shí),全世界才發(fā)現(xiàn),中國(guó)藏了一手更絕的!

      當(dāng)伊朗亮出海底光纜底牌時(shí),全世界才發(fā)現(xiàn),中國(guó)藏了一手更絕的!

      獨(dú)坐山巔前
      2026-05-12 23:14:57
      陳寶國(guó)自曝:拍大宅門時(shí),何賽飛不問(wèn)青紅皂白,直接給我一嘴巴子

      陳寶國(guó)自曝:拍大宅門時(shí),何賽飛不問(wèn)青紅皂白,直接給我一嘴巴子

      她時(shí)尚丫
      2026-05-12 23:32:24
      謝暉現(xiàn)狀:重返上海申花,俄羅斯妻子風(fēng)韻猶存,兒女雙全財(cái)富自由

      謝暉現(xiàn)狀:重返上海申花,俄羅斯妻子風(fēng)韻猶存,兒女雙全財(cái)富自由

      梁岱愛(ài)玩車
      2026-05-03 18:54:17
      2026-05-13 20:52:49
      侑虎科技UWA incentive-icons
      侑虎科技UWA
      游戲/VR性能優(yōu)化平臺(tái)
      1575文章數(shù) 987關(guān)注度
      往期回顧 全部

      游戲要聞

      LPL第二賽段:EDG會(huì)打比賽?三局戰(zhàn)勝OMG

      頭條要聞

      美國(guó)總統(tǒng)時(shí)隔9年再次訪華 特朗普抵達(dá)北京

      頭條要聞

      美國(guó)總統(tǒng)時(shí)隔9年再次訪華 特朗普抵達(dá)北京

      體育要聞

      14年半,74萬(wàn),何冰嬌沒(méi)選那條更安穩(wěn)的路

      娛樂(lè)要聞

      白鹿掉20萬(wàn)粉,網(wǎng)友為李晨鳴不平

      財(cái)經(jīng)要聞

      美國(guó)總統(tǒng)特朗普抵達(dá)北京

      科技要聞

      騰訊一季度營(yíng)收1964.6億元 同比增9%

      汽車要聞

      C級(jí)純電轎跑 吉利銀河"TT"申報(bào)圖來(lái)了

      態(tài)度原創(chuàng)

      家居
      藝術(shù)
      時(shí)尚
      房產(chǎn)
      公開課

      家居要聞

      內(nèi)在自敘,無(wú)域有方

      藝術(shù)要聞

      乾隆 “翻車” 名畫刷屏!

      快來(lái)解鎖富家千金風(fēng)穿搭,穿舒適又時(shí)髦,一鍵拿捏優(yōu)雅氣質(zhì)

      房產(chǎn)要聞

      卷瘋了!最低殺到7字頭!手握30萬(wàn),海口樓市橫著走!

      公開課

      李玫瑾:為什么性格比能力更重要?

      無(wú)障礙瀏覽 進(jìn)入關(guān)懷版 主站蜘蛛池模板: 亚洲无码丝袜| 国产女同一区二区在线| 国产精品午夜福利合集| 成人av午夜在线观看| 原平市| 国产精一品亚洲二区在线播放| 宗合久久| 亚洲国产中文字幕在线视频综合| 日韩国产精品视频在放| 亚洲人成网线在线播放va| 狠狠v日韩v欧美v| 国产绿帽在线视频看| 熟妇人妻不卡中文字幕| 欧美成a人片在线观看| 天天躁日日躁欧美老妇app| 99精品国产一区二区三区| 午夜DY888国产精品影院| 色亚洲天堂| 国产欧美日韩视频怡春院| 国产桃色在线成免费视频| 老司机午夜精品视频资源| 国产欧美va欧美va香蕉在| 日本一区精品久久久久影院| 午夜激情福利| 丰满少妇被猛烈进入av久久| 亚洲精品999| 好湿好爽好大好黄欧美国产不卡| 中文无码乱人伦中文视频在线| 91欧美在线久久一区黄瓜| 九九热免费在线视频观看| 免费无码无遮挡裸体视频在线观看| 亚洲区成人综合一区二区| 久久精品国产久精国产一老狼| 久久人人玩人妻潮喷内射人人| 亚洲av中文一区二区| 亚洲精品乱码久久久久久蜜桃| jizz.jizz| .【乱子伦】国产精品www| 美女黄色网| 日韩成人电影一区| 亚洲国产精品毛片av不卡在线|