Invalidation Box

An overview of Invalidation Box, which helps developers optimize UI Widgets.

Choose your operating system:




Prerequisite Topics

In order to understand and use the content on this page, make sure you are familiar with the following topics:


Widgets that are wrapped with an Invalidation Box allows the child widget geometry to be cached to speed up Slate rendering. Any widgets that are cached by an Invalidation Box are not pre-passed, ticked, or painted. In general, if you are looking to optimize your project, wrapping certain widgets with Invalidation Boxes may boost your performance (particularly for mobile projects or complicated UI displays). For widgets that do not change constantly, they can be placed inside an Invalidation Box and cached instead of considered during paint, tick, or prepass.

If the widget changes, however, it will become invalid and you will need to manually invalidate the cache which will throw it away essentially and force it to redraw on the next paint pass. Anything that changes the visual appearance of the widget requires it to be invalidated. The only exception to this is a change to the appearance that is not stored in the vertex buffer for those widgets (for example Materials, as changing a Material Parameter does not require invalidating the widget).


In the Details panel for a placed Invalidation Box , there are a couple of specific options that can be set that pertain to the widget:




Cache Relative Transforms

Caches the locations for child draw elements relative to the invalidation box which adds extra overhead to drawing them every frame. However, in cases where the position of the invalidation boxes changes every frame, this can be a big saving.

Is Volatile

If true, prevents the widget or its child's geometry or layout information from being cached. If this widget changes every frame, but you want it to still be in an invalidation panel, you should make it as volatile instead of invalidating it every frame, which would prevent the invalidation panel from actually ever caching anything.

Regarding the Is Volatile check box, any widget can be set to be volatile. Volatile widgets act like normal Slate widgets pre-invalidation. They're redrawn every frame, including all their children. When combined with the invalidation panel, it allows you to care only about redrawing the most dynamic bits of the UI, as invalidating a whole panel could be far more costly.


When using an Invalidation Box , it is up to the user to call Invalidate through C++ or the Invalidate Layout And Volatility node (pictured below) on a child widget to force invalidation.


Currently, some core widgets do this automatically when certain properties are changed, however more will do it over time.


You can debug your Invalidation Boxes using the Widget Reflector (CTRL+Shift+W) and clicking the Invalidation Debugging toggle.

SlateDebugger.Invalidate.Enable 1 is invoked, use SlateDebugger.Invalidate.ToggleLegend

Click image for full view.

With the Widget Reflector up and Invalidation Debugging on, you will see the following colors:




Paint invalidated this frame.


Volatility invalidated this frame.


ChildOrder invalidated this frame.


RenderTransform invalidated this frame.


Visibility invalidated this frame.


Layout invalidated this frame for Invalidation Box.


Every widget was reordered.


Fully re-updated.



Above we have an image that is marked as volatile inside of a Border which is wrapped with an Invalidation Box. Since the image is marked as volatile, it can be updated dynamically during gameplay while the Border (or any other art assets that we wanted to appear around the image that do not change) is cached.

Help shape the future of Unreal Engine documentation! Tell us how we're doing so we can serve you better.
Take our survey