Idiomatic Dojo that does the same thing as YAHOO.util.Event.onContentReady? - javascript

I want to start manipulating a DOM element as soon as it's available, to minimize the time that it might appear in its original state on screen. I know in YUI you'd use YAHOO.util.Event.onContentReady and I'm pretty sure you'd use bind in jQuery. I'm new Dojo, and I'm not sure: What's the "Dojo Way" to do this?
UPDATE: I specifically don't want to wait for the whole page (which is ridiculously data-heavy; the markup alone is potentially a MB or more) to load. I want to immediately start looking for the element in the DOM and start processing as soon as it's there, without waiting for ALL the markup to download, be parsed, and inserted into the DOM—that could take a relatively long time. I want to start looking at the DOM and get to work as soon as this tiny fragment is there. Given that constraint, isn't dojo.ready a poor fit? My understanding is that it waits for the entire DOM to be ready, similar to onDOMReady.

The most precise way of injecting functionality after a piece of DOM is added to the tree is to have the <script> that requires it placed directly below it in markup. It seems less sexy than something like onContentReady, but onContentReady is just a polling mechanism that may end up executing your callback around the same time as domready, anyway, long after the relevant DOM subtree is ready for scripting.
Browsers can assemble a DOM tree pretty fast. And with a polling solution such as onContentReady, you're slowing down the page assembly/render by having to execute the code that searches for the targeted element(s) every few milliseconds.
I'd stick with keeping your <script>s at the bottom of the <body> or if you must, putting the must-run-now-damnit code in a <script> after the required markup.
I am not familiar with dojo's API, so I can't answer your specific question wrt dojo if the above is not helpful.
(edited to escape the leading < in tags so they would display)

dojo.addOnLoad. There is also a newer alias dojo.ready.
note: Add on load also waits to be sure all required modules are loaded, in addition to waiting for DOM-readyness

dojo.addOnLoad() is what you want. See documentation.
Note that dojo.ready() is just an alias for that method.

Related

Potential performance improvement from inserting chunks of DOM elements dynamically as needed?

I'm looking at ways to improve performance of my single page web app, which will need to run on a variety of devices including lower-end phones.
I've got 8 modals (Twitter Bootstrap but this question applies to any framework) that add over 200 elements to my total page DOM element count (783). Is it worth having these as strings in Javascript rather than code in the HTML, and injecting them when needed into the DOM immediately before display, then removing them afterward? Would strip live DOM size down by a quarter, thus making e.g. JQuery element searches quicker, lighterweight page etc.
I was thinking to use JQuery's $.detach() and $.append() for example
Anytime you modify the DOM, you take a performance hit because the browser will have to "reflow" and "repaint" the UI. As such, keeping those modifications to a minimum will help, however doing modifications in batches absorbs some of that performance hit (i.e. changing 3 DOM elements separately is more expensive than changing all 3 at once). So, group together your DOM changes as best you can.
The actual mechanism you use to inject the new content could either be by:
Passing a string of HTML to the HTML parser and asking it to parse
on demand the string. This is essentially the same as the process
that happens when the page is being parsed from the server. Using
the standard .innerHTML or JQuery .html() accomplishes this.
You could also build up the DOM element in memory first and then
inject that node into the DOM at the right time (i.e. document.createElement or document.createDocumentFragment). I generally favor
this approach as it is more programmatic, vastly reduces the
possibility of string concatenation and quotation errors and is
cleaner to read. From a performance standpoint, this gives you the
benefit of getting some of the work done prior to DOM injection
time. This would be the equivalent of the DOM .appendChild() or
the JQuery .append() methods.
In the end, today's modern user agents handle DOM changes much better than they used to and either approach is viable. It's the really bad techniques (like modifying the DOM in a loop) that you want to stay away from that, in the end, will make a difference.

Serialization of the full page DOM. Can I get at the JS code that is loaded up, or must I AJAX it separately?

