removing unused DOM elements for performance - javascript

I'm writing a single page application. When the page is initially served, it contains many DOM elements that contain json strings that I'm injecting into the page.
When the page loads on the client, the first thing that happens is that these DOM elements are parsed from json to javascript objects and then they're never used again.
Would there be a performance benefit into deleting them from the DOM and reducing its size? I haven't found any conclusive data about this aspect. For info, these elements are about 500K in size.
Thanks for your suggestions.

Would there be a performance benefit into deleting them from the DOM
and reducing its size?
In terms of the performance of the DOM, generally, the less you interact with your DOM, the better.
Remember that your selectors traverse the dom, so if you use inefficient selectors, it will be poor performance no matter what, but if you're selecting elements by ID rather than class or attribute wherever possible, you can squeeze good performance out of the page, regardless of whether you've deleted those extraneous markup items.
When the page is initially served, it contains many DOM elements that
contain json strings that I'm injecting into the page.... For info,
these elemnts are about 500K in size.
In terms of page load, your performance is suffering already from having to transfer all of that data. if you can find a way to transfer the json only, it could only help. Deleting after the fact wouldn't be solving this particular problem, though.

Independent of whether you pull the JSON from the DOM, you might consider this technique for including your JSON objects:
<script type='text/json' id='whatever'>
{ "some": "json" }
</script>
Browsers will completely ignore the contents of those scripts (except of course for embedded strings that look like </script>, which it occurs to me as things a JSON serializer might want to somehow deal with), so you don't risk running into proplems with embedded ampersands and things. That's probably a performance win in and of itself: the browser probably has an easier time looking for the end of the <script> block than it does looking through stuff that it thinks is actual content. You can get the content verbatim with .innerHTML.

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.

How to load and parse HTML without modifying its contents

There are many ways to parse and traverse HTML4 files using many technologies. But I can not find a suitable one to save that DOM to file again.
I want to be able to load an HTML file into a DOM, change one small thing (e.g. an attribute's value), save the DOM to file again and when diffing the source file and the created file, I want them to be completely identical, except that small change.
This kind of task is absolutely no problem when working with XML and suitable XML libraries, but when it comes to HTML there are several issues: Whitespace such as indentations or linebreaks get lost or are inserted, self-closing start tags (such as <link...>) emerge as <link.../> and/or the content of CDATA sections (e.g. between <script> and </script>) is wrapped into <![CDATA[ ]]>. These things are critical in my case.
Which way can I go to load, traverse, manipulate and save HTML without the drawbacks described above, most importantly without whitespace text nodes to be altered?
comparison
If you want to get really serious leave out the GUI and go headless, SO example with Phantom
I am going with the HTML Agility Pack.
Loading and saving does not manipulate anything else than invalid parts.

if some parts of the html are repeated in several documents, is it more efficient to load it in the js?

For example, say you have an information box that will be repeated in every single page. if i have this in the HTML, then every time i change it, ill have to change it in every single HTML file.
But if i load it in the javascript (as in the whole thing), then I'll only need to change the javascript. For example,
$("body").append('<div id="infobox">*whatever i need*</div>')
is this a better way or does it create more complications?
or are there more efficient ways to do this?
In short, no. You're on a slippery path there…
It might be more efficient for the person maintaining the page but you should really be doing this on the server-side as mohkhan suggested e.g. through a CMS or pre-processing if you're site is completely static. I assume that on your site, there isn't just an info box that's repeated — what about the navigational elements, the banner etc.?
There's nothing wrong with loading elements through JavaScript (e.g. to show counters, data, etc.) but you shouldn't be doing it for core content. Remember too that you shouldn't assume that everyone will have JavaScript enabled.

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?

How efficient is element.cloneNode(true) (deep clone)?

I'm building the HTML code within an XML DOM object to be used as the contents of the innerHTML of a div element using an XSL template. Traditionally we create a new XML DOM document and add the input parameters as XML Elements for the transform via javascript. This is all very time-consuming as we are basically hand picking the data from another XML document that represents our current account and copying the data into a transient XML DOM document.
What I'd like to do is clone the relevant node of the account document (i.e. customer info) and use it as the basis for the transform. I don't want to use the account document directly as I'd like to be able to add transform specific input, without making changes to the account object.
How efficient is using .cloneNode(true) for a desired node of about typically less than 200 elements from a document of typically 2000+ elements? The target platform is IE6 with no external tools (i.e. ActiveX).
CloneNode is pretty efficient but it will be consuming more memory doing it that way.
Another approach to consider is to use a Template object and a processor, pass your additional/changed data as parameters to the processor and the element that you would have otherwise cloned as the input element. This approach would require fairly significant mods the XSL though.
IE will fail on certain things.
e.g. checked radio/checkboxes will not be checked when you add your copy to the DOM.
Example:
http://webbugtrack.blogspot.com/2008/03/bug-199-cant-clone-form-element-in-ie.html
http://webbugtrack.blogspot.com/2007/08/bug-242-setattribute-doesnt-always-work.html
To see what IE will actually return, try replacing the url with this in the Address Bar of one of your pages, and press enter.
javascript:'<xmp>'+window.document.body.outerHTML+'</xmp>';
If you are happy with the results, great!, but I think you'll end up less than satisfied at what IE returns (both in the DOM, and this "string" value equivelant.
If you don't need form-elements, cloneNode is a real reliable tool ...
-- and in inserting ajax-data it is incredible in efficiency ...
However, as especially IE has a history of having problems with name-attributes, it is inconvenient to address any of these if you insert data ...
-- I don't really understand your XSL(T)-using, to me it sounds like using a gas-station as a (not !-) convenient place to change a 1960 WV to a 2008 Skoda ...
Userely they have some common technology, though it is not used in the same way, computerization in some way is just a minor problem, the major problems is in nearly any other way !o]
Have you got any need for form-elements ?-)

Categories

Resources