Flutter Performance Issue/Jank with video_player in PageView

1.1k Views Asked by At

I've been struggling with severe janks with the "official" flutter video_player package in combination with the PageView widget.

My Goal

Scroll smoothly and quickly through several pages of a PageView widget, that contain a Video widget each.

Actual Result

When I try to scroll through those pages quickly, I get terrible janks/performance issues. When I swipe through the pages slowly, and wait for the scrolling animation to finish, everything is smooth. See my video recorded on a Xiaomi Redmi Note 8 Pro in profile mode as proof.

GIF: video proof of the janks in the app

Performance Analysis

I tried finding help by consulting flutter performance tool. The tool shows massive spikes in raster time. In one example 51.7 ms raster time, 43.0 ms of that time needed for shader compilation. I'm not experienced enough to understand what that means or how that information helps me, though. Screenshot follows:

screenshot: flutter performance tool screenshot showing slow frame

What I tried so far

  1. Removing the line controller.dispose(); resolves the issue, but that leeds to memory leaks and the widgets crashing eventually.
  2. I tried wrapping the controller.dispose(); into a WidgetsBinding.instance!.addPostFrameCallback((_) async {}, but that didn't help

My Code

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

class ExamplePageView extends StatelessWidget {
  ExamplePageView({Key? key}) : super(key: key);

  final PageController pageController = PageController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: MediaQuery.of(context).size.height,
        child: PageView(
          controller: pageController,
          onPageChanged: (value) {},
          children: [
            ExampleVideo(),
            ExampleVideo(),
            ExampleVideo(),
            ExampleVideo(),
            ExampleVideo(),
            ExampleVideo(),
          ],
        ),
      ),
    );
  }
}

class ExampleVideo extends StatefulWidget {
  const ExampleVideo({Key? key}) : super(key: key);

  @override
  State<ExampleVideo> createState() => _ExampleVideoState();
}

class _ExampleVideoState extends State<ExampleVideo> {
  late VideoPlayerController controller;

  @override
  void initState() {
    super.initState();
    controller = VideoPlayerController.network(
        "https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4");
    controller
      ..initialize()
      ..addListener(() {
        setState(() {});
      });
  }

  @override
  Widget build(BuildContext context) {
    return Align(
      alignment: Alignment.center,
      child: Container(
        constraints: BoxConstraints(
          maxHeight: MediaQuery.of(context).size.height,
        ),
        child: AspectRatio(
          aspectRatio: 16 / 9,
          child: controller.value.isInitialized
              ? VideoPlayer(controller)
              : Container(
                  color: Colors.black,
                ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

Flutter Doctor shows no issues, video_player and flutter are in their respective latest version. Thank you for helping! :)

Also posted on flutter's github

1

There are 1 best solutions below

0
On

dig through this package which works pretty much flawlessly. you may find your answer

https://pub.dev/packages/advstory