What is the most common waste of computing power in Javascript? - javascript

We've all seen people who do this:
jQuery('a').each(function(){
jQuery(this)[0].innerHTML += ' proccessed';
});
function letsPoluteNS() {
polute = '';
for (morePolution = 0; morePolution < arguments.length; morePolution++)
polute.join(arguments[morePolution]);
return polute;
}
and so on. I was wondering what people have seen the most common JavaScript/jQuery technique that is slowing down the page and/or wasting time for the JavaScript engine.
I know that this question may not seem to fit into what's an accepted question, yet I'm asking "what is the most common accepted waste?"

I'm guilt of this. Basically using only the element's class in a jQuery selector. Instead of combining the class selector with the elements tag name.
<div></div>
<div class="hide"></div>
<div class="show"></div>
<div class="hide"></div>
<div class="hide again"></div>
$(".hide").hide();
Instead of the quicker
$("div.hide").hide()
Also this is inefficient, many people don't make use of the context parameter for selectors
$( selector, [ context ] )
$("#mydiv").click(function () {
$("#mydiv span").show();
}
Which can be handled better like this:
$("#mydiv").click(function () {
$("span", this).show();
}

You'll also see this:
$('#this').find('a').doSomeThing();
Know what's a lot more efficient? One selector that covers both will server you better...
$('#this a').doSomeThing();
It seems obvious, but you'll see it all the time.

Anything that has do to with tracking users and heavy publicity. Thats wasted space for sure.
I guess wrong use of stuff like using classes instead ids as selector in very complex html would slow thing down.
And ie of course.

Calling $.animate to animate elements should make the things slow down.

not declaring your vars from the getgo so they are cached, not using closures and repeating x number of the same function/call/etc but only changing id or class for each, using eval().

Related

Using the `content` attribute as an HTML Template

I've been trying to use the CSS content property to make somewhat of a "template" for an element of a specific class.
I've tried multiple things. . .
Many places I have seen told me to convert everything to hexadecimal, so I did, until I saw that using hex wrote the litteral characters into the element, instead of evaluating the characters as HTML.
I then tried just litterally entering the characters into the content, and I got the exact same result (this makes it appear as if there is no purpose for the hex, yet thats hard to belive with how many people say there is. . . ).
Is there any way that I can place HTML content into an element using the CSS content attribute?
I've made a JS-Fiddle for this:
And, of course, Stack wants my source:
HTML:
<button id="normal" >Show with normal output</button>
<button id="hex" >Show with Hexadecimal output</button>
<div id="class_changer" ></div>
JS:
function changeClass(evt)
{
class_changer.className = evt.srcElement.id;
}
var class_changer = document.getElementById('class_changer');
var normal = document.getElementById('normal').addEventListener('click', changeClass, true);
var hex = document.getElementById('hex').addEventListener('click', changeClass, true);
And the un-godly long CSS:
.normal::before {
content: '<img alt="Facebook" src="http://cache.addthis.com/icons/v1/thumbs/32x32/facebook.png" />';
}
.hex::before {
content: '\0027\003c\0061\0020\0068\0072\0065\0066\003D\0022\0068\0074\0074\0070\003A\002F\002F\0061\0070\0069\002E\0061\0064\0064\0074\0068\0069\0073\002E\0063\006F\006D\002F\006F\0065\0078\0063\0068\0061\006E\0067\0065\002F\0030\002E\0038\002F\0066\006F\0072\0077\0061\0072\0064\002F\0066\0061\0063\0065\0062\006F\006F\006B\002F\006F\0066\0066\0065\0072\003F\0070\0063\006F\003D\0074\0062\0078\0033\0032\006E\006A\002D\0031\002E\0030\0026\0061\006D\0070\003B\0075\0072\006C\003D\0068\0074\0074\0070\0025\0033\0041\0025\0032\0046\0025\0032\0046\0077\0077\0077\002E\0063\0069\006D\0074\0072\0061\006B\002E\0063\006F\006D\0026\0061\006D\0070\003B\0075\0073\0065\0072\006E\0061\006D\0065\003D\0063\0069\006D\0063\006F\0072\0022\0020\0074\0061\0072\0067\0065\0074\003D\0022\005F\0062\006C\0061\006E\006B\0022\003e\003c\0069\006D\0067\0020\0061\006C\0074\003D\0022\0046\0061\0063\0065\0062\006F\006F\006B\0022\0020\0073\0072\0063\003D\0022\0068\0074\0074\0070\003A\002F\002F\0063\0061\0063\0068\0065\002E\0061\0064\0064\0074\0068\0069\0073\002E\0063\006F\006D\002F\0069\0063\006F\006E\0073\002F\0076\0031\002F\0074\0068\0075\006D\0062\0073\002F\0033\0032\0078\0033\0032\002F\0066\0061\0063\0065\0062\006F\006F\006B\002E\0070\006E\0067\0022\0020\002F\003e\003c\002F\0061\003e';
}
Check it out at JS-Fiddle and see what you can do! Let me know! Thanks everybody!
UPDATE: SOLVED (ish...)
Yes, wierd question sometimes accept wierd answers (like iterating over the DOM...) but if you have a better solution, I'm all ears.
As it turns out, the accepted answers means of evaluating a "CSS template" may be the best means of performing "templating" without the use of third-party libraries or the new <template> tag (that I'm still not sure of) even though it makes my skin crawl (if anyone has a better solution, please post it). Either way, I've updated my JSFiddle, so check it out!
Although, I guess the best answer would be purely making a template as a string in JavaScript, that is, if we are going to be evaluating it later on and pre-pending it to an element. Yea, that would make more sense...
No, this is not possible with plain CSS. However, if you really want to save these templates in CSS, you could iterate over all elements and use
window.getComputedStyle(element, ':before').content
to fetch the content and then prepend/append it to the element. To parse the HTML, you could either use jQuery.parseHTML, new DOMParser().parseFromString or a dummy DOM element. Alternatively, you could also use .innerHTML directly, but I wouldn't recommend that..

Only one node inside div - HTML, JavaScript

I have looked something different from .appendChild() and .innerHTML but to work with Image() JavaScript objects.
I have 10 variables, img[1,2,3,4...10], created with JavaScript (new Image()) to pre-load and it's OK, now I want to insert it into my div only one at time.
innerHTML returns something like HTMLImageObject and appendChild() won't work like I want.
My solution so far is:
document.getElementById("teste").removeChild(document.getElementById("teste").firstChild);
document.getElementById("teste").appendChild(img1);
Someone have any better ideas?
If you don't want appendChild use replaceChild. For example:
div.replaceChild(imgs[i], div.firstChild);
Demo: http://jsfiddle.net/8bKy8/
your way is pretty solid but maybe like this is easier to read.. also lastChild has a marginal performance advantage
var ele = document.getElementById('teste');
while(ele.lastChild) {
ele.removeChild(ele.lastChild)
}
ele.appendChild(img1);
http://jsperf.com/innerhtml-vs-removechild/15
you could also keep a reference to the element somewhere
var ele = document.getElementById('teste'), img = ele.lastChild;
ele.removeChild(img);
ele.append(img1);
if you have jQuery available you can use
$('#teste').clear().append(img1);
depending on the browser you are using you potentially also have access to the HTML5 Selector API as well even without jquery that may be an alternative to the document.element method
document.querySelector('#tests').first();
https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Locating_DOM_elements_using_selectors

How to speed up <img> append()

I'm sorry if this is a novice question, but I'm not very knowledgeable when it comes to Javascript...
So, here's the code snippet:
function insertSquares() {
for (i = 0; i < 113; i++) {
$('#wrapper').append('<span><img src="images/square_2.png" style='display: none;'/></span>');
}
}
As you can see, I have a loop that appends a <span> and an <img> to a <div> each time that the code is repeated. Normally, this appending isn't a problem, but since it has to do this a number of times in the loop, so it takes a while. (also, this function is called a number of times by a setInterval(), and it slows down the entire webpage)
When benchmarking this function with JSLitmus, it runs 5 ops/sec, and I would like to speed this up. I have already thought of using the loop to add the data to an array instead, (rather than appending each time through the loop) and then when outside of the loop, appending all of the data only once, but this does not seem to speed up the process by a noticeable amount.
So, is there some way I can speed this code up that I haven't thought of? I can't think of a more efficient way to load and display this amount of the same image.
The best thing you can do is wait until you've finished the loop to make your changes to the DOM. Your current method will hammer the DOM into submission, and you certainly don't want this. Consider Document Fragments instead.
John Resig wrote about DOM Document Fragments some time back, but the post is still a good primer. You can find it online at http://ejohn.org/blog/dom-documentfragments/.
You could just work with strings until you need to append it.
function insertSquares() {
var html = '';
for (var i = 0; i < 113; i++) {
html += '<span><img src="images/square_2.png" style="display: none;"/></span>';
}
$('#wrapper').html(html);
}
For smooth performance I agree with #jonathon-sampson and #timrwood that one modification to the DOM is preferable to many.
That said, the other way to boost your performance is to minimize the amount of html you are inserting into the DOM. In your case I'd try to cut each element down to a single <span> block if possible using a CSS class to encapsulate common stylistic elements.
from:
html += '<span><img src="images/square_2.png" style="display: none;"/></span>';
to:
html += '<span class='myclass'></span>';
As a comment above noted, if you can avoid all of this in general and handle the creation of the DOM server side, that really would be the 'best' solution.

Div with a jQuery click event bound to it is not firing when clicked?

It could be a rookie mistake, but I've gone over my code enough times doing things such as; pre-pending .select-delete with div, attempted to use document.write("Hello") to see if the event was firing or not.
Here's a link to my jsFiddle: http://jsfiddle.net/gPF8X/5/
I really have no idea what's going on :(.
Any help would be greatly appreciated!
Edit: Linked to the incorrect JSFiddle, relinked to the correct one.
There is no - in your div class name.
<div id="1" class="selectdelete"></div>
$('.select-delete').click( function() {
Got it - id needs to be wrapped in quotes.
var value = $(this).attr('id');
The trigger is firing, but your code is not running because of an error - you're not quoting the string 'id' so it's an undefined value. Use your browser's debugger tool - it will help for this sort of thing.
Beyond that though, I can't say anything further because it's not clear what the desired result is.
Edit There's another issue as well - the selector is not working. You can't use the [ and ] character unquoted inside a jQuery comparison like that. The simplest solution is just not to have those characters in your input names. But you can also use escaping like so: $('select[name=g_country\\['+value+'\\]]').
I know you already accepted my other answer, but I just want to add for the record that there is another way to do it. Specifically, this seems like one of those cases where jQuery is less helpful rather than more. What I would do is change your HTML so the element names were also given as IDs, and then write it like so:
document.getElementById('g_country['+value+']').disabled = true;
document.getElementById('g_url['+value+']').disabled = true;

Can this snippet of Javascript be simplified more with jQuery?

I have the following snippet of Javascript, which is just attaching an onclick to a button and then updating the text of an em tag underneath it. I'm slowly trying to educate myself and work with jQuery more as I've found to like the syntax a lot more and for some tasks, it's more of a pleasure to work with.
Some of the best examples I've found have come from Stackoverflow, so I come once again, to see how this could refactored and improved with jQuery; any thoughts?
$$('em.green').each(function(em) {
em.up('button').onclick = function() {
em.update('Saving...')
};
});
Thanks!
Try this, little bit shorter:
$('button').click(function(i, button) {
$(button).closest('em.green').html('Saving...');
});
Saves you from having to loop through every EM and then bind the onclick. Might also help to add a class to the button so you're not binding to every button on the page, just in case there are others.
Here is a line by line translation from your prototype code. Not a lot different:
$('em.green').each(function(i, em) {
$(em).closest('button').click(function() {
$(em).html('Saving...')
})
});
IMO the prototype version looks just as nice if not nicer (without $ sprinkled everywhere).
This is a little shorter and might be easier to understand, but duplicates the "em.green" selector.
$('button:has(em.green)').click(function() {
$(this).find('em.green').html('Saving...');
});
crescentfresh's answer is also good, and doesn't need search for the em element each time. The performance impact shouldn't be noticeable though, since you probably don't have a huge tree of elements under the button.
Matthew Crumley's answer is good but why attach multiple handlers when one will do.
The added advantage is that this will also work if you create any em.green elements later in the lifespan of the document.
$('button:has(em.green)').live('click', function(){
$(this).find('em.green').html('Saving...')
});
(I can't edit, so I'll have to create a new answer but:)
Slightly shorter:
$('button').click(function() {
$(this).closest('em.green').html('Saving...');
});
Saves you from having to loop through every EM and then bind the onclick. Might also help to add a class to the button so you're not binding to every button on the page, just in case there are others.
It's unnecessary to include the function parameters, use the this variable to specify the context you want to find the closest parent of.

Categories

Resources