Skip to content

Ballistic simulations may be created too frequently #11599

Description

@xster

Make a normal fling gesture.
~50% of the time, many goBallistic calls are triggered when I would have expected just one.

In this example, it took 78ms cumulative recreating the simulations and causes frame drops.
cw5hukq7xsp

Call stack

#0      ScrollPositionWithSingleContext.goBallistic (package:flutter/src/widgets/scroll_position_with_single_context.dart:150:16)
#1      BallisticScrollActivity.applyNewDimensions (package:flutter/src/widgets/scroll_activity.dart:399:14)
#2      ScrollPosition.applyNewDimensions (package:flutter/src/widgets/scroll_position.dart:441:14)
#3      ScrollPositionWithSingleContext.applyNewDimensions (package:flutter/src/widgets/scroll_position_with_single_context.dart:110:29)
#4      ScrollPosition.applyContentDimensions (package:flutter/src/widgets/scroll_position.dart:411:7)
#5      RenderViewport.performLayout (package:flutter/src/rendering/viewport.dart:827:20)
#6      RenderObject._layoutWithoutResize (package:flutter/src/rendering/object.dart:1767:7)
#7      PipelineOwner.flushLayout (package:flutter/src/rendering/object.dart:1056:18)
#8      BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:251:19)
#9      BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:504:22)
#10     BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:189:5)
#11     BindingBase&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:695:15)
#12     BindingBase&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:643:9)
#13     _invoke (file:///Users/xster/development/flutter/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:86)
#14     _drawFrame (file:///Users/xster/development/flutter/bin/cache/pkg/sky_engine/lib/ui/hooks.dart:75)

Activity

  1. added
    c: performanceRelates to speed or footprint issues (see "perf:" labels)
    f: scrollingViewports, list views, slivers, etc.
    on Aug 12, 2017
  2. eseidelGoogle commented on Aug 12, 2017

    @eseidelGoogle
    Contributor

    Are these used on both iOS and Android or would this cause performance degradations specific to one or the other?

  3. Hixie commented on Aug 12, 2017

    @Hixie
    Contributor

    This happens if something within the list is changing dimensions (because we have to recompute the fling in case it would hit the edge). The question is, what is changing dimensions? And can we report it somehow (e.g. on the timeline) to make it obvious...

    This will depend on exactly what you're flinging.

  4. Hixie commented on Aug 12, 2017

    @Hixie
    Contributor

    The other thing is, goBallistic shouldn't be that expensive, yikes.

  5. Hixie commented on Aug 12, 2017

    @Hixie
    Contributor

    Looks from the timeline like maybe this is a long list with many items of various sizes so every time we render a new item, we change our estimate of the total list length, which would trigger this also.

  6. Hixie commented on Aug 15, 2017

    @Hixie
    Contributor

    Not sure what to do with this bug. Assuming I'm right about the cause, it's working as intended (modulo taking so long). Should we keep this open specifically to track down why it's so expensive?

  7. added this to the milestone on Aug 15, 2017
  8. self-assigned this
    on Aug 16, 2017
  9. xster commented on Aug 16, 2017

    @xster
    MemberAuthor

    Seems like it's mostly coming from recreating new AnimationControllers.

    Do you think it makes sense to let the position min/max extents be observables passed into the simulation instead of having them immutably baked in on construction?

    Or perhaps create new simulations but keep the old BallisticScrollActivity and AnimationController and just update the simulation? All the math in the simulation's constructor turned out to not be that expensive it seems.

  10. Hixie commented on Aug 16, 2017

    @Hixie
    Contributor

    We need to more precisely understand the cost. We could try doing a microbenchmark of just calling goBallistic in a tight loop and see what appears on the profile.

  11. added
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Jul 22, 2018
  12. knopp commented on Nov 26, 2018

    @knopp
    Member

    @xster, @Hixie, this is not just a performance problem. Calling goBallistic during scrolling means that the scrolling stops way sooner than it normally would. Also the momentum from multiple flings is not carried over.

    Look at example from #24715 or even Licenses screen from flutter gallery. It is pretty much impossible to scroll through all licenses on iPhone (cupertino mechanics seems to be much more affected by restarting simulation than mountain view). No matter the fling speed or number of flings, scrolling stops on next page.

    It seems wrong to me to recreate ballistic simulation on viewport size change then the extent is far from the final position of current simulation.

  13. removed their assignment
    on Nov 29, 2018
  14. knopp commented on Feb 5, 2019

    @knopp
    Member

    @xster, any chance of looking into this? We have long list of items with different heights and iOS scrolling is downright painful with all momentum lost severely impacting application usability.

  15. 13 remaining items

  16. github-actions commented on Sep 2, 2022

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  17. locked as resolved and limited conversation to collaborators on Sep 2, 2022
  18. Piinks commented on Sep 8, 2022

    @Piinks
    Contributor

    The PR that closed this is being reverted. Reopening.

  19. reopened this on Sep 8, 2022
  20. unlocked this conversation on Sep 8, 2022
  21. Piinks commented on Sep 8, 2022

    @Piinks
    Contributor

    For the next crack at solving this, this reproduction should be included as a test case: #110340

    Also, the latest attempt included creating and passing updated FixedScrollMetrics to createBallisticScrollAnimation. This was a breaking change for customers with their own custom scroll physics that expect a scroll position be provided to createBallisticScrollAnimation, not just ScrollMetrics. Either migrating the customer off of this currently safe assumption will be required, or a different approach that preserves that.

  22. removed their assignment
    on Sep 8, 2022
  23. added
    P2Important issues not at the top of the work list
    and removed
    P1High-priority issues at the top of the work list
    on Sep 8, 2022
  24. knopp commented on Sep 17, 2022

    @knopp
    Member

    Sad to see this reverted :-/ There was however one more issue in the last attempt (fixed by revert):
    Scroll offset correction (ScrollPosition.correctBy) was getting overridden by the BallisticScrollActivity animator.

    I had a local workaround and was going to report this:

    class CorrectingScrollPositionWithSingleContext
        extends ScrollPositionWithSingleContext {
      CorrectingScrollPositionWithSingleContext({
        required super.physics,
        required super.context,
        super.initialPixels = 0.0,
        super.keepScrollOffset,
        super.oldPosition,
        super.debugLabel,
      });
    
      @override
      Simulation? updateBallisticAnimation(
          double initVelocity, double initPosition) {
        return super
            .updateBallisticAnimation(initVelocity, initPosition + _correction);
      }
    
      double _correction = 0;
    
      @override
      void beginActivity(ScrollActivity? newActivity) {
        _correction = 0;
        super.beginActivity(newActivity);
      }
    
      @override
      void correctBy(double correction) {
        _correction += correction;
        super.correctBy(correction);
      }
    }
  25. Piinks commented on Sep 19, 2022

    @Piinks
    Contributor

    Thank you for providing another test case @knopp!

  26. Piinks commented on Nov 4, 2022

    @Piinks
    Contributor

    Another test case for when we revisit this: #114543

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: performanceRelates to speed or footprint issues (see "perf:" labels)f: scrollingViewports, list views, slivers, etc.frameworkflutter/packages/flutter repository. See also f: labels.team-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions