Skip to content

Significantly worse performance of new RoundedSuperellipse compared to default BorderRadius #167366

Closed

Description

@FelixMittermeier

Steps to reproduce

  1. Create a page with many widgets which are using the recently introduced RoundedSuperellipse
  2. Open this page, go back, open again and you will see noticeable lags

Expected results

Equal performance as when I use the default borderRadius property.

Actual results

Significant worse performance. The raster thread is taking twice as long compared to the default borderRadius. This can be seen also in the video (at the second half I have enabled the performance overlay).

The phone used was an iPhone 14 Pro Max, so not a slow device.

Code sample

Slow code:

DecoratedBox(decoration: ShapeDecoration(shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(16)))

Fast code:

DecoratedBox(decoration: BoxDecoration(borderRadius: BorderRadius.circular(16))

Screenshots or Video

Screenshots / Video demonstration

Slow raster thread with lags using RoundedSuperellipseBorder (performance overlay enabled in the second half of the video):

ScreenRecording_04-17-2025.20-28-16_1-3.mp4

Normal performance using default BorderRadius (performance overlay enabled in the second half of the video):

ScreenRecording_04-17-2025.20-33-15_1-2.mp4

Flutter Doctor output

Doctor output
[✓] Flutter (Channel master, 3.32.0-1.0.pre.73, on macOS 15.4 24E248 darwin-arm64, locale de-DE) [2,1s]
    • Flutter version 3.32.0-1.0.pre.73 on channel master at /Users/felixmittermeier/Documents/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision a7f820163c (6 days ago), 2025-04-11 18:24:16 -0700
    • Engine revision a7f820163c
    • Dart version 3.8.0 (build 3.8.0-265.0.dev)
    • DevTools version 2.45.0-dev.0

[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1) [1.558ms]
    • Android SDK at /Users/felixmittermeier/Library/Android/sdk
    • Platform android-35, build-tools 35.0.1
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 21.0.5+-13047016-b750.29)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.3) [779ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16E140
    • CocoaPods version 1.16.2

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

[✓] Android Studio (version 2024.3) [9ms]
    • 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 21.0.5+-13047016-b750.29)

[✓] VS Code (version 1.99.2) [8ms]
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.108.0

[✓] Connected device (3 available) [5,8s]
    • iPhone 14 Pro Max (mobile) • 00008120-00086C192E60C01E • ios            • iOS 18.4 22E240
    • macOS (desktop)            • macos                     • darwin-arm64   • macOS 15.4 24E248 darwin-arm64
    • Chrome (web)               • chrome                    • web-javascript • Google Chrome 135.0.7049.86

[✓] Network resources [588ms]
    • All expected network resources are available.

• No issues found!

