Dispatches From the Edge: Super Fast Collections

written by Tyler Keating

One of the most advanced changes coming in 1.10 is the formalization of a major enhancement to SproutCore’s collection views.  Some of you may have heard of, used or tried to use the SC.CollectionFastPath mixin which gives SproutCore’s collection views, namely SC.ListView and SC.GridView, a massive performance boost.  The performance boost comes from pooling the item view objects, pooling item view layers (i.e. elements) and re-positioning layers using layout styles without modifying the DOM tree.  By re-using objects and elements, we can increase the speed that our collections can update, making gigantic lists perform like butter, even on mobile.

However, using SC.CollectionFastPath was unwieldy and difficult to get working correctly.  Turning it on was not enough, you also had to provide a couple properties on your item view class that were totally undocumented.   Due to the fact that SC.CollectionView is already optimized to create item view objects and layers only for the visible portion of the collection, it could be hard to even be sure that the fast path code was active or not.  This is all changing in 1.10.

We believe that every SproutCore view should be as fast as possible out-of-the-box on every platform and so we’re making these improvements a part of SC.CollectionView directly.  This means that by default, SC.ListView and SC.GridView will be fully optimized without any further configuration.  That said, when creating custom item views, you should properly support render and update.  Since view performance is so important, you should already know how to do this and if you need a good example, check out the custom item views in the new demo in the SproutCore Showcase.  This demo was created to debug this new technology as well as to demonstrate working with gigantic lists.

For now, the feature is still being tested and fine-tuned and any additional real-world feedback is appreciated.  So please check it out on the SproutCore master branch and bring any issues forward so that they can be addressed before release.

Thanks!

 

For discussion, please use sproutcore@googlegroups.com or #sproutcore on IRC.

Note:  Whereas, before you needed to set properties to turn this on, you have to set properties to turn it off right now.  If for whatever reason, you don’t want to pool elements, you can set isLayerReusable to false on your custom item view and if you don’t want to pool views, you can set isReusable to false as well.

Dispatches From the Edge: Invoking “Next”

written by Tyler Keating

As the 1.10 release nears completion, I thought I’d better start writing about some of the many improvements now, lest the final release blog post would take me two days to write.  A lot of the changes, including today’s topic, were the result of working on big feature additions and discovering that more support was needed closer to the core.  Which brings me to the topic of this post:  SC.RunLoop.prototype.invokeNext. Continue reading

Optimizing App Performance with SC.Benchmark

written by Peter Bergstrom

SproutCore is a powerful JavaScript framework that allows developers to take full advantage of the code design paradigms used for native applications developed in languages like Cocoa. However, the tools that are available for web development are different and, in most ways, more basic than what is available when writing native applications.

One of the major challenges developing SproutCore applications is measuring the performance of your application. The major web browsers all have built-in profilers that allow developers to examine the overall performance of their application. These profilers allow you to easily track the execution of operations from start to finish, but they do not provide an easy way to optimize specific portions of code.

One of the less known features of SproutCore is SC.Benchmark, a built-in benchmarking tool that developers can, and should, use to optimize their application. There are several ways to report the data captured using SC.Benchmark, including aggregate reports and graphs.

It is very simple to use and can be used anywhere in a SproutCore application. Each benchmark needs a key value. This key value does not need to be unique if you want to get averages for benchmarks over many runs of a code segment. To start the benchmark, you add SC.Benchmark.start("my benchmark key"); to your function. To stop it, you add SC.Benchmark.end("my benchmark key");

Benchmarking Functions and Loops

In the example below, you can see it used inside of a function to capture the execution time for creating a number of SproutCore objects.

createObjects: function(klass, count) {
	SC.Benchmark.start("createObjects");
 
	var objects = [];
	for(var i=0; i<count ; i++) {
		objects.push(klass.create());
	}
 
	SC.Benchmark.end("createObjects");
}

Continue reading

Faster Loading Through Eval()

written by SproutCore

Note: Unfortunately, the images that accompanied this post were stored in an individual’s private share and have been lost. Because this post is very old, it will not be updated. However, the results of this work did make its way into SproutCore as SC.Module.

When you want to reduce the load time of a JavaScript-heavy web page (like any SproutCore application), you inevitably spend a lot of time thinking about how to reduce the time consumed by the JavaScript itself on page load.  This is particularly true when working on mobile devices, as the Gmail or Mobile team recently pointed out.

The Gmail team used an interesting technique to reduce their load time on the iPhone by loading scripts as comment which they later regexed and eval’d on demand.  I wanted to see if I could make something like this totally automatic in the next version of SproutCore, so I’ve been doing some research.  This post documents some of my findings.

Anatomy of a Script Load

Whenever your browser loads a script, it essentially has to go through three steps:

  1. Download the script from the server (if needed) or load it from cache
  2. Parse the script
  3. Execute the actual code in the script

Now, I should point out that usually 80% of your performance problem lie in step 3.  You can often cut the script-portion of your page load time the most by simply redesigning your code to do less work up front.

This is mostly what we focused on for SproutCore 1.0 and it yielded some big improvements.  One app, for example, had it’s worst case load time on IE drop from 10 seconds to 2 seconds just by using our new API that defers execution whenever possible.

After you stop doing more work than necessary, often the next biggest bottleneck is step 1.  You can get around this by packaging your scripts into as few files as possible, using a CDN, and using caching.  Again, SproutCore 1.0 makes almost all of this totally automatic.  So we’ve got you covered there.


Continue reading