Phil Wallach

I follow where my mind leads …

Phil Wallach header image 2

OpenLaszlo: optimising for a large number of views

July 22nd, 2007 · 3 Comments

THE PROBLEM

I had a serious performance problem with an OpenLaszlo application.  The application had a large number of views, most of which were ‘hidden’ at any one time.  The views comprised a number of subviews, including an image loaded at runtime.  I wanted all views instantiated at startup for quick navigation by the user.

The problem was that the load time ranged from 20 to 30 seconds for even small datasets.  That was pretty unacceptable.

WHAT DIDN’T WORK

As I mentioned above, I wanted all the views instantiated at startup for quick navigation by the user.  I found this out the hard way.  One of my first attempts to fix this problem used a state wrapped around each set of views.  By toggling the state on and off as required, I was able to instantiate only the minimal number of views I needed.  Load time was super fast.

The problem with this solution was that as the user navigated around the application, the lag in instantiating the newly visible views was very noticeable.  Worse, because the state mechanism destroyed views that were no longer necessary, this problem never went away.  The views had to be instanitated anew every time.

THE SOLUTION

The runtime loading of images was deferred until the image was required (previously the image had been loaded automatically through the ondata handler). The image view has a load_image() method to manually load the image.    There is a small noticeable delay when the image loads, but it is pretty quick and only happens the first time the view is displayed.

  <class name="myclass">
    <attribute name="imageurl" type="string" />
    <method name="load_image">
      var image = this.datapath.xpathQuery("text()");
      if (image == null) return;
      var imageurl="images/" + image;
      if (this.getAttribute('imageurl') == imageurl)
        return;
      this.setSource(imageurl);
      this.setAttribute('imageurl', imageurl);
    </method>
    ...
  </class>

For the views I set initstage to ‘defer’ or ‘late’ to delay instantiation. The ‘onvisible’ handler calls completeInstantiation() on views that become visible and requests the image be loaded.


  <view onvisible="${...}">
      <handler name="onvisible" args="v">
        if (!v) return;
        if (!this.myview.isinited)
          this.myview.completeInstantiation();
        this.myview.load_image();
      </handler>
      <myclass name="myview" initstage="defer" />
  </view>

These changes sped up application loading by a factor of 6, without materially affecting the user experience.

RESOURCES 

Check out http://www.vidog.com/blog/my-top-las…formance-tips/ if you haven’t already.

FOLLOW UPS

OpenLaszlo: background loading of images
OpenLaszlo: initstage … defer vs late

Tags: OpenLaszlo

3 responses so far ↓

  • 1 John Sundman // Jul 23, 2007 at 12:23 am

    Phil,

    Cool, thanks.

    It’s nifty to see OpenLaszlo blogs filling in the information space.

    I have nothing to add other than a usage nit: I think you want “affecting” not “effecting” in the last sentence.

  • 2 Raju Bitter // Aug 9, 2007 at 7:16 pm

    Generally states are a good solution to the view instantiation performance problems, but it’s important to use the pooling="true" attribute to make sure the views are re-used and not destroyed every time the state is removed.

  • 3 phil // Aug 9, 2007 at 8:22 pm

    Raju,

    You make a good point for the general case, which is important to point out for others reading this post.

    Unfortunately my application cannot use pooling, as stated in the documentation:
    “Pooling is generally a good optimization in cases where the data completely informs the state of a replicated view. If the view has additional state which can change through user interaction or depends on setting attributes at init time, then this option cannot usually be used.”

    It may be worthwhile for me to look at modifying my application to make pooling possible, but that is for another day.

    Thanks for your comment.

Leave a Comment