I'm building a data grid with thousands of list items and no pagination. As a result, the performance with live-binding is, understandably, very poor. With ~20 list items, there is no lag whatsoever.
<thead>
{{#each columns}}
<tr><td can-click="sort">{{name}}</td></tr>
{{/each}}
</thead>
<tbody>
{{#each thousandsOfItems}}
<tr><td>{{name}}</td></tr>
{{/each}}
</tbody>
Is there a way for part of my template to be live bound, such as the <thead>, but use simple string concatenation/injection for the <tbody>?
Edit
My approach may be the problem. Thousands of static <tr>s are likely quite laggy too. It's been suggested to me that I try adding/removing rows as the page is scrolled.
I made a JSPerf rendering 4000 rows in a single column table, which you can check out here:
http://jsperf.com/can-stache-table-render
Some takeaways from these experiments:
without live-binding you can get a 10x performance boost. If you need more than that, though, you'll probably have to do perceived performance boosts.
When not live binding any data, there's no performance boost in using {{#each}} versus just {{#thousandsOfRows}}
Using divs instead of table rows was something I was interested in trying since you could conceivably see incremental drawing faster (but really, with all of this running synchronously, the UI will lock until it's all drawn this way), but it's 35% slower to draw the whole table, and probably is best avoided.
So based on this, what can we do?
Page the table, or rather, draw many tables of a fixed size until you run out of data. The first screen will render quickly and the rest will fill in as you go. Make use of setTimeout() to draw the next table, so as to not lock the UI.
Use live-binding, but page it in using a pattern like this:
var i=0;
function loop() {
while(i < source_list.length) {
list_in_live_binding_context.push.apply(
list_in_live_binding_context,
source_list.splice(i, 20)
);
i += 20;
setTimeout(loop, 4);
}
}
Do one of the two previous things, but hide the results behind a screen with a spinner until the rendering is finished
Use jquery-ui-scrollable (https://github.com/bseth99/jquery-ui-scrollable) to detect when elements have been scrolled into view -- use a Stache helper to only render items once they're scrolled in to view, but you'll need to reserve the space first. This can be helpful if each individual row has complex rendering associated with it. You can delay the details until they're necessary.
Sorry it's not a simple answer, but it's not a simple problem. :) HTH, anyway.
Related
In an application I'm developing, i need to use the same space to display information from different sources with different formats in a grid according to what item was selected on a TreeView.
i found two ways to achieve this:
find the grid then destroy and recreate it.
find the grid then change datasoruce/options/
I'm very new to Kendo, so i'm not sure which approach would be wiser.
any advice?
The answer depends on your usage model.
How often are you going to change between datasources?
How long does it take getting the new data?
How much data is involved?
If it takes long time and you can switch quite often between DataSources I would go with a third approach that is having several grids and only one visible BUT if there is a lot of data involved then you should destroy the grid and recreate a new one avoiding having a lot of memory used but having to bring a lot of data back and forth.
You can go with the your second proposal (switching datasources) if you switch data and the structure of the grid is exactly the same (same columns and formatting).
If all your data had the same columns and options, then I would just call .setDataSource() on the grid widget to replace the data source with the new one.
However if you are changing options and columns, I think it would be better to just destroy the widget and re-create it, which would eliminate the possibility of the widget holding on to any of the old options. Something like:
function replaceGrid(selector, options) {
var $grid = $(selector);
var gridWidget = $grid.getKendoGrid();
if(gridWidget) {
gridWidget.destroy();
}
$grid.kendoGrid(options);
}
CSS Selectors are parsed right to left, and then displayed.
With this in mind, based on this code:
<a href="#" class="myImage">
<img>
</a>
Which is more performant?:
.myImage img
or
.myImage img:only-child
Does :only-child help specificity in selector selection? So instead of initially matching all <img> in the document then looking for the parent class, does it only match <img>'s that are the only child (thereby reducing the pool of selections)?
reference read: http://csswizardry.com/2011/09/writing-efficient-css-selectors/
EDIT
Found further reading:
The sad truth about CSS3 selectors is that they really shouldn’t be
used at all if you care about page performance. Decorating your markup
with classes and ids and matching purely on those while avoiding all
uses of sibling, descendant and child selectors will actually make a
page perform significantly better in all browsers.
-David Hyatt (architect for Safari and WebKit, also worked on Mozilla, Camino, and Firefox)
Source: http://www.stevesouders.com/blog/2009/03/10/performance-impact-of-css-selectors/
Alright, so this depends completely on the use case. What I'm going to do is handle cases.
Point 1 - Concerning given example
Case A
Say your code is simply:
<a href="#" class="myImage">
<img>
</a>
In this case .myImage img and .myImage img:only-child will have essentially identical performance hits. Reason being is as follows:
CSS performance hits are derived from having to style or re-style boxes. What CSS does is affect your graphics processor, not the CPU, so we only care about visual updates. And styling things again with duplicate properties DOES cause a redraw (By this I mean duplicate properties that are applied at a later time, which selectors generally cause).
Usually, .myImage img would style ALL <img>s in .myImage. While using the only-child selector may not style all (obviously).
But in this example, both .myImage img and .myImage img:only-child would do identical things, since they would both cause 1 draw/redraw on the same box.
Case B
But suppose we have:
<a href="#" class="myImage">
<img>
<img>
</a>
Here though, we have a different story.
In this example, only-child wouldn't work at all, since <img> is not the only child.
Case C
Finally, suppose you have this, but you only want to style the under the :
<a href="#" class="myImage">
<img>
</a>
<div class="myImage>
<img>
<img>
</div>
In this case, using the only-child selector would be significantly better performance-wise, since you only will style one element, instead of three.
Conclusion and Takeaway
Basically, remember a few things.
CSS selectors help you with writing code because you get to add less IDs and Classes, however, they are almost always less efficient than using all IDs and Classes, because using selectors will causes extra redraws. (Since you'll inevitably style multiple elements with some selector, and then re-style other things with IDs or classes, causing unnecessary redraws)
only-child is NOT faster than .class child if that .class only has one child.
Technically what you are comparing are two completely different things, used for different purposes.
Conclusion
In final answer to your question. In your shown example, neither is more efficient than the other since they cause identical redraws.
However, as
"Does :only-child help specificity in selector selection?"
goes: Yes, that's the point of the selector. See: http://www.w3schools.com/cssref/sel_only-child.asp
Sources:
I am a significant volunteer developer for Mozilla Thunderbird and the Mozilla project and work in the CSS area.
FYI
There are of course weird exceptions to this, but I won't go over them here since I think your exact question doesn't give a brilliant example.
Point 2 - Concerning speed of find selectors
I am purposely trying to drive home the point that it is the drawing the causes the CSS perf hit, not finding the selectors. However, the reason I say this is not because finding selectors takes no time, but instead because it's time is miniscule to the time caused by drawing. That said, if you did have 5,000 <div>s or something, and attempted to style a few using pseudo selectors, it would definitely a little longer than using CSS classes and IDs.
Again though, in your example it would make no difference, since it would look through each element anyway. Why only-child is helpful perf-wise is because it would stop searching for some element after it finds more than one child, whereas simply doing class child would not.
The problem with pseudo selectors is that they usually require a lot of extra searching AND it happens after IDs, classes, and such.
The links you provided are actually very helpful and I'm surprised they didn't answer your question.
One thing I should point out is that many selectors believed to be slow may be vastly improved now. See: http://calendar.perfplanet.com/2011/css-selector-performance-has-changed-for-the-better/
Remember selector performance is only important on very large websites.
Lets say I have an HTML div containing numerous form elements that are all watching model values, if I use ng-show, ng-if, or ng-switch on the div to hide it, will this stop angular JS from doing dirty checking on the form elements and thus improve the performance of my app?
I figure that if the bound elements are not visible then there's no need for angular to be checking the values bound to them.
ng-show and ng-hide will only set a CSS display style, and will still process the bindings. ng-switch, however, will completely comment out the cases that do not apply, which in turn means bindings in those are not processed. I agree, however, with Edmondo1984's reply, that I doubt you should base your choices on this. Do not rewrite your ng-shows as ng-switches because of this!
You can verify this with the Chrome extension Batarang, the performance tab shows which watches are active.
I have an homemade javascript which, among other things, do some kind of text-formatting work in order to emulate a retro text-based game:
When developing it, i tried to stick close to an MVC model, and this is what i did:
The data model basically consists of a list of objects mapping strings to very specific locations in the display, like this
[{
"value":"Hello!",
"color":"blue",
"row":1,
"column":13
},
{
"value":"What is your quest ?",
"color":"red",
"row":5,
"column":10
},
/* ... some other data */]
Then my view consists of a simple <pre> tag. When my controller draws the model on the view, it iterates through each string-location pair and create a <span> for each one that is appended to the <pre> tag. To keep the formatting consistent, it also adds "blanck" span each time it is needed.
<pre>
<span> </span><span class="blue">Hello!</span><span> </span><br>
<!-- ... other lines of the scene-->
</pre>
It's pretty simple, but it worked great until i had to dynamically change a span text value, without redrawing the whole scene each time.
So i took a look on the internet and realized that Ember.js existed, it really seems to be exactly what i could use to improve my whole code.
Now, i tried to redesign it using Ember.js, but as i don't fully understand yet its features i ran into a problem:
How do you represent a 'text-based' view into an Ember.js handlebar template ?
What am i missing here?
My data model contains both the value and the position in the display, so i don't exactly see how handlebars template could fit my needs. Or perhaps dynamically generating the template is an option ?
What do you think ?
Am I choosing the wrong framework or misunderstanding its use? is it my original MVC design that is wrong ? Changing the data model for something completely different is not an option i can easily consider as it would impact everything.
Do you have any ideas on how this could be implemented using Ember or some other framework?
Any advice will be appreciated :)
I made a rudimentary example on jsfiddle on how you could use ember for this.
Each row is an object and we have an ArrayProxy holding such objects. Thus if we have 10 rows, we have 10 row objects.
The view is binding one output line per row object.
Enjoy the flying bird:
http://jsfiddle.net/algesten/YMrW3/2/
Edit: Better to {{#if}} away empty rows as pointed out by ud3323:
http://jsfiddle.net/ud3323/92b24/
I am attempting to make a Facebook game and trying to replicate a common function that I usually find in many other Facebook game (a call to my website and illusionary image that is a loading bar).
The function should do the following:
User clicks on Button
Animated Gif Appears (Loading Bar)
Button Update User's Status
Animated Gif Disappears
Facebook Canvas page is updated
The code I currently have can be found at <dead link>
I am having trouble thinking of Step 2 and 4.
I need to optimize Step 5.
To clarify what happens on Step 5. I have Box 1 which has my stats. And Box 2 which has my points. I click on Box 1. This should update Box 1 with 1 points, and update Box 2; minus a point. (Clicking on Box 1, concurrently update both boxes)
I have successfully done this, but it is quite slow. I was wondering if there are alternative way that may be faster than what I am currently doing.
Script Updated with Mark-up. <dead link>
I've found a quick way to optimize the call. Rather than querying for data that I already have query, I will be using the first query to grab most of my data rather than querying it when I update.
It would help greatly to see the document markup (XHTML) where you have your elements and the calls to your javascript functions.
For steps 2 and 4 I recommend using the visibility attribute rather than display, or having the loading bar in an fb:js-string and using elem.setInnerFbml when you begin loading and once you have your response data, simply update it to the new content (you don't need an explicit loading_finish function in this case).
In your get_skillpoint function, you set parameters in an object and then you specify the action parameter again in the URL you are posting to as a URL query param - you may end up with one value overwriting the other, depending on how you access these values on the server side. I would recommend using different names for these two parameters if they are not the same. Also, why are you trying to send separate GET and POST variable sets? You should put everything in the POST and simply leave out the URL query string. I vaguely remember losing data that way in the past (vaguely, mind you).
If you can post your markup I'll update my answer with any light it sheds on the problem. It might be slow simply because Facebook isn't blinding fast when it comes to FBJS and AJAX. Also, FBML being returned must be preprocessed in the FB proxy before your app gets it, which adds a bit of lag; it's a bit faster to return JSON and just pull the data needed out of it, then place the appropriate pieces into an existing element or make use of fb:js-string.