From 78c0fe65546ad4a4a1c1537dee1c22946cbe200a Mon Sep 17 00:00:00 2001 From: Lukas Klingsbo Date: Wed, 5 Aug 2026 18:31:30 +0200 Subject: [PATCH] perf: Make render contexts and debug caches lazily allocated --- .../lib/src/components/core/component.dart | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/flame/lib/src/components/core/component.dart b/packages/flame/lib/src/components/core/component.dart index c8198d496d5..7d9e8ecdc48 100644 --- a/packages/flame/lib/src/components/core/component.dart +++ b/packages/flame/lib/src/components/core/component.dart @@ -587,19 +587,16 @@ class Component { /// cleans them up afterwards. @protected void renderChild(Canvas canvas, Component child) { - int? originalLength; - final hasContext = _renderContexts.isNotEmpty; - if (hasContext) { - originalLength = child._renderContexts.length; - child._renderContexts.addAll(_renderContexts); + final contexts = _renderContexts; + if (contexts == null || contexts.isEmpty) { + child.renderTree(canvas); + return; } + final childContexts = child._renderContexts ??= []; + final originalLength = childContexts.length; + childContexts.addAll(contexts); child.renderTree(canvas); - if (hasContext) { - child._renderContexts.removeRange( - originalLength!, - child._renderContexts.length, - ); - } + childContexts.removeRange(originalLength, childContexts.length); } /// Called once after all children have been rendered in [renderTree]. @@ -612,7 +609,7 @@ class Component { void renderTree(Canvas canvas) { final context = renderContext; if (context != null) { - _renderContexts.add(context); + (_renderContexts ??= []).add(context); } render(canvas); @@ -630,7 +627,7 @@ class Component { } if (context != null) { - _renderContexts.removeLast(); + _renderContexts!.removeLast(); } } @@ -1153,14 +1150,16 @@ class Component { //#region Context - final QueueList _renderContexts = QueueList(); + /// The stack of render contexts inherited from ancestors during the render + /// pass. Created lazily: most components never provide or receive one. + List? _renderContexts; /// Override this method if you want your component to provide a custom /// render context to all its children (recursively). ComponentRenderContext? get renderContext => null; T? findRenderContext() { - return _renderContexts.whereType().lastOrNull; + return _renderContexts?.whereType().lastOrNull; } //#endregion @@ -1191,8 +1190,9 @@ class Component { /// The color that the debug output should be rendered with. Color debugColor = const Color(0xFFFF00FF); - final ValueCache _debugPaintCache = ValueCache(); - final ValueCache _debugTextPaintCache = ValueCache(); + late final ValueCache _debugPaintCache = ValueCache(); + late final ValueCache _debugTextPaintCache = + ValueCache(); /// The [debugColor] represented as a [Paint] object. Paint get debugPaint {