Performance Issues with rendering table

58 views
Skip to first unread message

Donny Velazquez

unread,
Sep 21, 2016, 2:54:55 PM9/21/16
to Ractive.js
So I'm noticing some weird performance issues. This only has 171 records but takes 4 sec to render.
It does have 90 fields but I wouldn't think it would be enough to slow down RactiveJS.

If you look at the console it will give you the render times. Line 789 is where the data gets set() happens.

Anyone see something I'm doing wrong? 

Thanks

Donny Velazquez

unread,
Sep 21, 2016, 3:54:15 PM9/21/16
to Ractive.js
Actually its line 799 is where the data is getting set.

(I can't believe you can't edit a google group post?)

Chris Reeves

unread,
Sep 21, 2016, 4:20:14 PM9/21/16
to Donny Velazquez, Ractive.js
A quick profile shows a good bit of time in two places: resolving references and something in jquery. I can't say much to the jquery part, since it's minified and a bit out of scope for ractive-related slowness, but the resolving references can probably be sped up a fair amount by avoiding ambiguity e.g. using relative or absolute references where the reference is not in the immediate context. For example `{{#each foo}}{{#each bar}}{{baz}} {{bat}}{{/each}}{{/each}}` where every foo has a bar and baz and the bars have a bat would be faster as `{{#each foo}}{{#each bar}}{{../../baz}} {{bat}}{{/each}}`. There's even more benefit to that if you're iterating unrelated structures and using references to data elsewhere e.g. with `data: { rows: { ...data... }, columns: { ...column defs... } }` `{{#each rows:r}}<tr>{{#each columns:c}}<td>{{rows[r][.name]}}</td>{{/each}}</tr>{{/each}}` would be faster with a root reference `~/rows[r][.name]`.The speed difference grows greater with each layer of context.

0.7.3, while quicker than previous versions, is not exactly a speed demon when it comes to large dom structures. edge, which will be 0.8 soon, is much better in these scenarios and it has some extra helpers to make removing ambiguity a good deal easier with aliases e.g. `{{#each rows as row}}{{#each ~/columns as col}}{{row[col.name]}}{{/each}}{{/each}}`. Overall, it looks like 0.8 will render big funky dom 25-50% faster than 0.7.3.

And yeah, you can't edit a post, because, while Google presents them as forums, groups are more like a mailing list and you can't edit email once it's sent. :)


Thanks, Chris

On Wed, Sep 21, 2016 at 3:54 PM, Donny Velazquez <don...@gmail.com> wrote:
Actually its line 799 is where the data is getting set.

(I can't believe you can't edit a google group post?)

--
You received this message because you are subscribed to the Google Groups "Ractive.js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Donny Velazquez

unread,
Sep 22, 2016, 9:59:05 AM9/22/16
to Ractive.js, don...@gmail.com
So I changed the template to use root so it wouldn't need to resolve anything but its still takes 4sec. 
It doesn't look like it made any difference. Am I doing something wrong?

<script id="DynamicTableTemplate" type="text/ractive">
   
<div class="dt-headers">
       
<table class="table dt-header-data">
           
<thead>
               
<tr>
                   
{{#each ~/fieldData : i}}
                    <th>{{~/
fieldData[i].name}}</th>
                   
{{/each}}
               
</tr>
            </
thead>
       
</table>
    </
div>
   
<div class="dt-rows" style="position: relative;">
       
<table style="position: absolute; top: {{~/table_top}}px; left: 0px;" class="table table-condensed table-hover dt-row-data">
           
<tbody>
               
<tr class="dt-row-fields">
                   
{{#each ~/fieldData}}
                    <td></
td>
                   
{{/each}}
               
</tr>
                {{#each ~/
rowData : i}}
               
<tr on-click="on-row-select"> @*class="{{row_style(~/rowData[i])}}" style="{{inline_row_style(~/rowData[i])}}"*@
                   
{{#each ~/rowData[i].row : j}}
                    <td style="height:{{~/
row_height}}px;">{{~/rowData[i].row[j]}}</td>
                   
{{/each}}
               
</tr>
                {{/
each}}
           
</tbody>
        </
table>
       
<div style="position: relative; top: 0px; left: 0px; width: 1px; height: {{~/scroll_height}}px;"></div>
   
</div>
</script>


Thanks, Chris

To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+...@googlegroups.com.

Chris Reeves

unread,
Sep 22, 2016, 2:39:24 PM9/22/16
to Donny Velazquez, Ractive.js
That cut roughly a second off for me. It now loads in 2 - 2.5s vs 3 - 3.5s. Roughly 50% of that time is spent in sizing outside of Ractive.

There is a bunch of data here: 171 rows with 90 cols is roughly equivalent to 1500 rows with 10 cols and taking about a second to render tracks with my experience on 0.7.3. edge is a good bit faster.

Aside from optimizing the resize and/or migrating to edge, nothing else really jumps out at me as something you can do to speed up significantly. Unfortunately, initial render of lots of DOM is one of Ractive's weaker points right now. If performance is critical, I would go with a grouping via tree-table, cutting (way) down on the number of columns initially shown to have a more digestible view (master-detail), or perhaps lazy-rendering the data after the first screen full using a scroll listener. For that last one, you could compute offsets for the first chunk of data and have the styles applied by Ractive as a calculation for the viewport size, row heights, and column widths.

I know there are a few devs that have used Ractive to do similar, though probably not as wide, grids, and they may be able to provide some more useful suggestions.


Thanks, Chris

To unsubscribe from this group and stop receiving emails from it, send an email to ractive-js+unsubscribe@googlegroups.com.

Donny Velazquez

unread,
Sep 23, 2016, 9:01:38 AM9/23/16
to Ractive.js, don...@gmail.com
It looks like in the Chrome Profile tool that a whole 1 sec is being used up with resizing the widths of the columns.
That causes a repaint of the entire table. I'm going to try to do this but with only 1 record. Get the widths and then render the entire
table. That should hopefully speed things up.

Actually if you look in the javascript code this is a widget to handle virtual scrolling of unlimited records. So its already chunking the data and only showing
what's visible with a little bit of buffer above and below. I think its the columns that are slowing it down though on the ractivejs side.
A possible fix could be like the rows, only showing whats visible, so only showing what columns are visible.  

Thanks for all your help.

Marty Nelson

unread,
Sep 23, 2016, 9:21:02 AM9/23/16
to Ractive.js, don...@gmail.com
I also noticed the reflow thrashing when I profiled. Could you initially set the table to display: none and then change in onrender? Idea would be to allow Ractive to create all the DOM before browser tries to paint.
Reply all
Reply to author
Forward
0 new messages