Activity

  1. maheshj01 commented on Apr 18, 2025

    @maheshj01
    Member

    Hey @FelixMittermeier, Thanks for filing the issue. Can you please confirm if the below code sample reproduces the issue on your end. If it doesn't then please share a minimal and complete code sample to reproduce the issue.

    I verified the below code on a simulator as well as Google pixel 7 (Physical device) and it seems to work fine.

    Screen.Recording.2025-04-18.at.17.53.51.mov
    code sample
    // create a counter app with flutter
    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home: MyHomePage());
      }
    }
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      bool bugMode = false;
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('Counter App'),
            actions: [
              Text('Bug Mode'),
              Switch(
                value: bugMode,
                onChanged: (x) {
                  setState(() {
                    bugMode = !bugMode;
                  });
                },
              ),
            ],
          ),
          body: ListView(
            children: [
              for (var i = 0; i < 100; i++) Item(index: i, bugMode: bugMode),
            ],
          ),
        );
      }
    }
    
    class Item extends StatelessWidget {
      final int index;
      final bool bugMode;
    
      const Item({super.key, required this.index, required this.bugMode});
    
      @override
      Widget build(BuildContext context) {
        Widget decoratedBox() => DecoratedBox(
          decoration:
              bugMode
                  ? ShapeDecoration(
                    shape: RoundedSuperellipseBorder(
                      borderRadius: BorderRadius.circular(16),
                    ),
                  )
                  : BoxDecoration(borderRadius: BorderRadius.circular(16)),
          child: Text(
            index % 10 == 0 ? 'Tap me to Navigate to second Screen' : 'Item $index',
          ),
        );
    
        if (index % 10 == 0) {
          return InkWell(
            onTap: () {
              Navigator.push(
                context,
                MaterialPageRoute(builder: (context) => SecondPage()),
              );
            },
            child: decoratedBox(),
          );
        }
        return decoratedBox();
      }
    }
    
    class SecondPage extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: Text('Second Page')),
          body: Center(child: Text('Nothing to see here.')),
        );
      }
    }
    
    flutter doctor -v

    master

    [✓] Flutter (Channel master, 3.32.0-1.0.pre.90, on macOS 15.4 24E248 darwin-arm64, locale
        en-US) [31.4s]
        • Flutter version 3.32.0-1.0.pre.90 on channel master at
          /Users/mahesh/Development/flutter_master
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 29810cd6d1 (3 days ago), 2025-04-16 00:07:50 +0530
        • Engine revision 29810cd6d1
        • Dart version 3.8.0 (build 3.8.0-265.0.dev)
        • DevTools version 2.45.0-dev.0
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [4.5s]
        • Android SDK at /Users/mahesh/Library/Android/sdk
        • Platform android-35, build-tools 35.0.0
        • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
          This is the JDK bundled with the latest Android Studio installation on this machine.
          To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 16.3) [3.1s]
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 16E140
        • CocoaPods version 1.16.2
    
    [✓] Chrome - develop for the web [148ms]
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2024.3) [147ms]
        • 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 21.0.5+-12932927-b750.29)
    
    [✓] IntelliJ IDEA Community Edition (version 2021.2.1) [144ms]
        • IntelliJ at /Applications/IntelliJ IDEA CE.app
        • Flutter plugin version 61.2.4
        • Dart plugin version 212.5080.8
    
    [✓] VS Code (version 1.96.2) [18ms]
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.102.0
    
    [✓] Connected device (2 available) [6.3s]
        • macOS (desktop) • macos  • darwin-arm64   • macOS 15.4 24E248 darwin-arm64
        • Chrome (web)    • chrome • web-javascript • Google Chrome 131.0.6778.265
    
    [✓] Network resources [365ms]
        • All expected network resources are available.
    
    • No issues found!
  2. added
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Apr 18, 2025
  3. FelixMittermeier commented on Apr 21, 2025

    @FelixMittermeier
    ContributorAuthor

    @maheshj01 Thanks for answering. I slightly modified your code sample to make it easily reproducible now.

    New screen recording:

    ScreenRecording_04-21-2025.23-53-01_1.mp4

    Sample code:

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(home: MyHomePage());
      }
    }
    
    List<Widget> items = [];
    
    class MyHomePage extends StatefulWidget {
      const MyHomePage({super.key});
    
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      bool bugMode = false;
    
      void createItems() {
        items = List.generate(301, (index) => Item(index: index, bugMode: bugMode));
      }
    
      @override
      void initState() {
        super.initState();
        createItems();
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Column(
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
              const SizedBox(height: 200),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('Bug Mode'),
                  Switch(
                    value: bugMode,
                    onChanged: (x) {
                      setState(() {
                        bugMode = !bugMode;
                        createItems();
                      });
                    },
                  ),
                ],
              ),
              Padding(
                padding: const EdgeInsets.only(top: 20, left: 16),
                child: ElevatedButton(
                  onPressed: () {
                    Navigator.push(context, MaterialPageRoute(builder: (context) => SecondPage()));
                  },
                  child: Text('Tap me to open second page'),
                ),
              ),
            ],
          ),
        );
      }
    }
    
    class Item extends StatelessWidget {
      final int index;
      final bool bugMode;
    
      const Item({super.key, required this.index, required this.bugMode});
    
      @override
      Widget build(BuildContext context) {
        final shadow = [BoxShadow(color: Colors.black.withValues(alpha: 0.15), blurRadius: 8, spreadRadius: -4, offset: const Offset(0, 2))];
        return Container(
          padding: EdgeInsets.all(4),
          decoration:
              bugMode ? ShapeDecoration(shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(16)), color: Colors.grey, shadows: shadow) : BoxDecoration(borderRadius: BorderRadius.circular(16), color: Colors.grey, boxShadow: shadow),
          child: Text(index.toString()),
        );
      }
    }
    
    class SecondPage extends StatelessWidget {
      const SecondPage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(appBar: AppBar(title: Text('Second Page')), body: Wrap(spacing: 4, runSpacing: 4, children: items));
      }
    }
    
  4. removed
    waiting for responseThe Flutter team cannot make further progress on this issue until the original reporter responds
    on Apr 21, 2025
  5. maheshj01 commented on Apr 21, 2025

    @maheshj01
    Member

    Thanks for the code sample reproduces on the latest master channel.

    Without RoundedSuperellipseBorder With RoundedSuperellipseBorder
    Screen.Recording.2025-04-21.at.18.53.20.mov
    Screen.Recording.2025-04-21.at.18.49.32.mov
    flutter doctor -v

    master

    [✓] Flutter (Channel master, 3.32.0-1.0.pre.90, on macOS 15.4 24E248 darwin-arm64, locale en-US) [19.4s]
        • Flutter version 3.32.0-1.0.pre.90 on channel master at /Users/mahesh/Development/flutter_master
        • Upstream repository https://github.com/flutter/flutter.git
        • Framework revision 29810cd6d1 (6 days ago), 2025-04-16 00:07:50 +0530
        • Engine revision 29810cd6d1
        • Dart version 3.8.0 (build 3.8.0-265.0.dev)
        • DevTools version 2.45.0-dev.0
    
    [✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0) [3.8s]
        • Android SDK at /Users/mahesh/Library/Android/sdk
        • Platform android-35, build-tools 35.0.0
        • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
        • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
          This is the JDK bundled with the latest Android Studio installation on this machine.
          To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
        • Java version OpenJDK Runtime Environment (build 21.0.5+-12932927-b750.29)
        • All Android licenses accepted.
    
    [✓] Xcode - develop for iOS and macOS (Xcode 16.3) [2.2s]
        • Xcode at /Applications/Xcode.app/Contents/Developer
        • Build 16E140
        • CocoaPods version 1.16.2
    
    [✓] Chrome - develop for the web [123ms]
        • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
    
    [✓] Android Studio (version 2024.3) [122ms]
        • 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 21.0.5+-12932927-b750.29)
    
    [✓] IntelliJ IDEA Community Edition (version 2021.2.1) [119ms]
        • IntelliJ at /Applications/IntelliJ IDEA CE.app
        • Flutter plugin version 61.2.4
        • Dart plugin version 212.5080.8
    
    [✓] VS Code (version 1.96.2) [18ms]
        • VS Code at /Applications/Visual Studio Code.app/Contents
        • Flutter extension version 3.102.0
    
    [✓] Connected device (3 available) [6.4s]
        • iPhone 16 Pro (mobile) • D4BBFF03-3CBE-4EA0-80E0-7629055FD9E0 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-18-4
          (simulator)
        • macOS (desktop)        • macos                                • darwin-arm64   • macOS 15.4 24E248 darwin-arm64
        • Chrome (web)           • chrome                               • web-javascript • Google Chrome 131.0.6778.265
    
    [✓] Network resources [400ms]
        • All expected network resources are available.
    
    • No issues found!

    dart_devtools_2025-04-21_18_50_39.869.json.zip

  6. added
    engineflutter/engine related. See also e: labels.
    c: performanceRelates to speed or footprint issues (see "perf:" labels)
    has reproducible stepsThe issue has been confirmed reproducible and is ready to work on
    and removed
    in triagePresently being triaged by the triage team
    on Apr 21, 2025
  7. added
    P2Important issues not at the top of the work list
    on Apr 28, 2025
  8. jonahwilliams commented on Apr 29, 2025

    @jonahwilliams
    Contributor

    The cause of the slowness is that the rounded super ellipose doesn't have a fast path for blurs. #163893 needs to be fixed. FYI @dkwingsmt

  9. added
    r: fixedIssue is closed as already fixed in a newer version
    on May 25, 2025
  10. github-actions commented on Jun 8, 2025

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  11. locked as resolved and limited conversation to collaborators on Jun 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: performanceRelates to speed or footprint issues (see "perf:" labels)engineflutter/engine related. See also e: labels.found in release: 3.32Found to occur in 3.32has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions