Is it possible to make this script more efficient? - javascript

I have just finished my script, using flot and jquery. Now to my question, it is fast in opera and Firefox, but it is painfully slow in internet explorer (no surprise), so thats why I wonder if there is a way to make my script more efficient (In other words perhaps remove some of the "for loops" etc)? So if there are any code gurus out there who have some spare time to kill, please help me out, because I myself am terrible at writing efficient code :P
Thanks so much in advance =)
It can be found
on this address

A few more tips:
It was pointed out that:
... $(this).attr('id');
... $(this).attr('name');
is expensive, you don't need $ here at all, just use:
... this.id;
... this.name;
Also, using .css(...) is a huge waste, use a class and put the CSS in an style element.
You can store references like $('#x') in closures. Again, you don't need $, it's far more efficient to get a reference directly to the element using document.getElementByid so that rather than:
$('#x').text(pos.x.toFixed(2));
you can have:
x.innerHTML = pos.x.toFixed(2);
which replaces several function calls with a single property access. The basic idea is to remove as much jQuery as you can, keep references to things rather than getting them frequently and use direct property access, not functions.
Incidentally, when I try to copy from the jsFiddle javascript region, Safari freezes. I'm not a big fan of that site.

for(k; k<datasets.length; k++){
Every time the loop is executed next, you are calling the length property, it's better if you store it in a variable at the start of the loop only, like this:
for(var k, len = datasets.length; k < len; k++){
Also here you are wasting resources:
key = $(this).attr("id");
subsystem = $(this).attr("name");
just stich $(this) into a variable, cause every time you use $() a clone of the passed element is created. Just do like this:
var $this = $(this);
And use $this from there on instead of $(this), only reuse $(this) when this become a different object.

Firstly, with jQuery selectors, if using a classname, it's more efficient if you can make that more specific. e.g instead of
var checkboxContainerFailed = $(".failedCheckboxes");
try
var checkboxContainerFailed = $("#graph-table-bottom td.failedCheckboxes");
Secondly, it's generally considered better to use [] notation instead of var subsystemNames = new Array();
Thirdly, you have a trailing comma in the data array here. This might cause IE problems:
"test2-a4/",
]
Finally, try running the whole thing through JSLint for any errors.

Related

DRY attribute selection

Say I have an element on the page:
<div data-name='foo'>
What's the best way to get the attribute value? Is there anything more DRY than $('[data-name]').attr('data-name') or $('[data-name]').data('name')?
I don't know how do you define "DRY"...
if (x < 0) x = 1 isn't "DRY" because you wrote x twice?
Anyway with the current DOM structure, no there is not. The selector is inefficient which is more important!
You can give the element an id, which make the code faster.
<div id='foo' data-name='foo'> </div>
...
$('#foo').data('name'); // That's more like it.
I wouldn't know what this has to do with 'Don't Repeat Yourself', but if you don't have a cached reference to this node you would have to use that, rather verbose, call.
It might be a good idea to have at least an id for the nodes. The DOM query for that is lighting fast in comparison to that attribute-selector. But afterall, it's still the fastest technique to store a reference in a variable, like
var myNode = $('[data-name]');
and then use that variable throughout your whole application
myNode.data( 'name' );
You could have a plugin that did something like this. I'm not sure the additional overhead is worth it, though.
function getData(varName) {
var selector = '[data-' + varName + ']';
return $(selector).data(varName);
}
(not tested)
Without a tag qualifier (e.g. div[data-name]) your selector will be very inefficient as it will have to traverse the entire DOM to check for matching elements.
It would be much preferable to identify a specific ID (or even a class) to help out the selector engine and restrict how much of the DOM has to be searched.
As long as you don't repeat that everywhere, (i.e cache the result), I don't really see how you can get anything more DRY.
var name = $('[data-name]').data('name');
You're technically not repeating yourself yet.

jQuery(#id).val() vs. getElementById(#id).value

I been searching but I can only find articles talking about one or the other. Which one is better?
I'm making a small web app where performance is not a big concern since there's nothing complex going on.
I considered using jQuery's val() function since maybe it solves some inconsistency I'm not aware of, but getElementById.value IS faster (although the end user won't notice.)
So which one should I use? Is jQuery's non-native method worth the lower performance to gain more compatibility?
The biggest advantage of using jQuery().val() over document.getElementById().value is that the former will not throw an error if no elements are matched, where-as the latter will. document.getElementById() returns null if no elements are matched, where-as jQuery() returns an empty jQuery object, which still supports all methods (but val() will return undefined).
There is no inconsistency when using .value for form elements. However, jQuery.val() standardises the interface for collecting the selected value in select boxes; where as in standard HTML you have to resort to using .options[this.selectedIndex].value.
If you're using <select> elements as well, .value won't work whereas .val() will.
I would not mind about performance of just getting a value. If you want the best performance, perhaps you shouldn't use a library at all.
jQuery does so many nice little error handling things (look below) that I would never write a line of javascript without jquery in a browser again.
First, val works on checkbox groups, selects, gets html, and the
like.
Second, $ lets you use sizzle selectors, so in the future, you can
easily switch between an ID and a CSS path.
Third, your code will be so much easier to read and maintain if you
just use jQuery, that the time you save maintaining your code
outweighs any speedup that you admit your users won't see. Finally,
jQuery is a very popular, very widely used library. They will make
$ and val as fast as they can.
I think using pure Javascript is quicker for the following reasons:
You won't have to learn more than pure js
If you don't want errors, use catch(exeption) (I think...)
You don't have to put in that little extra time to type in the code to initiate jquery
The browser responds quicker if you don't use jquery
Normal js works (in a better way) on checkboxes #johndodo
Thank you for listening to my answer.
I've been looking into the performance differences with this recently and, slightly unsurprisingly, using vanilla JS to grab a value is faster than using jQuery. However, the fallbacks that jQuery provides to prevent errors, like what #Matt mentioned, is very useful. Therefore, I tend to opt for the best of both worlds.
var $this = $(this),
$val = this.value || $this.val();
With that conditional statement, if this.value tries to throw an error, the code falls back to the jQuery .val() method.
Here https://www.dyn-web.com/tutorials/forms/checkbox/same-name-group.php is an implementation for checkboxes, apparently options just need to be named the same with the array brackets notation in the name i.e.: name="sport[]" then yu get the array inJavascript via: var sports = document.forms['demoForm'].elements['sport[]']
I was looking for a selection type field solution without using jQuery and I came across this solution:
The Selection group is an object: HTMLCollection, and it has a lenght method and a selectedOptions property, which allows you to iterate through its label properties to populate an Array with the selected options, which then you can use:
...
vehicleCol = document.getElementById('vehiculo').selectedOptions;
vehiculos = [];
if (vehicleCol !== undefined) {
for (let i = 0; i < vehicleCol.length; i++) {
vehiculos.push(vehicleCol[i].label.toLowerCase())
}
}
...
I'd use jQuery's val(). Shorter code means faster download time (in my opinion).

jquery: context with closures?

I got a simple question about jQuery but rather javascript approaches in general...
Is it ok, to do this? :
this._checkedTexts.length = 0; // <- array belonging to "me"
var contextCheckedTexts = this._checkedTexts;
$('#valueContainer input:checked').each(function() {
contextCheckedTexts.push($(this).text());
});
Since 'this' points to the element, I am using a closure here to keep additional context for the 'each'-handler around.
Is this the way 'how it's done' or could there be any risk involved using a closure in this way (memoryleak-wise....)?
What other options are there?
I find it very practical - but also I'm always a little worried about introducing reference-count-problems when using closures - which will be hard to find later on.
I don't know what you are trying to achieve but your codes may also be done like this,
this._checkedTexts.length = 0; // <- array belonging to "me"
var arr = $('#valueContainer input:checked').map(function() {
return $(this).text();
}).get();
this._checkedTexts = this._checkedTexts.concat(arr);
It seems to be fine as jQuery methods like each, map, grep does not support context by default (there're bound to the current jQuery object). However you can create you own bind function that will apply context to functions (but in this case you dontn't have to as you use default context to get the elements text).

jQuery pitfalls to avoid [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
I am starting a project with jQuery.
What pitfalls/errors/misconceptions/abuses/misuses did you have in your jQuery project?
Being unaware of the performance hit and overusing selectors instead of assigning them to local variables. For example:-
$('#button').click(function() {
$('#label').method();
$('#label').method2();
$('#label').css('background-color', 'red');
});
Rather than:-
$('#button').click(function() {
var $label = $('#label');
$label.method();
$label.method2();
$label.css('background-color', 'red');
});
Or even better with chaining:-
$('#button').click(function() {
$("#label").method().method2().css("background-color", "red");
});
I found this the enlightening moment when I realized how the call stacks work.
Edit: incorporated suggestions in comments.
Understand how to use context. Normally, a jQuery selector will search the whole doc:
// This will search whole doc for elements with class myClass
$('.myClass');
But you can speed things up by searching within a context:
var ct = $('#myContainer');
// This will search for elements with class myClass within the myContainer child elements
$('.myClass', ct);
Don't use bare class selectors, like this:
$('.button').click(function() { /* do something */ });
This will end up looking at every single element to see if it has a class of "button".
Instead, you can help it out, like:
$('span.button').click(function() { /* do something */ });
$('#userform .button').click(function() { /* do something */ });
I learned this last year from Rebecca Murphy's blog
Update - This answer was given over 2 years ago and is not correct for the current version of jQuery.
One of the comments includes a test to prove this.
There is also an updated version of the test that includes the version of jQuery at the time of this answer.
Try to split out anonymous functions so you can reuse them.
//Avoid
$('#div').click( function(){
//do something
});
//Do do
function divClickFn (){
//do something
}
$('#div').click( divClickFn );
Avoid abusing document ready.
Keep the document ready for initialize code only.
Always extract functions outside of the doc ready so they can be reused.
I have seen hundreds of lines of code inside the doc ready statement. Ugly, unreadable and impossible to maintain.
While using $.ajax function for Ajax requests to server, you should avoid using the complete event to process response data. It will fire whether the request was successful or not.
Rather than complete, use success.
See Ajax Events in the docs.
"Chaining" Animation-events with Callbacks.
Suppose you wanted to animate a paragraph vanishing upon clicking it. You also wanted to remove the element from the DOM afterwards. You may think you can simply chain the methods:
$("p").click(function(e) {
$(this).fadeOut("slow").remove();
});
In this example, .remove() will be called before .fadeOut() has completed, destroying your gradual-fading effect, and simply making the element vanish instantly. Instead, when you want to fire a command only upon finishing the previous, use the callback's:
$("p").click(function(e){
$(this).fadeOut("slow", function(){
$(this).remove();
});
});
The second parameter of .fadeOut() is an anonymous function that will run once the .fadeOut() animation has completed. This makes for a gradual fading, and a subsequent removal of the element.
If you bind() the same event multiple times it will fire multiple times . I usually always go unbind('click').bind('click') just to be safe
Don't abuse plug-ins.
Most of the times you'll only need the library and maybe the user interface. If you keep it simple your code will be maintainable in the long run. Not all plug-ins are supported and maintained, actually most are not. If you can mimic the functionality using core elements I strongly recommend it.
Plug-ins are easy to insert in your code, save you some time, but when you'll need an extra something, it is a bad idea to modify them, as you lose the possible updates. The time you save at the start you'll loose later on changing deprecated plug-ins.
Choose the plug-ins you use wisely.
Apart from library and user interface, I constantly use $.cookie , $.form, $.validate and thickbox. For the rest I mostly develop my own plug-ins.
Pitfall: Using loops instead of selectors.
If you find yourself reaching for the jQuery '.each' method to iterate over DOM elements, ask yourself if can use a selector to get the elements instead.
More information on jQuery selectors:
http://docs.jquery.com/Selectors
Pitfall: NOT using a tool like Firebug
Firebug was practically made for this kind of debugging. If you're going to be mucking about in the DOM with Javascript, you need a good tool like Firebug to give you visibility.
More information on Firebug:
http://getfirebug.com/
Other great ideas are in this episode of the Polymorphic Podcast:
(jQuery Secrets with Dave Ward)
http://polymorphicpodcast.com/shows/jquery/
Misunderstanding of using this identifier in the right context. For instance:
$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
$(".listOfElements").each( function()
{
$(this).someMethod( ); // here 'this' is not referring first_element anymore.
})
});
And here one of the samples how you can solve it:
$( "#first_element").click( function( event)
{
$(this).method( ); //referring to first_element
var $that = this;
$(".listOfElements").each( function()
{
$that.someMethod( ); // here 'that' is referring to first_element still.
})
});
Avoid searching through the entire DOM several times. This is something that really can delay your script.
Bad:
$(".aclass").this();
$(".aclass").that();
...
Good:
$(".aclass").this().that();
Bad:
$("#form .text").this();
$("#form .int").that();
$("#form .choice").method();
Good:
$("#form")
.find(".text").this().end()
.find(".int").that().end()
.find(".choice").method();
Always cache $(this) to a meaningful variable
especially in a .each()
Like this
$(selector).each(function () {
var eachOf_X_loop = $(this);
})
Similar to what Repo Man said, but not quite.
When developing ASP.NET winforms, I often do
$('<%= Label1.ClientID %>');
forgetting the # sign. The correct form is
$('#<%= Label1.ClientID %>');
Events
$("selector").html($("another-selector").html());
doesn't clone any of the events - you have to rebind them all.
As per JP's comment - clone() does rebind the events if you pass true.
Avoid multiple creation of the same jQuery objects
//Avoid
function someFunc(){
$(this).fadeIn();
$(this).fadeIn();
}
//Cache the obj
function someFunc(){
var $this = $(this).fadeIn();
$this.fadeIn();
}
I say this for JavaScript as well, but jQuery, JavaScript should NEVER replace CSS.
Also, make sure the site is usable for someone with JavaScript turned off (not as relevant today as back in the day, but always nice to have a fully usable site).
Making too many DOM manipulations. While the .html(), .append(), .prepend(), etc. methods are great, due to the way browsers render and re-render pages, using them too often will cause slowdowns. It's often better to create the html as a string, and to include it into the DOM once, rather than changing the DOM multiple times.
Instead of:
var $parent = $('#parent');
var iterations = 10;
for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$parent.append($div);
}
Try this:
var $parent = $('#parent');
var iterations = 10;
var html = '';
for (var i = 0; i < iterations; i++){
html += '<div class="foo-' + i + '"></div>';
}
$parent.append(html);
Or even this ($wrapper is a newly created element that hasn't been injected to the DOM yet. Appending nodes to this wrapper div does not cause slowdowns, and at the end we append $wrapper to $parent, using only one DOM manipulation):
var $parent = $('#parent');
var $wrapper = $('<div class="wrapper" />');
var iterations = 10;
for (var i = 0; i < iterations; i++){
var $div = $('<div class="foo-' + i + '" />');
$wrapper.append($div);
}
$parent.append($wrapper);
Using ClientID to get the "real" id of the control in ASP.NET projects.
jQuery('#<%=myLabel.ClientID%>');
Also, if you are using jQuery inside SharePoint you must call jQuery.noConflict().
Passing IDs instead of jQuery objects to functions:
myFunc = function(id) { // wrong!
var selector = $("#" + id);
selector.doStuff();
}
myFunc("someId");
Passing a wrapped set is far more flexible:
myFunc = function(elements) {
elements.doStuff();
}
myFunc($("#someId")); // or myFunc($(".someClass")); etc.
Excessive use of chaining.
See this:
this.buttonNext[n ? 'bind' : 'unbind'](this.options.buttonNextEvent, this.funcNext)[n ? 'removeClass' : 'addClass'](this.className('jcarousel-next-disabled')).attr('disabled', n ? false : true);
Explanation
Use strings accumulator-style
Using + operator a new string is created in memory and the concatenated value is assigned to it. Only after this the result is assigned to a variable.
To avoid the intermediate variable for concatenation result, you can directly assign the result using += operator.
Slow:
a += 'x' + 'y';
Faster:
a += 'x';
a += 'y';
Primitive operations can be faster than function calls
Consider using alternative primitive operation over function calls in performance critical loops and functions.
Slow:
var min = Math.min(a, b);
arr.push(val);
Faster:
var min = a < b ? a : b;
arr[arr.length] = val;
Read More at JavaScript Performance Best Practices
If you want users to see html entities in their browser, use 'html' instead of 'text' to inject a Unicode string, like:
$('p').html("Your Unicode string")
my two cents)
Usually, working with jquery means you don't have to worry about DOM elements actual all the time. You can write something like this - $('div.mine').addClass('someClass').bind('click', function(){alert('lalala')}) - and this code will execute without throwing any errors.
In some cases this is useful, in some cases - not at all, but it is a fact that jquery tends to be, well, empty-matches-friendly. Yet, replaceWith will throw an error if one tries to use it with an element which doesn't belong to the document. I find it rather counter-intuitive.
Another pitfall is, in my opinion, the order of nodes returned by prevAll() method - $('<div><span class="A"/><span class="B"/><span class="C"/><span class="D"/></div>').find('span:last-child').prevAll(). Not a big deal, actually, but we should keep in mind this fact.
If you plan to Ajax in lots of data, like say, 1500 rows of a table with 20 columns, then don't even think of using jQuery to insert that data into your HTML. Use plain JavaScript. jQuery will be too slow on slower machines.
Also, half the time jQuery will do things that will cause it to be slower, like trying to parse script tags in the incoming HTML, and deal with browser quirks. If you want fast insertion speed, stick with plain JavaScript.
Using jQuery in a small project that can be completed with just a couple of lines of ordinary JavaScript.
Not understanding event binding. JavaScript and jQuery work differently.
By popular demand, an example:
In jQuery:
$("#someLink").click(function(){//do something});
Without jQuery:
<a id="someLink" href="page.html" onClick="SomeClickFunction(this)">Link</a>
<script type="text/javascript">
SomeClickFunction(item){
//do something
}
</script>
Basically the hooks required for JavaScript are no longer necessary. I.e. use inline markup (onClick, etc) because you can simply use the ID's and classes that a developer would normally leverage for CSS purposes.

Performance: Which of these examples of code is faster and why?

$('#element').method();
or
var element = $('#element');
element.method();
Without using a profiler, everyone is just guessing. I would suspect that the difference is so small it isn't worth worrying about. There are small costs to the second above the first like having to preform a lookup to find 'var element' to call the method on, but I would have thought finding '#element' and then calling the method is far more expensive.
However, if you then went on to do something else with element, the second would be faster
//Bad:
$('#element').foo();
$('#element').bar();
//Good:
var e = $('#element');
e.foo();
e.bar();
If you were using a loop where the value of $('#element') was used a lot, then caching it as in the 2nd version before the loop would help a lot.
For just this small snippet, it makes little difference.
Lookups via id (#) are pretty fast. I just tested your scenario on a small page with 2 div tags. Here is the code i used
var x = $("#div1");
var y = $("#div2");
var z = $("#div1");
every lookup took about 0.3ms on my laptop. The 2nd lookup for div1 executed the same internal jQuery methods as the first - indicating that there is no caching of already looked up objects
Performance becomes a bigger problem when you use other selectors like classname or more advanced jQuery selectors. I did some analysis on jQuery Selector Performance - check it out - hope it is helpful.
If you run only this code, no one should realy be faster. The second one might need more memory (because of the additional variable created).
If you want to be sure, why not test it yourself using a small selfwritten benchmark?
I think $('#element').method(); does not need as much memory as
var element = $('#element');
... because you bind #element to a variable.
Juste fore funne
\Indifferent:
$('#element').foo().bar();

Categories

Resources