Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListView has one frame jank when releasing finger (PointerUpEvent), no matter how lightweight the content is #113494

Open
fzyzcjy opened this issue Oct 16, 2022 · 4 comments
Labels
f: scrolling Viewports, list views, slivers, etc. found in release: 3.3 Found to occur in 3.3 found in release: 3.5 Found to occur in 3.5 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P2 Important issues not at the top of the work list team-framework Owned by Framework team triaged-framework Triaged by Framework team

Comments

@fzyzcjy
Copy link
Contributor

fzyzcjy commented Oct 16, 2022

Consider a classical Flutter case with very light workload. Suppose vsync happens at 0ms, 16.67ms, 33.33ms, etc, and suppose PointerUpEvent is handled at 15ms (i.e. the after-draw-frame period). Then, at 15ms, Flutter calls goBallistic with current offset and velocity. Next, during the 16.67-33.33ms frame, Flutter's ballistic scroll activity handles the first tick (i.e. with elapsed being zero), so it outputs a offset identical to the last pointer offset. Because of this, the output from 16.67-33.33ms frame will has the same offset as that from 0-16.67ms.

Reproducible sample:

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets('ListView jank', (tester) async {
    await tester.pumpWidget(MaterialApp(
      home: Scaffold(
        body: ListView(
          children: [
            for (var i = 0; i < 10; ++i) Container(height: 300),
          ],
        ),
      ),
    ));
    final state = tester.state<ScrollableState>(find.byType(Scrollable));

    double? lastPosition;
    void checkPositionChanged() {
      final currPosition = state.position.pixels;
      expect(currPosition, isNot(lastPosition));
      lastPosition = currPosition;
    }

    checkPositionChanged();

    final gesture =
        await tester.startGesture(tester.getCenter(find.byType(Scrollable)));
    for (var i = 0; i < 30; ++i) {
      await gesture.moveBy(const Offset(0, -5));
      await tester.pump();
      checkPositionChanged();
    }
   
    await gesture.up();
    await tester.pump();
    checkPositionChanged();
  });
}

Output

/Volumes/MyExternal/ExternalRefCode/flutter/bin/flutter --no-color test --machine --start-paused --local-engine-src-path=/Volumes/MyExternal/ExternalRefCode/engine/src --local-engine=host_debug_unopt test/hi.dart
Testing started at 14:37 ...

══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: not <150.0>
  Actual: <150.0>

When the exception was thrown, this was the stack:
#4      main.<anonymous closure>.checkPositionChanged (file:///Users/tom/RefCode/flutter_smooth/packages/smooth/test/hi.dart:20:7)
#5      main.<anonymous closure> (file:///Users/tom/RefCode/flutter_smooth/packages/smooth/test/hi.dart:36:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

This was caught by the test expectation on the following line:
  file:///Users/tom/RefCode/flutter_smooth/packages/smooth/test/hi.dart line 20
The test description was:
  ListView jank
════════════════════════════════════════════════════════════════════════════════════════════════════

Test failed. See exception logs above.
The test description was: ListView jank
@danagbemava-nc danagbemava-nc added the in triage Presently being triaged by the triage team label Oct 17, 2022
@danagbemava-nc
Copy link
Member

Reproducible using the code sample provided above.

Labeling for further investigation from the team.

logs
══╡ EXCEPTION CAUGHT BY FLUTTER TEST FRAMEWORK ╞════════════════════════════════════════════════════
The following TestFailure was thrown running a test:
Expected: not <150.0>
  Actual: <150.0>

When the exception was thrown, this was the stack:
#4      main.<anonymous closure>.checkPositionChanged (file:///Users/nexus/projects/nevercode/hs/test/widget_test.dart:20:7)
#5      main.<anonymous closure> (file:///Users/nexus/projects/nevercode/hs/test/widget_test.dart:36:5)
<asynchronous suspension>
<asynchronous suspension>
(elided one frame from package:stack_trace)

This was caught by the test expectation on the following line:
  file:///Users/nexus/projects/nevercode/hs/test/widget_test.dart line 20
The test description was:
  ListView jank
════════════════════════════════════════════════════════════════════════════════════════════════════
Test failed. See exception logs above.
The test description was: ListView jank


✖ ListView jank

