Skip to content

[WEB] frameData.frameNumber from PlatformDispatcher always returns -1 on the web #170972

@itspectre

Description

@itspectre

Steps to reproduce

Use the code below or try dartpad:
https://dartpad.dev/?id=06c010125e651e2bfadeecbff2db181a
I tested it on the main branch and on the stable one.

Expected results

PlatformDispatcher.instance.frameData.frameNumber should return actual frame number on the Web, just like on other platforms.

Actual results

On the web PlatformDispatcher.instance.frameData.frameNumber returns always -1.
I have tested the code below on the desktop (Windows) and it returns the correct ascending frame numbers. But on the web (via flutter run -d chrome or dartpad) this method always returns -1.
I also found two strange behaviors (potential bugs?).

  1. frameNumber has the old value until the end of the transientCallbacks phase. If this is not a bug, it should be documented. The picture below shows a different number in different callbacks during a frame. (underlined in blue)
  2. scheduleMicrotask method calls its callback after the frame ends on the web, and not between onBeginFrame and onDrawFrame as expected (underlined in red). On the desktop (Windows) it works correctly.

Code sample

Code sample
import 'dart:async';
import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart' show SchedulerBinding, Ticker;

void main() {
  WidgetsFlutterBinding.ensureInitialized();

  // ignore: invalid_use_of_protected_member
  SchedulerBinding.instance.ensureFrameCallbacksRegistered();

  final onBeginFrame = PlatformDispatcher.instance.onBeginFrame;
  final onDrawFrame = PlatformDispatcher.instance.onDrawFrame;

  PlatformDispatcher.instance.onBeginFrame = (Duration elapsed) {
    print('+' * 30);
    final frameNumber = PlatformDispatcher.instance.frameData.frameNumber;
    print('frameNumber from onBeginFrame callback: $frameNumber');
    onBeginFrame!(elapsed);
    print('___finish onBeginFrame');
  };

  PlatformDispatcher.instance.onDrawFrame = () {
    print('___start onDrawFrame');
    onDrawFrame!();
    final frameNumber = PlatformDispatcher.instance.frameData.frameNumber;
    print('frameNumber from onDrawFrame callback: $frameNumber');
    print('-' * 30);
  };

  runApp(const App());
}

class App extends StatelessWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(debugShowCheckedModeBanner: false, home: Home());
  }
}

class Home extends StatefulWidget {
  const Home({super.key});

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> with TickerProviderStateMixin {
  Ticker? ticker;

  @override
  void initState() {
    super.initState();

    SchedulerBinding.instance.addPersistentFrameCallback((_) {
      final frameNumber = PlatformDispatcher.instance.frameData.frameNumber;
      print('frameNumber from the persistent callback: $frameNumber');
    });

    ticker = createTicker((_) {
      final frameNumber = PlatformDispatcher.instance.frameData.frameNumber;
      print('frameNumber from the transient callback: $frameNumber');
      scheduleMicrotask(() {
        final frameNumber = PlatformDispatcher.instance.frameData.frameNumber;
        print('frameNumber from the microtask callback: $frameNumber');
      });
      SchedulerBinding.instance.addPostFrameCallback((_) {
        final frameNumber = PlatformDispatcher.instance.frameData.frameNumber;
        print('frameNumber from the postframe callback: $frameNumber');
      });
    })..start();

    Timer(const Duration(seconds: 1), () {
      ticker?.dispose();
      ticker = null;
    });
  }

  @override
  void dispose() {
    ticker?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}

Screenshots or Video

Screenshots / Video demonstration

On the desktop:
Image

On the web:
Image

Logs

Flutter Doctor output

Doctor output
[√] Flutter (Channel main, 3.33.0-1.0.pre.619, on Microsoft Windows [Version 10.0.19045.5965], locale ru-RU)
[√] Windows Version (Њ ©Єа®б®дв Windows 10 Pro 64-а §ап¤­ п, 22H2, 2009)
[√] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
[√] Chrome - develop for the web
[√] Visual Studio - develop Windows apps (Visual Studio Build Tools 2022 17.6.5)
[√] Android Studio (version 2022.2)
[√] VS Code (version 1.101.1)
[√] Connected device (4 available)
[√] Network resources

• No issues found!

Metadata

Metadata

Assignees

Labels

P2Important issues not at the top of the work listengineflutter/engine related. See also e: labels.found in release: 3.32Found to occur in 3.32found in release: 3.33Found to occur in 3.33frameworkflutter/packages/flutter repository. See also f: labels.good first issueRelatively approachable for first-time contributorshas reproducible stepsThe issue has been confirmed reproducible and is ready to work onplatform-webWeb applications specificallyr: fixedIssue is closed as already fixed in a newer versionteam-webOwned by Web platform teamtriaged-webTriaged by Web platform team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions