Repository: flutter
Issue: TextField is slow with long text with CanvasKit
Labels: a: text input,engine,c: performance,platform-web,perf: speed,e: web_canvaskit,has reproducible steps,assigned for triage,P2,found in release: 3.10,found in release: 3.12,team-web,triaged-web

## Details

With CanvasKit, setting a `TextEditingController.text` to a string with 270k characters takes 90 seconds including the render.
With HTML renderer, it is takes less than a second although still noticeably slow.

This test app progressively sets the text to 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, and 10000 lines (each 27 characters long) and measures the time before interactive again after each change.

With different renderers, it shows the following time in seconds (ran with `--release`):

```
Lines	1000	2000	3000	4000	5000	6000	7000	8000	9000	10000
HTML	0.111	0.154	0.188	0.211	0.252	0.394	0.447	0.423	0.44	0.491
Canvas	0.806	2.448	5.308	9.267	23.366	32.874	46.939	59.016	73.45	90.266
```

To produce this series, click "1-10k" button.
To measure a single change, click any of the other buttons.

In this video, the text field is set to 3000 lines, which takes almost 6 seconds:

https://github.com/flutter/flutter/assets/44893228/9a5b5dc3-8d9e-451c-b7bb-50579f4067eb

Subsequent edits of such long texts are also slow.

Nearly identical results are produced with `expands: true` and without it (wrapping in a `SingleChildScrollView`).

<details>
<summary>main.dart</summary>

```dart
import 'dart:js' as js;
import 'package:flutter/material.dart';

const maxKLines = 10;
const text = 'abcdefghijklmnopqrstuvwxyz\n';
final texts = [
  for (int i = 0; i <= maxKLines; i++) text * i * 1000,
];

final controller = TextEditingController();
final renderer = js.context['flutterCanvasKit'] == null ? 'HTML' : 'Canvas';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          actions: [
            for (int i = 0; i <= maxKLines; i++)
              ElevatedButton(
                child: Text('${i}k'),
                onPressed: () => _setText(i),
              ),
            ElevatedButton(
              child: Text('1-${maxKLines}k'),
              onPressed: _setTexts,
            ),
          ],
        ),
        body: TextField(
          controller: controller,
          maxLines: null,
          expands: true,
        ),
      ),
    );
  }

  Future<Duration> _setText(int klines) async {
    final sw = Stopwatch();
    sw.start();

    controller.text = texts[klines];

    // Give up the control to render.
    await Future.delayed(const Duration(milliseconds: 100));

    final result = sw.elapsed;
    print('Set ${klines}k lines in ${result}');
    return result;
  }

  Future<void> _setTexts() async {
    final durations = <Duration>[];

    for (int i = 1; i <= maxKLines; i++) {
      durations.add(await _setText(i));
    }

    print('$renderer\t' + durations.map((d) => d.inMilliseconds / 1000).join('\t'));
  }
}
```
</details>

**Target Platform:** Web
**Target OS version/browser:** Ubuntu, Chrome 114

## Logs

<details>
<summary>flutter doctor -v</summary>

```
[✓] Flutter (Channel master, 3.12.0-3.0.pre.35, on Ubuntu 20.04.5 LTS 5.14.0-1059-oem, locale en_US.UTF-8)
    • Flutter version 3.12.0-3.0.pre.35 on channel master at /home/alexey/snap/flutter/common/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 66cda5917d (2 hours ago), 2023-06-09 04:28:18 -0700
    • Engine revision cb93477008
    • Dart version 3.1.0 (build 3.1.0-180.0.dev)
    • DevTools version 2.24.0

[!] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at /home/alexey/Android/Sdk
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/linux#android-setup for more details.

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • clang version 10.0.0-4ubuntu1
    • cmake version 3.16.3
    • ninja version 1.10.0
    • pkg-config version 0.29.1

[✓] Android Studio (version 2022.1)
    • Android Studio at /home/alexey/bin/android-studio
    • Flutter plugin version 72.1.2
    • Dart plugin version 221.6096
    • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301)

[✓] VS Code (version 1.75.1)
    • VS Code at /usr/share/code
    • Flutter extension can be installed from:
      🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Ubuntu 20.04.5 LTS 5.14.0-1059-oem
    • Chrome (web)    • chrome • web-javascript • Google Chrome 114.0.5735.90

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.
```
</details>