huge_listview icon indicating copy to clipboard operation
huge_listview copied to clipboard

Deferred loading not working as expected

Open vishnukvmd opened this issue 3 years ago • 3 comments

Hey again @deakjahn !

While running some tests I realized that _MaxVelocityPhysics.recommendDeferredLoading is never being called, making the list view render all the items during a fast-scroll.

You can verify this by adding a log-line within recommendDeferredLoading.

Do you have any ideas on how we could make sure that the optimizations you've added in here itemBuilder performs as expected?

Thanks again!

vishnukvmd avatar Apr 25 '21 16:04 vishnukvmd

I dug in a little more, here are some findings:

Scrollable.recommendDeferredLoadingForContext is not running its checks against _MaxVelocityPhysics.

We must instead run it against the scrollController.position within the primary and secondary controllers within ScrollablePositionedList.

What we can do is pass a scrollablePositionedListKey of type GlobalKey<ScrollablePositionedListState> to the ScrollablePositionedList to get access to these two controllers.

Then the itemBuilder can call the following function to find out whether it should defer the item rendering or not.

bool shouldDefer(context) {
  bool shouldDefer = false;
  try {
    final primaryPosition = scrollablePositionedListKey
        .currentState.primary.scrollController.position;
    shouldDefer = primaryPosition.recommendDeferredLoading(context);
  } catch (e) {
    // Preventing errors due to a detached controller
  }
  if (!shouldDefer) {
    try {
      final secondaryPosition = scrollablePositionedListKey
          .currentState.secondary.scrollController.position;
      shouldDefer =
          secondaryPosition.recommendDeferredLoading(context);
    } catch (e) {
      // Preventing errors due to a detached controller
    }
  }
  return shouldDefer;
}

vishnukvmd avatar Apr 26 '21 06:04 vishnukvmd

That said, the unfortunate bit about this optimization is that for drags the velocity is computed to be 0. So when a user drags through the scroll view over a large distance, no rendering is deferred and all items are rendered. 😞

If you have any workarounds, please do let me know. I'll update this issue if I find something.

vishnukvmd avatar Apr 26 '21 06:04 vishnukvmd

I have to confess that most of that code, including this deferred loading, came from the original SO article and I never really experimented with it. I just assumed it works. :-)

deakjahn avatar Apr 26 '21 08:04 deakjahn