Skip to main content
March 24, 2009
Question

Composition Performance/Behavior

  • March 24, 2009
  • 1 reply
  • 555 views
I have some questions about how the composer works when parts of the text flow are damaged and how it interacts with the container controllers. We are seeing the responsiveness of editing operations drop significantly with longer text flows with the way that we have things set up. I've developed a custom container controller, and I've had some fairly good success with some ideas to improve scrolling/composition/editing performance when dealing with text flows on the order of 50,000+ characters in one container.

All that aside, I am trying to understand how the composer works so that I can make more informed decisions about how to interact with/manipulate it. Currently, flex profiling shows that an internal 'callTheComposer' method routinely consumes a majority of the processing time required to update the container after damage. I also notice that the 'verticalScrollPosition' property is accessed on the container controller during this process. Currently, I'm also noticing that the time required by 'callTheComposer' increases as the size of the text flow grows, even if the text flow had been fully composed at the time of damage and only one paragraph was modified and no lines were added or removed.

Here are a few specific questions I have:
1) What's the logic as far as how much work has to be done in 'callTheComposer' when some damage occurs in the middle of a text flow?
2) How exactly is the verticalScrollPosition of the container controller used in the composition process?

It seems that the vertical scroll position is used to determine how much of the text flow needs to be composed. If that's the case, would you consider possibly adding a new getter to the container controller interface for something like get verticalComposePosition that just returns the verticalScrollPosition in the ContainerControllerBase class but would give us the ability to override it if we'd like? I've spent probably 50+ hours just dealing with the fact that composition is tied so closely to the scroll position. It's *really* tough to keep the frame rate up during scrolling (and editing) when composition is required and being enforced. When dealing with text flows that take longer to compose, I would like to be able to control composition asynchronously and keep it separate from the scrolling behavior. I'm doing this now in a roundabout way, but it would be nice a have a cleaner way to control this a little better.

I also have worked on some ideas for improving the performance of the updateCompositionShapes method in the container controller. I'm using a custom composer class that extends StandardFlowComposer, which I supply throught the TextFlow configuration. I added a method to my container controller interface that I call during the 'addLine' method of the composer to notify the container controllers about which line indexes have changed. I then use that information during updateCompositionShapes to narrow down the number of text lines that need to be checked/inserted/removed, etc. Using this pattern improved the average duration of the updateCompositionShapes method by about 10x. That said, there are still some glitches with the approach that I have not worked out.

Some of the issues I'm running into are probably related to how I've attempted to disconnect scrolling from composition, but my goal here is to achieve consistent (ideally near zero) latency for both scrolling and editing, including both short text flows and those that approach 100,000+ characters.

Thanks,
--Brent
This topic has been closed for replies.

1 reply

Adobe Employee
March 25, 2009
We have done only a limited amount of optimization around long flows. When composing a flow into a scrollable container, we will compose through the end of what is visible, and stop sometime soon after that. That means if you are scrolled to the bottom, composition will be slower, because it will have to compose everything previous to the visible area. This should be relatively quick if the lines can be reused, but obviously the longer the flow, and the more you are scrolled down, the longer it will take. We do reuse lines that are undamaged and are being fitted into the same width they had before, and rather than rebuilding them we just reposition them.

Eventually I would like to see us be in a position where we cache enough information that we can start the composition at the point of first change. This is for the future, though, and not much help to you now.

One thing I would advise is where possible to break long flows up into smaller portions to avoid some of these problems. If you are working with an entire book, it is much more efficient to work with it chapter by chapter, it will consume less memory and take some of the pressure off the garbage collector.

We will look into your suggestions for updateCompositionShapes -- that's very useful info.

Thanks!

- robin