Skip to content

[web] ImageDecoder should be more memory-efficient #96145

@yjbanov

Description

@yjbanov

Branching off the memory efficiency issue from #94500. While the leak associated with the Codec objects has been fixed, ImageDecoder still uses a lot more memory when decoding multiple animated images simultaneously (i.e. all codecs are live by design and there are no objects to reclaim) compared to plain <img> tags or WASM codecs used by CanvasKit. For example, the WASM codec never grows past 150MB, while ImageDecoder can easily grow to 600-700MB when stressed.

This may require a fix in Chromium (plain JS repro, see also #94500 (comment)).

Repro using Flutter:

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Animated image stress test',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

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

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    const List<String> urls = <String>[
      'https://media4.giphy.com/media/Ve1cBYXUmh6iyuYSnF/giphy.webp',
      'https://media3.giphy.com/media/fZ31GBoN4EOUb83rIt/giphy.webp',
      'https://media4.giphy.com/media/wP4T2q2sb9vqgz4GZ1/giphy.webp',
      'https://media1.giphy.com/media/RgGfMHu2HLKLwGeGFb/giphy.webp',
      'https://media0.giphy.com/media/3o7TKtpfZ3e8rwww7K/giphy.webp',
      'https://media1.giphy.com/media/4nKnhZsY9mNX9n928r/giphy.webp',
      'https://media4.giphy.com/media/8Rqk3cKgw799pM8U1a/giphy.webp',
      'https://media3.giphy.com/media/3ov9jSfDqguXOoLfhu/giphy.webp',
      'https://media4.giphy.com/media/yh4Q1Hft8zzUgzOybI/giphy.webp',
      'https://media4.giphy.com/media/SF9v8zMYhyvLn9GTTH/giphy.webp',
      'https://media0.giphy.com/media/BwPYESM1eTKgozrKnT/giphy.webp',
      'https://media2.giphy.com/media/Gx9iROMAiZmFtAopIJ/giphy.webp',
      'https://media1.giphy.com/media/wyyqRSqoWGSiP66G6a/giphy.webp',
      'https://media2.giphy.com/media/SWUneSnAJCgy1qSfNG/giphy.webp',
      'https://media0.giphy.com/media/l6oX5SS8vA5n7GSXG2/giphy.webp',
      'https://media2.giphy.com/media/QBpi7TeiDCgQ59VH1O/giphy.webp',
    ];

    return Scaffold(
      appBar: AppBar(
        title: const Text('Animated image stress test'),
      ),
      body: GridView.count(
        primary: false,
        padding: const EdgeInsets.all(20),
        crossAxisSpacing: 10,
        mainAxisSpacing: 10,
        crossAxisCount: 4,
        children: <Widget>[
          for (int i = 0; i < 50; i++)
            for (String url in urls)
              Image.network(url),
        ],
      ),
    );
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority issues at the top of the work liste: web_canvaskitCanvasKit (a.k.a. Skia-on-WebGL) rendering backend for Webengineflutter/engine related. See also e: labels.perf: memoryPerformance issues related to memoryplatform-webWeb applications specifically

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions