This is not a real coding question, more of a real-world statement.
I have previously noted that DOMReady events are slow, very slow. So, I noticed while browsing the jQuery source that the jQuery domeready event can be trigger using $.ready(). Then I thought, placing this simple execution script just before closing the body should trigger all the "onDomReady" listeners that where previoulsy attached. And yes, it works as expected:
<script>$.ready()</script>
</body>
Here are two examples, this one measures the ms spent while waiting for DOMReady:
http://jsbin.com/aqifon/10
As you can see, the DOMReady trigger is very natively slow, the user has to wait for a whole 200-300 milliseconds before the domready script kick in.
Anyway, if we place $.ready() just before closing the BODY tag we get this:
http://jsbin.com/aqifon/16
See the difference? By triggering domready manually, we can cut off 100-300 ms of execution delay. This is a major deal, because we can rely on jQuery to take care of DOM manipulations before we see them.
Now, to a question, I have never seen this being recommended or discussed before, but still it seems like a major performance issue. Everything is about optimizing the code itself, which is good of course, but it is in vain if the execution is delayed for such a long time that the user sees a "flash of "unjQueryedContent".
Any ideas why this is not discussed/recommended more frequently?
By triggering the event yourself, you are stating to your ready() handlers that your dom has been loaded BUT it may not have been! There is no short cutting the DOM ready event. If there is indeed a long wait time, then employ the amazing debugging tools of firebug, chrome, etc.... check your resources and their timing ques. It's all there in black and white and will indicate what is taking so long (the requests, the rendering, how many resources, etc.. )
Any ideas why this is not discussed/recommended more frequently?
Placing JavaScript just before </body> has been discussed a lot, and as you know it's recommended if you're looking for faster page loads. Manually triggering the jQuery ready handlers is in fact poorly discussed. Why? Well, I don't think there is one single objective answer to that, but I'll try to outline some possibilities here:
Performance is not the main goal of jQuery (anthough it's definitely a concern), and performance freaks will usually look for lighter libraries for cross-browser DOM manipulation and event handling, or roll their own.
It's an extra step, and it doesn't look clean. jQuery tries to be clean and elegant, and recommending an extra step to initialize scripts doesn't sound like something that's gonna happen. They recommend binding to ready, so recommending to force .ready() and ignoring the actual browser event looks "wrong". Whoever is concerned about that probably knows that initializing scripts right before </body> is faster.
Optimizing DOMContentLoaded sounds like a task for browser vendors. I'm not sure why it's slower, though, and maybe there's not much room for optimization – in my understanding, calling init scripts before </body> should always be the fastest way to initialize stuff (as it's executed immediately when parsing the container <script> tag, while browsers must finish parsing the whole file before triggering DOMContentLoaded).
You probably remember that not so long ago it was common practice to have <script> blocks scattered everywhere on the HTML. Then the Web Standards movement came, and recommended more sane and maintanable ways to do things. That included bootstraping scripts from a single place – initially, window.onload, which was then considered problematic for being slow, then DOMContentLoaded and its emulations for IE8 and below. However, we still see spaghetti-HTML with scripts everywhere on a daily basis here on StackOverflow. So I'm not sure if recommending placing scripts before the end of the body is a good call today, because it may be interpreted as a license to add scripts anywhere within the body.
Finally, if you're really concerned about loading your script fast, and your code does not manipulate the DOM, the fastest way to load it is to put it in the <head> before any stylesheets. And I'm stating that just to say that there's no silver bullet, no optimal way to init scripts that is the fastest and most elegant in every scenario. I think that's why the community sticks with recommending something that looks sane and tends to create more maintainable code, instead of other better performing alternatives.
Actually, placing a function call before </body> tag makes it pointless to use jQuery's ready(). Just put native JS-wrapper function call that contains calls of all other functions that should be called on document ready.
In general, it's a working (though somewhat littering HTML code and therefore unacceptable for perfectionists) alternative for situations when author does not need/want to use jQuery at all. In such situations though, I would prefer to use native DOMContentLoaded event handler that is supported by most of browsers including IE9+ (for IE8- we can use window.load() as an acceptable fallback).
Related
Someone recommended here that window.onpaint be used to run some javascript before page load. I've never actually seen this before, could someone explain its usage/usefulness?
From the MDN :
onpaint doesn't work currently, and it is questionable whether this
event is going to work at all, see bug 239074.
So the usefulness is zero.
It might depend on your exact use case but if you want to run a script "before page load", the simplest solution is probably to put it in the head.
Explanation
For reasons which I appreciate, as of jQuery 1.8, the load event has been deprecated, however, it was still possible to detect whether an image was loaded (even if it was in the cache) just by using certain workarounds. Therefore, the deprecation of the event is actually quite irritating as it posed as a starting point at the very least for detecting when an image has finished loading onto the page.
Nevertheless, it has been deprecated, and I am therefore asking this question with the hope that I will find an answer, thus, help me and potentially others that may soon be running into the same issue.
An Example (before jQuery 1.8)
Without using a plugin (as this should be able to be done in very little code, so a plugin is unnecessary), I would like to call a function when each image on my page is loaded.
Something like this (this will not work due to the deprecation):
$('#mn_content .column').on('load','img',function(){
console.log('loaded');
})
My Question
Is anybody aware of how to achieve this now that the load event does not exist?
Please note: If the only way to achieve this (now), is to use the Javascript new Image objects, then please do not waste your time helping me as others need your help more than I do. I am able to write this code, it just seems a bit long winded for something so basic.
I have simply asked this question to ensure there is not a way of achieving this without the use of the Javascript image objects
I will of course be very grateful for any help, I just don't want you spending much time on me when there are others that need your help more. :-)
The load event still exists, you just can't bind to it using .load anymore. Your event delegation example should continue to work on into 1.9 and 2.0 (if the browser you're testing in supports bubbling of the load event)
I personally would still use the new Image method because i don't trust that all browsers will always bubble the load event properly.
Edit: Sorry if i wasn't clear, the point i was making is that the load event is still there, you just have to properly bind to it. Since the load event doesn't bubble in all browsers (if in any browser?), you must bind the event directly to the image. I'd suggest using the method that you asked us not to provide you an example of.
This question already has answers here:
Does the <script> tag position in HTML affects performance of the webpage?
(8 answers)
Closed 9 years ago.
In all the documentation I see the jQuery script tag beneath <title> in the head, but then when I go into some other sites (the initializr template is the first off the top of my head), they drop it into the bottom of the body (you know, right before </body>).
Which of these two is right?
Quoting the YDN Best Practices for Speeding Up Your Web Site:
Put Scripts at the Bottom
The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.
In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.
An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.
It's funny that people used to say that I should be slapped upside the head for doing that when I said that in 2009 and now it's suddenly a best practice... Some progress.
Well, I think you need to put this inside a $(document).ready(function() { so that the document is actually ready before you are calling the jQuery. Personally I also put just before the </body>. Now given that both works, is there a 'right' way, or it's just a question of personal preference?
Would love to listen from experts, though.
Steve Souders' book High Performance Web Sites recommends putting scripts at the bottom, before the </body> tag. You can also find this documented at the developer.yahoo.com site here. (It's the fourth recommendation in the list.)
I generally put the scripts at the bottom, before my '' tag and have had few issues with this. I've noticed that this helps performance on older browsers like IE7 a lot more than it does with newer ones like FF3.6, Chrome and IE9. The older browsers only support 2 parallel downloads, whereas the newer ones support something 6 connections. The blocking, as a result, isn't as noticeable.
Hope this helps!
Placing scripts at the bottom has performance benefits:
Where should I put <script> tags in HTML markup?
I still consider myself a novice with javascript...so be gentle :)
Is there a way to view all open events listeners on a page and perhaps to see any inifinte loops that may be running?
What is happening, is a page I'm trying to debug works fine. Nodes get added to the page dynamically via a drag and drop method. All works well, but as time goes on, it seems to get increasingly slower - meaning the mouse starts skipping and the such.
I don't know if this is because javascript stores stuff in memory and my memory is getting used up, or if because of the constant checking of elements on mousemove slows things down as more elements are added to the page.
So I thought I would ask what I thought to be the obvious of maybe eventListeners are piling up and I'm not realizing it, or maybe there is an inifinte loop that is not being closed out.
I have firebug, and feel like I've looked at everything. I've put in console.debug statements in the loops and they all seem to end fine.
Any debugging tips would be appreciated.
I would say definitely be careful of memory leaks, especially in IE.
Here's a good resource for learning Javascript:
www.javascriptkit.com
Specifically here are some useful articles:
http://www.javascriptkit.com/jsref/events.shtml
http://www.javascriptkit.com/javatutors/closuresleak/index.shtml
What you need is a JavaScript profiler. Google chrome has a built in under ctrl-shift-j > profiles. There is one available in firebug for firefox as well.
I'm trying to lazy load javascripts, but I can't get it to work reliably. My pages load quite quickly and I want to keep it that way, so I'm not about to use a timeout to delay the loading. Besides document.readyState, how do I ensure the DOM is genuinely ready for modification?
Method I:
poll readyState
createElement script
src = url
appendElement to head
Results:
IE8: always aborts
FF3: loads first time, aborts every
other
Chrome: loads first time, aborts every
other
Method II: (lazyload included in head tag)
load with lazyload
Results:
IE8: always aborts
FF3: works
Chrome: loads first time, aborts every
other
If you put your <script> tag just above the </body> tag, you could do most things with DOM without it raising any errors, i.e. anything that is above the <script> tag is usually up for modification.
However, if you are looking for a more robust solution, you might have some progress by checking out how the major libraries are detecting if the DOM is ready, here's one for starters (jQuery): http://github.com/jquery/jquery/blob/master/src/core.js#L393
Javascript is hardly usable cross-browsers without a decent framework to help you span the differences. Probably most popular today is jquery, where, per this tutorial, you could use $(document).ready(). In dojo, also quite popular, you could use addOnLoad. And so on... and if you aren't using any framework, you're making life too hard for yourself: do yourself a favor and pick a JS framework you like!-)