Knockout is fantastic but too slow

3,340 views
Skip to first unread message

Joachim

unread,
Dec 27, 2011, 4:45:37 PM12/27/11
to KnockoutJS
I love Knockout and I can't wait to replace my templating engine with
it. However, performance needs to be radically improved.

Model driven views is by far the nicest way to build web applications;
and Knockout is the most mature platform. The only other model driven
alternative is Google MDV. The Google framework however has just been
put together as a proof-of-concept prototype and is way to unstable to
use in production.

I believe Knockout will be a huge hit if performance is addressed. As
it stands now, you will have to give up performance for productivity.
As the end user experience is on top of my list, I will have to wait.

Take a look at these fiddles for comparison:

http://jsfiddle.net/StarcounterJack/FgSCw/
http://jsfiddle.net/StarcounterJack/Fe2Dr/

Joachim

unread,
Dec 27, 2011, 5:59:21 PM12/27/11
to KnockoutJS
On a dual core smartphone the example takes 13 seconds to run instead
of a few milliseconds in the reference template.

Nuno Job

unread,
Dec 27, 2011, 6:01:35 PM12/27/11
to knock...@googlegroups.com
This email contains no information or question. 

Did you hit send by mistake? Or are you just unaware this is a mailing list?

Btw knockoutjs does not take 13 seconds to render any view, so there is the possibility that your code is doing that?

Nuno

Michael Best

unread,
Dec 27, 2011, 6:35:13 PM12/27/11
to KnockoutJS
I think you meant 1.3 seconds. You're right that Knockout is slow for
generating a table of data. This has been discussed in the forum
recently and there are a couple of solutions. You can use a string-
based templating engine for your table. Knockout allows you to hook
into any templating engine for a specific template (Here's an example
using Underscore: http://jsfiddle.net/U4FqR/4/). You can also use the
repeat binding that I've created (https://github.com/mbest/knockout-
repeat). I updated your example to use repeat (https://github.com/
mbest/knockout-repeat) and it's down to about a second.

Michael Best

unread,
Dec 27, 2011, 6:45:49 PM12/27/11
to KnockoutJS
The url for the repeat binding is:
https://github.com/mbest/knockout-repeat

The updated fiddle with repeat is:
http://jsfiddle.net/mbest/FgSCw/7/

Here is a second update to your fiddle that uses repeat along with my
'playground' version of knockout with various optimizations:
http://jsfiddle.net/mbest/FgSCw/8/

Also the time reported in your reference sample isn't accurate. Here's
an update that give an accurate value:
http://jsfiddle.net/mbest/Fe2Dr/5/

Jack Wester

unread,
Dec 27, 2011, 6:54:03 PM12/27/11
to KnockoutJS
Nuno et. al,

Sorry for the incomplete post. In my head I was posting in the git-hub
issues section. Nonetheless. My answer to your comment is this:

I was referring to was the fiddles I posted earlier (
http://jsfiddle.net/StarcounterJack/Fe2Dr/ and http://jsfiddle.net/StarcounterJack/FgSCw/
).

Knockout suffers from its constant re-interpretation of templates and
bindings. In order to be effective, I believe it needs to generate
intermediate functions for reuse. Especially when it comes to
performance sensitive operations such as 'foreach'. Knockout is
*currently* to slow if

a) You work with tabular result-sets
b) Your users use smartphones
c) You have a lot going on in your forms and snappy user interfaces
are important

The reason I'm commenting on it is:
a) Conceptually, a declarative MVVM should be able to generate
intermediate functions for DOM operations and I would like to suggest
it as a priority going forward.
b) I really, really, really like Knockout.
c) I really dislike that I currently have to go back to ugly string
based templating and even uglier binding solutions.
d) I think that testing performance on any mobile device
e) I think that Knockout performance should be put into perspective
with the other components in the stack such as data acquisition and
render times. Take a look at http://www.jamesward.com/census2/ or
other such benchmarks.

EntitySpaces

unread,
Dec 27, 2011, 10:20:44 PM12/27/11
to KnockoutJS
We love Knockout and especially the new 2.0 Native Template Engine,
but have to abandon the Native Template Engine on tabular data of any
real size because of performance with tabular data. Of course, it
depends on the browser, IE is really slow with foreach compared to
Chrome. I kind of agree, a killer fast template engine for 2.x in the
future would be sweet.

EntitySpaces