I have a bug I'm trying to track down, and it is very difficult to do so because of the complexity of the web app. There are many frames, and many instances of Javascript code that is embedded into the HTML in different ways.
The thing that needs to be fixed is a sub-page created with showModalDialog (so you already know it's going to be a disaster), and I am hoping that I can find a way to serialize as much of the DOM as possible within this dialog page context, so that I may open it to the same content both when the bug is present and when it is not, in hopes of detecting missing/extra/different Javascript, which would become apparent by pumping the result through a diff.
I tried jQuery(document).children().html(). This gets a little bit of the way there (it's able to serialize one of the outer <script> tags!) but does not include the contents of the iframe (most of the page content is about 3 iframe/frame levels deep).
I do have a custom script which I'm very glad I made, as it's able to walk down into the frame hierarchy recursively, so I imagine I can use .html() in conjunction with that to obtain my "serialization" which I can then do some manual checking to see if it matches up with what the web inspector tells me.
Perhaps there exists some flag I can give to html() to get it to recurse into the iframes/frames?
The real question, though, is about how to get a dump of all the JS code that is loaded in this particular page context. Because of the significant server-side component of this situation, javascript resources can be entirely dynamic and therefore should also be checked for differences. How would I go about (in JS on the client) extracting the raw contents of a <script src='path'> tag to place into the serialization? I can work around this by manually intercepting these resources but it would be nice if everything can go into one thing for use with the diff.
Is there no way to do this other than by separately re-requesting those JS resources (not from script tags) with ajax?

Javascript like $(document).ready() for "modern HTML5" browsers

This is most likely already a question somewhere, but I cannot find it, as EVERY single search turns up jQuery questions.
I'm looking for a proven method to bind to the document being ready, much like jQuery's $(document).ready(). However, this is for a "modern browser only" page, with very light javascript, and I'd like to avoid loading jQuery here.
Would someone kindly point me in the right direction?
Thanks!
document.addEventListener('DOMContentLoaded', function () {
/* ... */
});
The event "DOMContentLoaded" will be fired when the document has been parsed completely, that is without stylesheets* and additional images. If you need to wait for images and stylesheets, use "load" instead.
* only if the <script> is before the <link rel="stylesheet" ...>
window.onload = function() {} is a standard from the long past ago, whereas it also waits for all the images to load, it is basically a working, functional alternative for some such cases also in all old browsers. A user usually still should wait a second till he makes a responsible action.
Edit: In my case, I needed it for all the libraries being loaded prior to anything else, as they were listed fixed in the footer (jquery). At it is mine dependency to continue to work with is possible just once it is loaded. So IMHO the fact that the user has to wait is irrelevant (unless I miss something here and am available to be explained), as it's the case with any way of jQuery loading, till it's not loaded it can't be worked with it. For the sake of that point ofc any way there must be a backend check as client-side js can be "intercepted". Waiting for an entire document to load is certainly more lengthy than using it just after its inclusion, however this is for cases when you eg. can't affect the order of html scripts, eg when you use it in own 3rd party package.

JavaScript and CSS order

I have an HTML file which is linked to CSS file and also to JavaScript file.
Is JavaScript executed first and then the CSS is applied, or vice versa ?
Is there any way to change the order ?
Thanks !
It's generally considered a good idea to import your scripts as late as possible, and your stylesheets as early as possible. If possible, in fact, you should stick all your script imports at the very end of the <body>. I find that problematic when there are components pulled into the page that want to be able to drop little script blocks that reference jQuery (for example).
If your stylesheets are first, that helps make sure the browser applies styles before showing anything to the user. Conversely, by including scripts last, you defer that potentially slow script processing until after the point where the user gets to see something on the screen.
The JavaScript gets executed when the <script> element is parsed. Some of the JS might set up event handlers to run some JS when events happen.
CSS is applied to the live DOM. Changes to the DOM get CSS applied automatically. Changes to CSS apply to the whole DOM automatically.
Yahoo's research into speeding-up page loading times should be very helpful, and they explain things much clearer than I can.
http://developer.yahoo.com/performance/rules.html

Initiate onclick faster than with document.onload

I have html-pages with links where i want to attach a function to their onclick event. One way to do it is of course:
Save
But I know this is not the best practice. So instead I wait for window.onload, loop through the links and attach the save-function to the links with rel="save". The problem with this is that it waits until the whole page has finished loading which can be several seconds after the link is displayed and clickable.
So is there another way to do this? Avoiding onclick in the html but that makes it work immediately when the link is rendered.
Internet Explorer has a handy attribute for <script> tags called defer. It's for delaying the parsing of a script until the document has finished loading. For other browsers that support it, you can use DOMContentLoaded, as someone else suggested and for browsers that don't support either you can fall back to onload.
<script type="text/javascript" defer>
//- Run this code when the DOM parsing has completed
</script>
I did a quick Google search for "DOMContentLoaded defer" and found the following page that might help:
http://tanny.ica.com/ica/tko/tkoblog.nsf/dx/domcontentloaded-event-for-browsers
In your case, you can just leave that as it is. Stick to the simplest possible thing, even if it is not the general best practice.
You could try DOMContentLoaded event instead of load. IE also gives you the defer attribute for script tags, which defers execution until the DOM is loaded. If those don't work for you, then you are stuck with the solutions you mention, as far as I know.
I don't know if this is appropriate for your solution, but you could insert script immediately below the are with the links you need altered. This script would not be wrapped in a function, allowing the browser to execute it immediately when seen. The effect is that you can run script before the full page is loaded, altering only the items that exist above the script being run. (If you reference something below the script, it will fail.)
BTW, this is almost certainly not a best practice, and some would probably label it a worst practice.
How about this?
Save
Note: This solution requires to users to have Javascript enabled. Not exactly best practice, but may be suitable for your scenario.
The ideal here would be to use the ideas of Unobtrusive Javascript.
In this way, if the Javascript isn't loaded the link would still do something. It's a link right, so it leads the user to another piece of content? - this should work without Javascript. And if the functionality attached to the links can ONLY work with Javascript you should create and insert them into the DOM with Javascript (they aren't clickable if they aren't there...).
(Otherwise how about delegating the click event to a wrapper element? Does that work before the element is complete?)
edit: Oh, and "save" sounds very much like it ought to be a button in a form rather than a link. The Unobtrusive JS stuff still applies though.

Categories

Resources