Solutions to knockoutjs excessive memory usage

2,019 views
Skip to first unread message

kevin...@gmail.com

unread,
Jul 14, 2012, 12:26:06 AM7/14/12
to knock...@googlegroups.com
I honestly don't know if this is the right place to put this, but after much searching, head banging, and thinking I found a solution to a problem which came up when I started using knockout and I would like to share it somewhere so I can perhaps save someone a little time.

I was tasked by my boss to try out a few javascript frameworks since our projects were getting more and more complex and the javascript was becoming unmanageably huge for some projects. During this process I discovered knockout and its pretty much changed the entire way I think about javascript and coding web applications. However, I ran into a problem when I started using very large datasets: my memory usage per page would be absolutely horrendous. The documentation and tutorials on the knockoutjs website don't cover in huge depth ajax saving and such and along with my naivety in relation to things javascript and memory usage I ended up being totally stumped when I spied my page running at 800Mb with a thousand or so elements being displayed (no images). Google was no help since I didn't even know what my problem was (I thought it was memory leaks due to circular references between page elements and javascript objects, but using the 'if' binding to actually remove the elements to break the cycle didn't fix anything) and so after thinking about it for a couple months, over the past few days I have finally figured out that the problem was in how I structured my model.

I've written a post about how to solve knockout memory problems when loading large datasets and how not to structure a knockout-based ajax application. It is here: http://cuznersoft.com/wordpress/?p=208

Does anyone have any thoughts, feedback, or insights on the topic of knockout memory usage? Maybe things I should add to my post? Mistakes and incorrect assumptions I have made?

Thanks.

Dawid Ciecierski

unread,
Jul 17, 2012, 9:51:56 AM7/17/12
to knock...@googlegroups.com
Thanks for sharing this, and indeed it seems that in the case of many objects being created / in memory, creating functions on them as instances could blow up your memory usage quite a bit.

While your solution of moving the related behaviour to your view model certainly would (and hope does) work, I personally find it a bit of a code smell. I feel that behaviour should be encapsulated by particular models as much as it makes sense, and with your strategy it gets spilled into your parent view model who shouldn't necessarily be concerned with details of its children's behaviours.

An alternative solution would be to fiddle with function prototypes, but I personally haven't done much in that space so unable to give any concrete examples on how this would be done.

But anyway - nice that you bring it up, we recently came across a similar issue mapping ~2k objects with ko.mapping and had to backpedal to using an observable array of plain old javascript objects to make it usable (mapping took ~40-60s on a modern PC!). Would be interested to check out how much of this time could be saved with strategies such as the one you proposed.

Regards,
Dawid Ciecierski

TonyB

unread,
Jul 17, 2012, 1:07:31 PM7/17/12
to knock...@googlegroups.com
I've been using a pattern I got from here for managing lists in Knockout. https://github.com/SteveSanderson/knockout/wiki/View-Add-Edit-Delete-Design-Pattern

It appears very similar (if not identical to yours), although Steve's post is not the most readable, and covers a lot more than just the pattern you describe. 

So for me, your post gets a big thumbs up - I find this approach clean, and performant.

szabolc...@gmail.com

unread,
Jul 18, 2012, 5:41:11 AM7/18/12
to knock...@googlegroups.com
Dear "unknown" - either your wordpress install sucks or I failed on at least ten captchas; so, eventually, here's my comment:

Thank you for the article, in my opinion knockout propagates bad coding practice (for javascript at least) - the whole "everything is a constructor" pattern is pretty flawed and requires way too much carefulness in terms of memory consumption (and inheritance is quite sucky compared even to prototypic declarations or plain old extends). Since you're using Wordpress I recommend you copy the code (before inserting it) into a jsfiddle (jsfiddle.com) and copy it from there, the style will be copied via contenteditable.



On Saturday, July 14, 2012 6:26:06 AM UTC+2, (unknown) wrote:

Kevin Cuzner

unread,
Jul 22, 2012, 9:56:24 PM7/22/12
to knock...@googlegroups.com, kevin...@gmail.com
Sorry my blog wasn't working right. It should be fixed now...I guess having spam free wordpress and wprecaptha installed cause some issues.

Thanks everyone for the feedback! I hadn't checked back here in a little while, so sorry for the 5 day response wait.

After taking a brief look at doing object prototyping with Javascript (I have never messed with it before except to extend the built in objects (like adding trim() to the string object in IE, etc) I am starting to think that doing it that way may allow me to put functions in the child container objects while not having to essentially store a copy of the function in every single object. In one application I am developing, it would really start to clutter up the root object if I were to re-write it moving all the child methods down to the root model. Would I be correct in assuming that each object would share the same function if I were to use prototypes rather than using the "everything in constructor/every object gets a copy of the function" method for putting functions in objects? That would end up with the same effect I was going for by moving everything down to the root and so I think I'll mess around with it a bit in the coming days.

szabolc...@gmail.com

unread,
Jul 23, 2012, 2:29:34 AM7/23/12
to knock...@googlegroups.com, kevin...@gmail.com
Oh yes, they would, but the constant binding (or $.proxy-ing) will make you mad - also note that the observable wrappers will always mean a certain overhead and their creation will have to be placed into the constructor. It's not what you want, but be sure to read Resig's post on parent/super inheritance pattern, it will help you understand prototypic glue somewhat better.

sz

bogi...@gmail.com

unread,
Jul 24, 2012, 9:16:00 AM7/24/12
to knock...@googlegroups.com
I think the key to keeping everything managable, while using knockout and mapping, is to use the the copy option in mapping..

var mappingReportFields = {
      'copy': ["ReportField"] }

The copy option allows you to use the mapping plugin, to create your base model. but not make everythign observable, which is what adds the huge amounts of overhead.
Reply all
Reply to author
Forward
0 new messages