Can anyone help me improve the performance of this Knockout page?

3,398 views
Skip to first unread message

Peter S

unread,
Feb 9, 2011, 4:16:59 PM2/9/11
to KnockoutJS
Hi all,

I'm using Knockout to render a table based on a moderate sized dataset
(approx 200 rows) and am running into major performance issues on
Internet Explorer (8). On Firefox and Chrome it's fine but on IE
there's a noticeable delay of a few seconds before the browser becomes
responsive. I know IE isn't known for being particularly fast but I
didn't expect it to be so bad that the response time would be
measurable in seconds.

I set up a JSFiddle to show what I'm doing:

http://www.jsfiddle.net/bfRS8/

I'm hoping I'm doing something stupid that will be easy to rectify. If
not does anyone have any ideas of anything I can do to improve
matters?

Thanks in advance for any advice.

mkidder

unread,
Feb 10, 2011, 1:24:17 AM2/10/11
to KnockoutJS
Hi Peter,

I don't see any glaring problems with your code. I could recommend
the obvious (streamlining your json, not returning as many rows,
etc.), but that is not really the point. Is there a bottleneck in
knockout that is causing slow execution in IE? It does appear IE
renders this template sample slower than compared to say Chrome. Let's
find out what is going on. Grab your pitch forks, there is an Ogre in
the village!

It did a quick profiling with your sample on my computer, and Chrome
was approx 4-5x faster than IE9 (I don't have IE8 installed). If you
walk the call tree (in either browser) you will see that 80-90% of the
scripts execution is spent in executeTemplate function. Dig deeper
and you will see that time split fairly evenly between the
"jQuery.tmpl" call, and "ko.utils.arrayForEach". Within the
arrayForEach call, 25% of script time is spent within the "unmemoize"
function, and 10% for "findMemoNodes". Are there optimizations
lurking here, very possibly.

So what is my point? From an execution breakdown based on
percentages, both browsers are handling the call stack in the same
manner (despite having completely different javascript engines). Any
optimization to the code, should benefit either browser. Of course,
it is getting late and perhaps I really don't have a point. :) who
knows! It was fun to profile out the code anyways.

Having said all that, there is a pull request for knockout currently
on the github site. It is an optimization to cache template loading,
submitted by canadianveggie (Pulse Energy). I've tested it with your
sample it shaved nearly 20% of execution time off your sample in IE9.
So the Canadians are eating there veggies and optimizing code. You
should to!

Hope you found the information helpful.

Peter S

unread,
Feb 10, 2011, 5:18:17 AM2/10/11
to KnockoutJS
Hi mkidder,

Thanks for the reply, that was very interesting, even if it wasn't the
silver bullet I'd hoped for!
I'm not very experienced with JS development but after reading what
you wrote I poked about with the IE 8 developer tools and found a
JavaScript profiler in there and ran that on my page.
Unless I'm reading the results wrong (and it's very possible that I
am) I get quite a different pattern from the one you saw.
I see a massive difference between the time spent in arrayForEach and
the rendertemplate functions with over twice as much time being spent
in arrayForEach. I'd seen the optimization submitted by canadianveggie
but it didn't "feel" any faster, however profiling revealed it knocked
about half a second off so that's certainly not to be sniffed at. This
optimization shifted the execution to about 90% spent in the
arrayForEach, the vast majority of which is spent in the unmemoize
function, so I guess there's something in there that IE 8 struggles
with.

Actually, this is quite depressing as I'd hoped the bottleneck was
going to be in the templating engine rather than Knockout itself. I
don't want to give up on Knockout as it's a brilliant library but I'm
not sure I can get away with this level of performance :(

Anders Hansson

unread,
Feb 10, 2011, 5:32:41 AM2/10/11
to knock...@googlegroups.com
I am not really sure if this answer will help you or anything. I am also relatively new to JS development but I have done a fair amount of UI work over the years. And I agree with you that KO is amazing! ;-)

If you have something that is slow that you can't live without you should make the user experience feel snappy at least. It is not that a few seconds will actually make any difference to the user (he or she) would not be able to take all that information in on that time anyway. 

What I mean in more technical terms is to make the UI more asynchronous. If your template rendering takes too much time to be acceptable during the page load. Well, you should do it as asynchronously as possible - loading and populating in the background while the user "feels" that the rest of the page is responding as it should. You could divide the retrieval of the data into chunks and making it appear as it is getting processed rather than waiting for the whole lot to get done before displaying the result, etc, etc... You get the idea. 

The bottom line is that it doesn't have to *feel* slow even though it really is.

Anyway, it's just a thought maybe worth considering.

BR,
Anders

Peter S

unread,
Feb 10, 2011, 5:56:40 AM2/10/11
to KnockoutJS
Progress, I like this profiler tool!

The bulk of time time is being spent in the jQuery event binder.
Removing the jQuery reference from the registerEventHandler and using
the browser specific code saw a reduction in execution time from over
2 seconds to about .7 of a second, with more time now spent in the
template rendering code than the foreach. Whether this will have any
ill effects I'm not sure, but, touch wood, things still seem to be
working ok. Boo, jQuery, boo!

@Anders,

While I certainly agree with what you are saying I'm not sure how I
can apply it in this case. The data loading is not the problem, merely
the time taken for the UI to get drawn and become usable and I don't
see any obvious way to make it incremental.
Having said that I was thinking it would be nice to provide the user
with some kind of feedback that the page is doing something and hasn't
crashed so I'll probably try to figure out some way of showing a
processing image or something while knockout is working.

