Skip to main content
Participating Frequently
October 28, 2009
Question

Text Editing Performance issues

  • October 28, 2009
  • 1 reply
  • 2326 views

Hello!

I've been trying out Flex 4 and TLF recently, and I've stumbled on huge performance issue in TextArea component, which is built around TLF.

It works great for smaller texts, but when you try to edit text say 50kB long, then you find yourself struggling at every character, cause they appear with a noticeable delay as you type.

I've tried to take a deeper look into a problem, and it seems that TLF recomposes all the text up to the insertion point on each character insert.  It's really visible - typing is OK at the begining of the text, but it becomes really slow at the end of it.

I believe that recomposition on every single text insert operation is done in EditManager.finalizeDo which calls

updateAllControllers() every time.

Is it a TLF problem or Flex problem? If it's flex problem, then what was done wrong in Flex 4 TextArea? How can it be optimized so that performance becomes acceptable?

This topic has been closed for replies.

1 reply

Adobe Employee
November 2, 2009

It does depend a bit on your content and where you type - are you typing at the end or the beginning?  Is it one long paragraph or lots of small ones?

Typing at the beginning of one large paragraph will damage and rebreak every line.  A damaged paragraph gets recomposed to the end.

The rest of the lines in the container will be reused if possible.  It doesn't recompose but it will "re-place" every line in the container  (it scans through it and makes sure it is reusable and looks at its width - it may reuse the same line at a new location). It does this in order to get the content bounds calculation width correct.

If you are doing your own TLF containers there are recent optimizations to skip to the first damaged container - so if you can organize your TextFlow so that it uses multiple containers TLF will skip to the first damaged container.

The drawback of that approach is that it defeats TLF's line virtualization logic.  The idea of that is that in a scrolled container TLF lets the player GC lines that aren't displayed to reduce memory use.

Going forward TLF needs a way to compose just the damaged lines in the container and still get the content bounds calculation correct.  This won't be addressed in time for 1.0.

Hope that helps,

Richard

hrundik1Author
Participating Frequently
November 2, 2009

The problem is mostly visible when I type at the end of the text. The paragraphs are nor small, nor big. The text all in all has around 900 lines.

Performance slowdowns are REALLY visible when editing long text at the end, it takes ages to appear (something around a second).

I've used 400px wide TextArea for tests with a sample text (attached, 50kB) already in it:

<fx:Script>
<![CDATA[
  import spark.layouts.VerticalLayout;
  protected function button1_clickHandler(event:MouseEvent):void
  {
   area.text = testString;
  }
]]>
</fx:Script>

<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
<fx:String id="testString" source="20959_small.txt" />
</fx:Declarations>

<s:VGroup>
<s:TextArea id="area" width="400" height="300" />
<mx:Button label="load (50 kb of text)" click="button1_clickHandler(event)" />
</s:VGroup>

TextArea uses RichEditableText internally in Flex 4. And RichEditableText uses single container and, I believe, it's the main reason of these slowdowns.

So the question is - is it planned to make RichEditableText in Flex 4 use multiple containers? Or is it planned to speed up TLF internals itself to deal better with long containers?

Unfortunately, in it's current state RichEditableText component is actually a no-go for editing sufficiently long texts.

Adobe Employee
November 2, 2009

I wrote this example program to see how a simple AS3 TLF only solution would work on your content.  Note I had to strip out the unicode value that was the first character of your posted file.  I've attached the tweaked text file.  The problem that caused is fixed in the 10.1 player.  Anyhow compare this to your RichEditableText solution.

package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
   
    import flashx.textLayout.container.ContainerController;
    import flashx.textLayout.conversion.ConversionType;
    import flashx.textLayout.conversion.TextConverter;
    import flashx.textLayout.edit.EditManager;
    import flashx.textLayout.elements.TextFlow;
    import flashx.textLayout.tlf_internal;
   
    import mx.core.ByteArrayAsset;
   
    [SWF(width="1100", height="550")]
    public class SmallText extends Sprite
    {
       // embed the file
        [Embed(source="20959_small.txt",mimeType="application/octet-stream")]
        private var SmallTextData : Class;
   
        public function SmallText()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
               
            var s:Sprite = new Sprite();
            s.x = 50;
            s.y = 50;
            addChild(s);
           
            var baa:ByteArrayAsset = new SmallTextData();
            var textData:String = baa.readMultiByte(baa.length,"utf-8");
            var textFlow:TextFlow = TextConverter.importToFlow(textData, TextConverter.PLAIN_TEXT_FORMAT);

            textFlow.flowComposer.addController(new ContainerController(s,400,300));
            textFlow.interactionManager = new EditManager();
            textFlow.flowComposer.updateAllControllers();
        }
    }
}