One frame visual delay when populating ListView via ViewModel binding

I’m using the UMG Viewmodel plugin to bind a list of items from a ViewModel to a ListView Widget. The ListView uses an Entry ViewModel for each item, and then Entry Widget has bindings to that for setting the visual content. I’ve been running into the issue that when a new Entry is added, there’s a one-frame delay before the item updates its visuals to match its ViewModel bindings. It’s most apparent at lower frame rates.

From the attached sample:

Frame X

[Image Removed]

Frame X+1

[Image Removed]

I dug around the codebase and it looks like the bindings are applied at the end of the frame via the FTSTicker::GetCoreTicker callback, when UListViewBase::HandleAnnounceGeneratedEntries is run. I’m guessing this runs after the Widget has been queued up for rendering, so if the render thread makes it to screen first it will show the not yet up to date Widget.

As a workaround I’m setting the ListView Entry Visibility to Hidden by default, and then once the bindings kick in it sets to to Visible. But this is tedious to do for every ListView in our UI that we’re using ViewModel bindings for. Is there a better way to do this - or am I going about this the wrong way?

Thanks!

Steps to Reproduce

  1. Hit play to start PIE
  2. Set the max FPS to something low <30 FPS via the `t.MaxFPS 30` console command
  3. Click “Add Entry” and observe that the ListView item briefly shows the text `[Text Block]` (the default text for the widget).
  4. Click “Remove Entry” and “Add Entry” again to observe that the ListView item briefly shows the previous value before changing to the new one.

Hi,

Sorry for the delay responding. I’m seeing the same with your test project, though it’s a bit sporadic on when the stale data shows up. That seems in line with your thought that it may be based on timing of the render thread. We may be able to add a new event to ListViews that occurs without the frame delay so that the view binding can run between the entry being created and it being displayed, though that would require some more investigation on our side. In the meantime, it does look like OnListItemObjectSet runs earlier, so that may be a good spot to do some preprocessing before the binding can run. Something like this in the List Item widget should guarantee it doesn’t show up until a frame has passed and the binding has had a moment to run:

[Image Removed]To avoid redundant work, you could make a ListItem base widget class that implements this, then derive your other list items off of that base.

Best,

Cody

Hi Cody,

Thanks for taking a look and confirming what I was seeing. I’ll take your advice and implement a base class to work around this.

Max