3

I use knockout foreach binding to populate UL. After every scroll to the end I fetch next 25 items and add it to the UL. Everything works really fast in Chrome (The best) and Firefox (little slower), but IE 10 takes around 8 times more to display same data as Chrome. To display all data with all bindings Chrome needs around 50ms. IE takes almost 400.

Is there any way to speed up IE rendering? Is there some way to manually insert items and apply binding if it will make it faster.

I do know that I will not remove any element from the list. I can only replace the whole list. Is there some way to use that as an advantage?

This is binding

  <ul class="items-list"
            data-bind="foreach: items>
 <li>
  ....
 </li>
 </ul>

And I add items with this

self.items.push.apply(self.items, newItems); --items are observableArray
Marka
  • 377
  • 1
  • 4
  • 17
  • I don't know the details but I have a feeling that when rendered in IE, it is rerendering the entire array of items, rather than just the newly added items. IIRC, a lot of workaround had to be made to get it to work in IE. – Jeff Mercado Jun 27 '13 at 16:14
  • @JeffMercado I'm still new to whole web development, but one would expect that at least the latest version of IE would work fine – Marka Jun 27 '13 at 16:42
  • Maybe put something in jsFiddle, if you can. – RP Niemeyer Jun 27 '13 at 16:43
  • Code is so big that i don't know what to extract. Anyway, even when I remove every binding from elements within li IE render it after 40-50ms. Chrome needs 5ms at best. And what's even worse, when he's adding items UL is frozen. I can't scroll while it's rendering. I couldn't reproduce same behaviour in Chrome or Firefox. – Marka Jun 27 '13 at 16:50
  • Have you tried loading them upfront and have the visible binding set to false until you reach a certain point on the page to reveal them? The bindings should be intact and loading 'in the background' and changing visibility should just display them. – PW Kad Jun 27 '13 at 16:54
  • @kadumel This was my idea also. But, problem is 'foreach'. Even when I have visibility set, knockout still has to create all dom elements and apply all bindings. Is there a way to define bindings on dom elements afterwards? – Marka Jun 27 '13 at 20:18
  • Just try to be creative with it - load the first 25 items and then when dom is ready begin pushing the rest into the observableArray in the background with a visibility toggle set to false if you can. That is my best guess without testing it out – PW Kad Jun 27 '13 at 20:38

1 Answers1

4

One thing that will give you a boost in Chrome and IE is to strip the text nodes around your "template". So, rather than:

<ul data-bind="foreach: items">
    <li data-bind="text: name"></li>
</ul>

Do:

<ul data-bind="foreach: items"><li data-bind="text: name"></li></ul>

The important part is the top-level nodes rather than anything inside the children. Now the li is the only node rather that it and two text nodes. This will allow KO to do less work when processing the "template".

RP Niemeyer
  • 114,592
  • 18
  • 291
  • 211
  • Great tip Ryan. I'll try it. – Marka Jun 27 '13 at 20:25
  • Any idea of the % of difference this makes? Obviously it makes code much less readable but if there is a sizable difference it may be worth it... – PW Kad Jun 27 '13 at 20:34
  • For a while Chrome had issues with processing text nodes and this had a huge effect (Chrome seems to be better now). In a basic sample (non-complex markup, just an `li` with one binding), this dropped the time for me by 40%. I was using this fiddle: http://jsfiddle.net/rniemeyer/ExR9v/ – RP Niemeyer Jun 27 '13 at 21:02
  • Ryan, it seems it works much faster now. I'll measure time tomorrow and report my findings – Marka Jun 27 '13 at 21:46