unread,
Dec 27, 2011, 10:39:21 PM12/27/11
to KnockoutJS
Actually, if you run his original sample in IE 9 it takes anywhere
from 8 to 9 seconds, amazingly, the doT template sample posted here
http://jsfiddle.net/StarcounterJack/Fe2Dr/ runs in 6 milliseconds,
that's 8 seconds vs 6 milliseconds, compare the two in IE, wow

doT - foreach
http://jsfiddle.net/StarcounterJack/Fe2Dr/

ko - foreach
http://jsfiddle.net/StarcounterJack/FgSCw/

Information on doT
http://olado.github.com/doT and https://github.com/olado/doT

Igor Loginov (aka ilog2000)

unread,
Dec 28, 2011, 9:22:35 AM12/28/11
to KnockoutJS
Michael,

Could you, please, elaborate a bit deeper on your 'playground' version
of knockout? What kind of optimization is there?

BTW, the fiddle (http://jsfiddle.net/mbest/FgSCw/8/) doesn't work for
me.

EntitySpaces

unread,
Dec 28, 2011, 11:44:05 AM12/28/11
to KnockoutJS
I just did a very interesting experiment, will post two links later
today, if you take the very fast doT template system and setup it up
as a ko.setTemplateEngine() then you lose most of the benefits. Here's
the deal, if you want to use ko.observable() properties and such you
have to use it through ko.applyBindings() so you have to setup your
template engine through ko. I have samples of this and will post the
comparison in a bit. The truth is, all these comparisons are moot,
sure, you can display html to the screen very fast through doT, but
only if you don't want observable data, and then, why bother, you're
not even using knockout.

EntitySpaces

unread,
Dec 28, 2011, 2:28:54 PM12/28/11
to KnockoutJS
Here are the two links. I'm sorry, I tried to create them in jsFiddle
but had issues, you can just choose "View Source" in the browser.

The doT template engine, very fast, but when used to as the ko
template engine makes very little different at all
http://www.entityspaces.net/Punchout/examples/Non-EntitySpaces/doT_TemplateEngine.htm

The ko template engine:
http://www.entityspaces.net/Punchout/examples/Non-EntitySpaces/ko_TemplateEngine.htm

Now, something very interesting, even though the doT template engine
renders very fast initially, when updating ko.observables the update
is horrible so, look at the button click handler.

So, if you are looking at using a template language through "ko" as a
custom template engine, don't expect any dramatic improvements, it's
the nature of the beast. We will need to wait until a future release
of ko to make binding to large chuncks of data fast. What really
confounds me is why the button click is so slow on the doT sample,
very strange indeed.

Jack Wester

unread,
Dec 28, 2011, 2:35:28 PM12/28/11
to KnockoutJS
The reason DoT is fast is not due to string concatenation (it is still
an order of magnitude faster than interpreting string manipulation
templating engines). The secret sauce is dynamic function generation.
This pattern is not reserved for any particular process and can be
applied whenever there is repetitive state manipulation. I don't know
the specifics of the Knockout implementation, but we use the same
pattern in our database engine (we generate execution function
corresponding to a SQL query. We can then call the ready made function
with the new input parameters whenever a similar SQL query is posed).

Once you travelled down that path, you will find that complexity does
not increase but rather decreases. The generated manipulator functions
can be inspected and debugged much easier than tiresome and complex
workings of the interpreting code that reads the declarative data.

To be more precise:

A) We have a current DOM state generated by a rule/template
B) We have type of model change relating to A)
C) Our aim is to get to the future DOM state C)
D) Lets generate a Javascript function that transforms A) to C) using
B)
E) Save D in a dictionary for reuse using template A) and change type
B) as key
F) Whenever we need to apply B) we look it up in E) and call D) on A).
This will be the fastest way to get to C)

Imho, this would make Knockout up to a hundred times faster.

On Dec 28, 4:39 am, EntitySpaces <entityspa...@gmail.com> wrote:
> Actually, if you run his original sample in IE 9 it takes anywhere
> from 8 to 9 seconds, amazingly, the doT template sample posted herehttp://jsfiddle.net/StarcounterJack/Fe2Dr/runs in 6 milliseconds,

EntitySpaces