Exited (1).
flutter doctor -v
[✓] Flutter (Channel stable, 3.3.4, on macOS 12.6 21G115 darwin-arm, locale en-GB)
    • Flutter version 3.3.4 on channel stable at /Users/nexus/dev/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision eb6d86ee27 (12 days ago), 2022-10-04 22:31:45 -0700
    • Engine revision c08d7d5efc
    • Dart version 2.18.2
    • DevTools version 2.15.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.0)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14A309
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[!] Android Studio
    • Android Studio at /Applications/Android Studio Preview 2.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9014738/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[!] Android Studio
    • Android Studio at /Users/nexus/Downloads/Android Studio Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] VS Code (version 1.72.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.50.0

[✓] Connected device (3 available)
    • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64  • Android 13 (API 33) (emulator)
    • macOS (desktop)             • macos         • darwin-arm64   • macOS 12.6 21G115 darwin-arm
    • Chrome (web)                • chrome        • web-javascript • Google Chrome 106.0.5249.119

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 2 categories.
[✓] Flutter (Channel master, 3.5.0-6.0.pre.49, on macOS 12.6 21G115 darwin-arm64, locale en-GB)
    • Flutter version 3.5.0-6.0.pre.49 on channel master at /Users/nexus/dev/sdks/flutters
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 1e4d56ec7a (4 hours ago), 2022-10-17 01:58:03 -0400
    • Engine revision f6aef9b30f
    • Dart version 2.19.0 (build 2.19.0-312.0.dev)
    • DevTools version 2.18.0

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /Users/nexus/Library/Android/sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.0)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14A309
    • CocoaPods version 1.11.3

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2021.3)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[!] Android Studio
    • Android Studio at /Applications/Android Studio Preview 2.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[✓] Android Studio (version 2021.3)
    • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9014738/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[!] Android Studio
    • Android Studio at /Users/nexus/Downloads/Android Studio Preview.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    ✗ Unable to find bundled Java version.
    • Try updating or re-installing Android Studio.

[✓] VS Code (version 1.72.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.50.0

[✓] Connected device (3 available)
    • sdk gphone64 arm64 (mobile) • emulator-5554 • android-arm64  • Android 13 (API 33) (emulator)
    • macOS (desktop)             • macos         • darwin-arm64   • macOS 12.6 21G115 darwin-arm64
    • Chrome (web)                • chrome        • web-javascript • Google Chrome 106.0.5249.119

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 2 categories.

@danagbemava-nc danagbemava-nc added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. has reproducible steps The issue has been confirmed reproducible and is ready to work on found in release: 3.3 Found to occur in 3.3 found in release: 3.5 Found to occur in 3.5 and removed in triage Presently being triaged by the triage team labels Oct 17, 2022
@xu-baolin xu-baolin self-assigned this Oct 20, 2022
@xu-baolin
Copy link
Member

Interestingly, if the animation starts during SchedulerPhase.idle(such as pointer event dispatching), the animation will start with a delay of one frame because it is processed as follows,

if (SchedulerBinding.instance.schedulerPhase.index > SchedulerPhase.idle.index &&
SchedulerBinding.instance.schedulerPhase.index < SchedulerPhase.postFrameCallbacks.index) {
_startTime = SchedulerBinding.instance.currentFrameTimeStamp;
}

@goderbauer @Hixie @gspencergoog Do you have any ideas?

@fzyzcjy
Copy link
Contributor Author

fzyzcjy commented Oct 20, 2022

@xu-baolin That 'if' IMHO is because currentFrameTimeStamp is explicitly reset to null during idle period. If that is necessary, maybe we can create something like previousFrameTimeStamp which is non-null during idle, so that ticker can utilize it?

@xu-baolin
Copy link
Member

The impact of this issue may need to be assessed. Fixing this is bound to break a lot of test cases.

@goderbauer goderbauer added the P2 Important issues not at the top of the work list label Oct 25, 2022
@xu-baolin xu-baolin removed their assignment Nov 4, 2022
@flutter-triage-bot flutter-triage-bot bot added team-framework Owned by Framework team triaged-framework Triaged by Framework team labels Jul 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
f: scrolling Viewports, list views, slivers, etc. found in release: 3.3 Found to occur in 3.3 found in release: 3.5 Found to occur in 3.5 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on P2 Important issues not at the top of the work list team-framework Owned by Framework team triaged-framework Triaged by Framework team
Projects
None yet
Development

No branches or pull requests

4 participants