On Feb 10, 10:32 am, Anders Hansson <and...@opendev.se> wrote:
> I am not really sure if this answer will help you or anything. I am also
> relatively new to JS development but I have done a fair amount of UI work
> over the years. And I agree with you that KO is amazing! ;-)
>
> If you have something that is slow that you can't live without you should
> make the user experience feel snappy at least. It is not that a few seconds
> will actually make any difference to the user (he or she) would not be able
> to take all that information in on that time anyway.
>
> What I mean in more technical terms is to make the UI more asynchronous. If
> your template rendering takes too much time to be acceptable during the page
> load. Well, you should do it as asynchronously as possible - loading and
> populating in the background while the user "feels" that the rest of the
> page is responding as it should. You could divide the retrieval of the data
> into chunks and making it appear as it is getting processed rather than
> waiting for the whole lot to get done before displaying the result, etc,
> etc... You get the idea.
>
> The bottom line is that it doesn't have to *feel* slow even though it really
> is.
>
> Anyway, it's just a thought maybe worth considering.
>
> BR,
> Anders
>

Lance Wynn

unread,
Feb 12, 2011, 8:31:02 PM2/12/11
to KnockoutJS
Hi,
I have an iterative binder called 'each' that I have been using in
lieu of the jquery template binding. I put together a quick test using
it, and was able to render 1000 rows in about 2 seconds in ie. 200
rows takes around .300 secs in ie.

Anyhow, please take a look and let me know what you think:
http://www.jsfiddle.net/lancewynn/ArmPv/7/

Charlie K

unread,
Feb 12, 2011, 9:16:16 PM2/12/11
to KnockoutJS
Nice! I get 1.2 secs in IE and 2.5 secs in chrome and 2.8 secs in FF
for 1000 rows. How'd you make IE faster than Chrome? :)

How does this compare with jquery template performance?

Lance

unread,
Feb 12, 2011, 11:05:48 PM2/12/11
to KnockoutJS
Wow, I only tested on ie for the performance.
The binder is very simple, it just spins through the array, creates a
Dom element applies ko, and appends Dom elements. It does use jQuery
for the Dom manipulation though. If i get time maybe I'll try to
remove the dependency on jQuery. Maybe that will speed things up
more.
> > Anyhow, please take a look and let me know what you think:http://www.jsfiddle.net/lancewynn/ArmPv/7/- Hide quoted text -
>
> - Show quoted text -

Charlie K

unread,
Feb 13, 2011, 1:25:50 PM2/13/11
to KnockoutJS
Hi Lance,

I really like your each binding, syntactically it works great and I
think it adds readability and maintainability to pages that don't have
a lot of data. In cases where performance is most important, it seems
like jquery templates works better. I recreated your example using
jQuery templates for 1000 records in both foreach and data mode:

Google chrome (9.0.597.47 beta):

each (custom): 2800ms
foreach (knockout): 285ms
data (knockout): 151ms


Firefox: (3.6.13)

each (custom): 3500ms (very variable)
foreach (knockout): 1200ms (very variable)
data (knockout): 408ms

IE 8:

each (custom): 1500ms
foreach (knockout): 1500ms (no message???)
data (knockout): 800ms (with a message saying scripts may be slowing
down page)

It is obvious that jQuery templates really uses some js optimizations
available in Chrome, see the fiddle here:
http://www.jsfiddle.net/charlieknoll/FyFFt/16/

These were run on 1000 records which may not be realistic, I don't
think any page should be showing 1000 records but if performance is
highest priority using jQuery templates in "data" mode is the way to
go.
> > > Anyhow, please take a look and let me know what you think:http://www.jsfiddle.net/lancewynn/ArmPv/7/-Hide quoted text -

Peter S

unread,
Feb 14, 2011, 9:43:55 AM2/14/11
to KnockoutJS
Hi Lance,

I'm afraid I didn't see any improvements in performance either. That's
a really nice syntax though, it would be great if we could leverage
that using jQuery templates instead of having to provide an external
template to use.
> > > > Anyhow, please take a look and let me know what you think:http://www.jsfiddle.net/lancewynn/ArmPv/7/-Hidequoted text -

Lance Wynn

unread,
Feb 14, 2011, 6:15:57 PM2/14/11
to KnockoutJS
Hey Peter,
Please check out this discussion, I wrote a pagedArray binding handler
that (if I do say so myself) is pretty sweet, and runs quite fast.

http://groups.google.com/group/knockoutjs/browse_thread/thread/9d66036113bc756a

here's the fiddle:
http://jsfiddle.net/lancewynn/TDQRd/
> > > > > Anyhow, please take a look and let me know what you think:http://www.jsfiddle.net/lancewynn/ArmPv/7/-Hidequotedtext -
>
> > > > - Show quoted text -- Hide quoted text -

Peter S

unread,
Feb 15, 2011, 4:26:29 AM2/15/11
to KnockoutJS
Hi Lance,

That is really, really cool, I love it. I was thinking about how to do
paging for my project and had resigned myself to having a server
paging model with one page at a time editing but this is miles better.
I really need to improve my JavaScript, it amazes me what skilled
people can do with it.

On Feb 14, 11:15 pm, Lance Wynn <lance.w...@stgutah.com> wrote:
> Hey Peter,
> Please check out this discussion, I wrote a pagedArray binding handler
> that (if I do say so myself) is pretty sweet, and runs quite fast.
>
> http://groups.google.com/group/knockoutjs/browse_thread/thread/9d6603...
Reply all
Reply to author
Forward
0 new messages