fleather-editor / fleather

Soft and gentle rich text editing for Flutter applications.
https://fleather-editor.github.io
Other
197 stars 35 forks source link

The blinking cursor in the Fleather editor is causing severe heating of the phone. #394

Closed guoz2013 closed 1 month ago

guoz2013 commented 1 month ago

I've noticed that when the editor cursor is blinking, it causes significant heating of the phone. If the editor loses focus, the phone's energy consumption returns to normal. In XCode, the increase in energy consumption is quite noticeable. I'm not sure what the cause is, as I've only used the simplest example without any additional features.

Steps to Reproduce

Just use the simplest example.

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final controller = FleatherController(document: ParchmentDocument());
  void _incrementCounter() {
    setState(() {
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: Column(
        children: [
          FleatherToolbar.basic(controller: controller),
          Expanded(
            child: FleatherEditor(controller: controller),
          ),
          FleatherField(controller: controller)
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Environment

image

guoz2013 commented 1 month ago

Then, when using TextField, the cursor still blinks, but the energy consumption noticeably returns to normal. I'm not sure what the difference is between how Fleather and TextField draw the cursor. I'm curious if there's potential for optimization here. image

Amir-P commented 1 month ago

Hi @guoz2013 . Thanks for reporting the issue. I haven't investigated it thoroughly yet, but I suspect it might be coming from rendering/editable_text_line.dart:472. It's also worth noting that we have planned to fix some performance issues that we have and we have a PR for adding performance tests to validate the improvements (#384). I'm a bit busy recently but I will prioritize working on performance issues.

amantoux commented 1 month ago

@Amir-P I tried removing the entire painting of the cursor (removing any calls to containsCursor) but it had no effect After some more investigation, it seems we are paint the entire editor at each tick of the cursor. Don't know if this is expected...

amantoux commented 1 month ago

@guoz2013 can you please try with?

  fleather:
    git:
      url: https://github.com/fleather-editor/fleather
      ref: fix/cursor_blink_gpu_intensive
      path: packages/fleather

Note that there is a bug with the floating cursor, that I'm working on

Update: Fixed the floating cursor issue

guoz2013 commented 1 month ago

@amantoux Thank you very much for the prompt update. I tried the new branch, but the issue seems to persist. image

amantoux commented 1 month ago

@guoz2013 are you still using an empty editor? are you sure you are using the branch? this is what I get

image
guoz2013 commented 1 month ago

@amantoux Apologies, it was due to a cache issue. I created a new project and everything is back to normal now. Thank you very much.

guoz2013 commented 1 month ago

@amantoux I've found that if I open the editor from a bottom sheet, the issue resurfaces, causing the cursor to flicker and leading to infinite rebuilding of both the home view and the Editor Page. I'm not sure if this is an issue with the bottom sheet itself.

code:

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

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final controller = FleatherController(document: ParchmentDocument());
  void _incrementCounter() {
    showModalBottomSheet(context: context, builder: (context)=>SizedBox(
        height: MediaQuery.of(context).size.height*0.5 ,
        child: const EditorPage()),isScrollControlled: true );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
        title: Text(widget.title),
      ),
      body: ListView.builder(itemBuilder: (context, index)=> FlutterLogo(size: 200), itemCount: 100,),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

class EditorPage extends StatefulWidget {
  const EditorPage({super.key});

  @override
  State<EditorPage> createState() => _EditorPageState();
}

class _EditorPageState extends State<EditorPage> {
  final controller = FleatherController(document: ParchmentDocument());
  void _incrementCounter() {
    setState(() {
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        children: [
          FleatherToolbar.basic(controller: controller),
          Expanded(
            child: FleatherEditor(controller: controller, ),
          ),
          FleatherField(controller: controller)
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

截屏2024-08-12 上午1 50 55 拷贝

amantoux commented 1 month ago

@guoz2013 you seem to be in debug mode, if it is the case, it is normal that the app consumes more resources I tried your example on my end, here's my energy consumption in profile mode

image
guoz2013 commented 1 month ago

@amantoux I tried it in profile mode, and the energy consumption returned to normal, thank you very much.