unread,
Dec 28, 2011, 2:42:55 PM12/28/11
to KnockoutJS
Thanks Jack, makes sense, I don't know if you read my above post, but
I figured out why the updating of the observables in my doT sample two
posts above is slow, it regenerates the entire page on each change, so
it's rendering the table 15 times since I'm updating 15 columns. This
doesn't happen in the ko example because the foreach and other
constructs are smart and know only what and when to regenerate. So,
swapping doT in as the template engine for "ko's" native template
engine is counter productive, in fact, you really must use "ko's" for
smart binding and intelligent updating. Now, when you don't care about
observables of course you can scream with doT.

I think the real challenge would be for someone to take and totally
overhaul the logic when ko is laying out the data, the updating logic
in ko with observables seems to be very fast and intelligent, just the
bulk foreach'ing over data and getting it onto the screen is slow.

Does that make sense?

EntitySpaces

unread,
Dec 28, 2011, 2:53:03 PM12/28/11
to KnockoutJS
Jack, one more thing. I think our solution is going to be using doT
for laying out static non-observable data and not making it the
ko.templateEngine, rather, just use it as regular ol' doT templating.
Then, when a user clicks on a row in the tabular data (grid) when we
fetch the entity, make it observable, and use
ko.applyBindings(viewModel, theDiv) to bind the "detail editing" area.
This way we have extremely fast layout, and all the proper observables
for tracking our row level and column level dirty states.

One the native ko template engine is fast enough we can easily switch
over from the doT syntax if we need to and make our whole "grids"
observable.


Jack Wester

unread,
Dec 28, 2011, 3:03:15 PM12/28/11
to KnockoutJS
I don't think using DoT with Knockout is a very attractive idea.

For our own purposes we are considering three options (in "wish list"
order):

1) Waking up to the announcement of KnockoutJs 3.0 using code
generation. At least for "foreach" operations.
2) Rewriting Google MDV using code generation.
3) Rewriting Knockout using code generation.

The reason 2) comes before 3) is not because Google MDV is better (it
is not), but because it uses a clean JSON tree instead of the ko
function wrappers. If you have clean Javascript view models, you can
mix-and-match cool Javascript goodies such as D3.js etc without the
need of integrating the frameworks. Knockout had to give up "clean"
view models as they will only work with never browsers. To notify
observers of model changes, the browser needs to support proxies (i.e.
get/set properties etc.). As compatibility with older browsers was a
design goal, this was not an option (I guess?).

p.s. For those considering Google MDV as a Knockout alternative I
think you should think twice. It is super, super slow and super duper
unstable and is only intended as a "proof-of-concept" prototype.



On Dec 28, 8:28 pm, EntitySpaces <entityspa...@gmail.com> wrote:
> Here are the two links. I'm sorry, I tried to create them in jsFiddle
> but had issues, you can just choose "View Source" in the browser.
>
> The doT template engine, very fast, but when used to as the ko
> template engine makes very little different at allhttp://www.entityspaces.net/Punchout/examples/Non-EntitySpaces/doT_Te...
>
> The ko template engine:http://www.entityspaces.net/Punchout/examples/Non-EntitySpaces/ko_Tem...

Michael Best

unread,
Dec 28, 2011, 3:49:10 PM12/28/11
to KnockoutJS
I updated the fiddle to use the debug version because the minified one
wasn't working:
http://jsfiddle.net/mbest/FgSCw/9/

I posted it mostly to give the idea that Knockout can be made faster
without sacrificing functionality. Please don't use my 'playground'
for any real applications.

-- Michael

On Dec 28, 4:22 am, "Igor Loginov (aka ilog2000)" <ilog2...@gmail.com>
wrote:

Igor Loginov (aka ilog2000)

unread,
Dec 28, 2011, 6:33:14 PM12/28/11
to KnockoutJS
Michael, thank you for this update. Actually I've already got better
understanding from your pull requests on github.

Jack Wester

unread,
Dec 28, 2011, 8:10:24 PM12/28/11
to KnockoutJS
Sounds like a pragmatic approach. Although I would hope to see
Knockout make other DOM templating engines redundant, I do like the
idea of rendering various parts of the view model using the
appropriate tool. For example, D3.js is fantastic at making beautiful
and fast graphical visualizations. Model driven views and data binding
are also ideal for advanced user experiences (even games).

Please let me know about your experiences. I'm curious to learn how
responsive your application turns out to be.

Do you have a lot of data in your forms and data grids?

Jack Wester

unread,
Dec 28, 2011, 8:12:01 PM12/28/11
to KnockoutJS
Nice work. I'll consider disobeing your recommendation ;)
Reply all
Reply to author
Forward
0 new messages