AgentSkillsCN

canvas-performance

针对 UGUI Canvas 和 UI Toolkit 运行时,提供高效的 UI 性能优化方案。

SKILL.md
--- frontmatter
name: canvas-performance
description: "UI performance optimization for both UGUI Canvas and UI Toolkit runtime."
version: 1.0.0
tags: ["UI", "performance", "optimization", "Canvas", "batching"]
argument-hint: "target='Canvas' OR optimization='batching' profiler='true'"
disable-model-invocation: false
user-invocable: true
allowed-tools:
  - run_command
  - list_dir
  - write_to_file

UI Performance Optimization

Overview

UI performance optimization techniques for Unity Canvas (UGUI) and UI Toolkit. Covers batching, dirty flagging, pooling, and profiling strategies.

When to Use

  • Use when UI causes frame drops
  • Use when optimizing mobile UI
  • Use when dealing with dynamic content
  • Use when profiling identifies UI issues
  • Use when building complex interfaces

Performance Comparison

AspectUGUIUI Toolkit
Batch breakingCommon issueLess prone
Dirty rebindingCanvas rebuildElement repaint
Object overheadGameObject per elementNo GameObjects
MemoryHigherLower

UGUI Canvas Optimization

code
┌─────────────────────────────────────────────────────────────┐
│                   CANVAS HIERARCHY                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  BAD (Single Canvas)          GOOD (Split Canvases)        │
│  ┌──────────────────┐        ┌──────────────────┐          │
│  │ Canvas           │        │ Canvas (Static)  │          │
│  │  ├─ HUD          │        │  ├─ Background   │          │
│  │  ├─ Health Bar ⚡ │        │  └─ Title        │          │
│  │  ├─ Score      ⚡ │        ├──────────────────┤          │
│  │  ├─ Minimap    ⚡ │        │ Canvas (Dynamic) │          │
│  │  └─ Background   │        │  ├─ Health Bar   │          │
│  └──────────────────┘        │  └─ Score        │          │
│                               └──────────────────┘          │
│  ⚡ = Frequent updates cause full rebuild                   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Key Optimizations

OptimizationImpactTechnique
Split canvasesHighSeparate dynamic/static
Disable Raycast TargetMediumUncheck on non-interactive
Object poolingHighReuse list items
Disable invisibleMediumgameObject.SetActive(false)
Avoid layout groupsMediumUse anchors when possible
Cache referencesMediumDon't use GetComponent

UI Toolkit Optimizations

OptimizationTechnique
Avoid style changesUse USS classes
Query onceCache Q<> results
Virtual listsListView with virtualization
Avoid generateVisualContentUse built-in elements
Reduce hierarchyFlatten when possible

Best Practices

  • ✅ Split dynamic and static into separate canvases
  • ✅ Disable Raycast Target on decorative elements
  • ✅ Use object pooling for dynamic lists
  • ✅ Profile with UI Profiler module
  • ✅ Use UI Toolkit for complex hierarchies
  • NEVER animate layout properties
  • NEVER use GetComponent in Update
  • NEVER enable Raycast on all elements

Few-Shot Examples

Example 1: Canvas Splitter

User: "Optimize my HUD canvas."

Agent:

code
Recommended structure:
1. Canvas_Background (Static)
   - Overlay layer 0
   - Background images, frames
   
2. Canvas_HUD_Dynamic (Nested)
   - Health bar, stamina, score
   - Updates frequently
   
3. Canvas_Minimap (Separate)
   - Render Texture display
   - Updates at lower frequency
   
4. Canvas_Popup (Overlay)
   - Dialogs, notifications
   - Only visible when needed

Example 2: Raycast Optimizer

User: "Fix raycast performance."

Agent:

csharp
#if UNITY_EDITOR
[MenuItem("Tools/UI/Optimize Raycasts")]
public static void OptimizeRaycasts()
{
    var graphics = FindObjectsOfType<Graphic>();
    int count = 0;
    
    foreach (var g in graphics)
    {
        // Disable raycast on non-Button, non-Toggle elements
        if (g.GetComponent<Selectable>() == null)
        {
            g.raycastTarget = false;
            count++;
        }
    }
    
    Debug.Log($"Disabled raycast on {count} elements");
}
#endif

Example 3: UI Toolkit Pooled List

User: "Efficient scrolling list."

Agent:

csharp
// UI Toolkit ListView with virtualization (built-in)
var listView = new ListView(
    itemsSource: _items,
    itemHeight: 50,
    makeItem: () => new ItemView(),
    bindItem: (element, index) => 
    {
        var view = (ItemView)element;
        view.Bind(_items[index]);
    }
);

// Virtualization is automatic - only visible items are created
listView.virtualizationMethod = CollectionVirtualizationMethod.FixedHeight;

Profiling Tips

  • Use UI Profiler module
  • Check Canvas.BuildBatch time
  • Watch for Layout spikes
  • Monitor Fill rate on mobile
  • Use Frame Debugger for batches

Related Skills

  • @ui-toolkit-modern - Modern UI approach
  • @responsive-ui-design - Layout optimization
  • @object-pooling - Pool patterns