PageView 中 video_player 的 Flutter 性能问题/卡顿

Fly*_*zzy 7 performance flutter jank flutter-pageview flutter-video-player

我一直在与“官方”flutter video_player包与 PageView 小部件结合使用时遇到严重的卡顿问题。

我的目标

平滑快速地滚动浏览PageView 小部件的多个页面,每个页面都包含一个视频小部件。

实际结果

当我尝试快速滚动这些页面时,我遇到了严重的卡顿/性能问题。当我缓慢地滑动页面并等待滚动动画完成时,一切都很顺利。请参阅我在小米红米 Note 8 Pro 的个人资料模式下录制的视频作为证据。

GIF:应用程序卡顿的视频证明

绩效分析

我尝试通过咨询颤振性能工具来寻求帮助。该工具显示光栅时间出现大量峰值。在一个示例中,光栅时间为 51.7 毫秒,其中 43.0 毫秒用于着色器编译。不过,我的经验不足,无法理解这意味着什么或这些信息如何帮助我。截图如下:

屏幕截图:显示慢帧的 flutter 性能工具屏幕截图

到目前为止我尝试过的

  1. 删除该行controller.dispose();可以解决问题,但这会导致内存泄漏和小部件最终崩溃。
  2. 我尝试将其包装controller.dispose();成 a WidgetsBinding.instance!.addPostFrameCallback((_) async {},但这没有帮助

我的代码

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();
  }
}

Run Code Online (Sandbox Code Playgroud)

Flutter Doctor 显示没有任何问题,video_player 和 flutter 都是各自的最新版本。感谢您的帮助!:)

也发布在flutter的github上

use*_*575 0

深入研究这个包,它的工作原理几乎完美无缺。你可能会找到你的答案

https://pub.dev/packages/advstory