Load content into a div with same performance as an IFrame - javascript

Have a issue with performance while injecting a glob of content into a view page. The markup can get rather large. I did a test using an IFrame to load the content from a temp file and directly by setting the html and the performance is much better than using the jquery .load() or html(). However, everything has already been built around loading into a div and I am trying to avoid IFrame.
NOTE : I am making a hunch that there are some operations going on when injecting the content into a dom that you don't get when loading into an IFrame. Similar to if open a 2.5 mb html directly in the browser it loads almost instantly, meanwhile, loading 2.5 mb into a div using jquery doesn't offer the same performance.
Are there any tricks I could use that would allow .load() to perform better?
Edited: Added code:
The question is rather straight forward. I am getting a payload from an ajax call that is either a url or raw html. I am then using either
element.html(content)
or
element.load(content)
based on whether the content is a url or markup.
When I change the element to an IFrame and then use either
element.attr('src', content);
or
element.contents().find('html').html(content);
The content loads much faster.

Related

Can't get document.write to work with ajax

I have a script that uses document.write that needs to work within ajax, but I am having trouble finding a solution to make it work. here is the script that is loaded into the page via ajax.
<script type="text/javascript">
example_widget_id = "example-1234";
example_widget_name = "registration";
example_widget_type = "example";
document.write(unescape("%3Cscript src='https://widgets.example.com/javascripts/example_widget.js' type='text/javascript'%3E%3C/script%3E"));
</script>
What happens is that the page goes blank...which is normal for document.write and ajax. I am trying to find a way to add it via innerHTML (or another solution) but I have had no luck. I looked at this thread JavaScript Document.Write Replaces All Body Content When Using AJAX
but I can't seem to figure out how to make that work with what I have.
Thanks for any help you can provide.
UPDATE:
The script snippet is third party widget. It is used by inserting it into a frontend web page editor that allows the user to position the content on the page anywhere they want (via ajax). Once it is positioned it can also be styled with the frontend editor. When the page is how the users wants it, they can save the layout and the front end editor is disable (turned off) until needed. When this happens the script (document.write) will then load and work fine on the page as it should without the interference of the ajax based frontend editor.
I was thinking if there was a way to cache the html results of the document.write (html portion) and then that cached version could be loaded via the frontend editor. Then I can swap out the html cached version of the widget with the original script w/document.write once the front end editor becomes disabled or turn off. I played around with the logic and I am able to swap out what loads depending on the state of the front end editor. I guess my question is can a document.write content be cached or saved? I think I can handle the logic in how it is used after that.
There is no solution. document.write() replaces the document after the onload event have fired. It cannot be done.
You cannot make it to work*.
*note: Technically, you can make it to work if you write your own web browser because you then would be able to make your browser NOT behave like all other browsers and append instead of replace on document.write(). But you cannot make it to work with Chrome or IE or Firefox or Opera.
For a quick solution, use .innerHTML instead. For a better solution, learn the DOM manipulation API (or use a DOM library).

How to preprocess HTML before it is parsed by the browser - block resorce loading

I am looking for a way to modify some text inside the HTML before it is being parsed by the browser.
More precisely, I would like to remove some tags from the HTML so the image resources would not be fetched by the browser, only when I am ready I could insert these tag back to have them loaded.
Is it possible to do that via some JS/Jquery or CSS, if so, how?
the motivation here is to be able to block the loading of some resources on a page and have them loaded only when needed according to some logic. this needs to be done by some kind of scripting added to the page
Because you're doing this in JavaScript the HTML is already being processed when it comes to launch your <script> tags.
You could move your <script> tags into the <head> from the <body>, or move it to the very beginning of the body. However the problem here is that you'll have to wait for your elements to actually be created in the DOM before you can work with them.
You could use something like setTimeout() or similar and continually look for them until you find them, but there's still going to be a slight delay between them being created and your script finding them, at which point they might already start to load.
The only surefire way is to process the markup server side long before it gets to the browser.
My answer here possibly could be of use, if you can place noscript tags in key places in your markup prior to parsing/evaluation:
Client-Side Dynamic Removal of <script> Tags in <head>
This method—for javascript-enabled agents—would delay the rendering of the entire page however, or at least the regions that you needed to affect.
basic generalised theory
Wrapper your body or specific region with a noscript tag identified with either a class or id. Place some javascript to execute directly after the close noscript that grabs the tag and reads the html contents as a string. At this point you could modify the html string however you like and then re-inject it back into the DOM replacing the noscript tag.
more specific implementation
If you know before-hand which resources you need to postpone—say all your images—you could wrap each image in-question with a noscript tag. Then trigger off some JavaScript that grabs all noscripts and rewrites the contained image html to use a placeholder or lower quality version of the image. At the same time you could set up event listeners or timeouts that inject the actual images when the time is right.
The Lazy Load Plugin for jQuery is maybe what you are looking for. It delays loading of images in long web pages.
You can use any jQuery event such as click or mouseover. You can also use your own custom events such as foobar. Default is to wait until user scrolls down and image appears on the window.
Beside all the It is also possible to delay loading of images. Following code waits for page to finish loading (not only HTML but also any visible images). Five seconds after page is finished images are loaded automatically.
$(function() {
$("img:below-the-fold").lazyload({
event : "sporty"
});
});
$(window).bind("load", function() {
var timeout = setTimeout(function() {
$("img.lazy").trigger("sporty");
}, 5000);
});
Check the delayed loading demo.

How to compare IFrame and Ajax contents in terms of performance and memory usage?

I have a page that contains a big chunk of contents generated dynamically by the server in the same domain & web app, I have total control of the page and the generation of the contents. So I have 2 options here :
use IFrame to load the contents and change src attribute when
contents refresh.
Ajax
Please note that the contents could be refreshed & changed to other contents, that means the iframe's src could be dynamically changed or the ajax contents could be refreshed frequently depending on the user.
Providing that I will clean up the iframe's/Ajax's resources(html, javascript objects,event listeners, etc) before unload/refresh, which option is preferable in terms of performance and memory usage if the contents are refreshed frequently? And what I should keep an eye on when doing frequent contents refresh?
Thank you.
If I were you I would go for AJAX, for a number of reasons:
It is cleaner to work with
You wouldn't have to deal with extracting the content and manipulating the DOM, which is always slow
It is easier to debug
Generally, I would say a good rule is: Don't use anything it wasn't made for on a large scale

Load pages via AJAX and execute javascript and CSS

I've been searching for a while now, but I can't figure out how to load an entire page via AJAX and still execute all javascript and css.
Mostly I just end up with the plain text without any CSS.
Is there a way to do this? I tried jQuery.get, jQuery.load and jQuery.ajax, but none really work like that.
I have a different solution. You may try it with an iframe. Use jQuery to append an iframe script including all relevant codes into some part of your page (like some div). This may do it for you including CSS, like;
$('<iframe src="your_page.html"/>').appendTo('#your_div');
Or you may try something like;
$('<iframe src="your_page.html"/>').load(function(){
alert('the iframe is done loading');
}).appendTo('#your_div');
I have solved similar problem as following.
Download the webpage over ajax
Iterate it over and find any <script> and </script> tags
Get content from within these tags as text
Create new <script> element and insert there the code
Append the tag to your webpage
Another thing is you will need to somehow call the script..
I have done it this way:
I set standardized function names like initAddedScript callback which I am calling after appending the script to the page. Same as I have deinitScript called when I do not need the code (and its variables,..) anymore.
I must say this is awful solution, which likely means you have bad application architecture so as I have had:)
With css is it the same, but you do not need any handlers. Just append the style tag to your documents head.
If the page you load doesn't have any style data, then the external stylesheets must have relative paths that are not correct relative to the invoking document. Remember, this isn't an iFrame - you aren't framing an external document in your document, you're combining one document into another.
Another problem is that loading your complete page will also load the doctype, html, head, and body tags - which modern browsers will cope with most of the time, but the results are undefined because it's not valid HTML to jam one document into another wholesale. And this brings me to the third reason why it won't work: CSS links outside of the head section aren't valid, and the misplaced head section caused by your haphazard document-in-document collage.
What I'd do for compliance (and correct rendering) is this, which would be implemented in the Success callback:
Copy all link elements to a new jQuery element.
Copy the contents of all script in the head section
Copy the .html() contents from the loaded document's body tag
Append the link elements (copied out in step 1) to your host document's head
Create a new script tag with your copied script contents and stick it in the head too
Done!
Complicated? Kind of, I guess, but if you really want to load an entire page using AJAX it's your only option. It's also going to cause problems with the page's JavaScript no matter what you do, particularly code that's supposed to run during the initial load. There's nothing you can do about this. If it's a problem, you need to either rewrite the source page to be more load-friendly or you could figure out how to make an iFrame suit your needs.
It's also worth considering whether it'd work to just load your external CSS in the host document in the first place.
I suppose you are looking for something like this:
your page div --> load --> www.some-site.com
After a quik search the closest solution seems to be the one by "And": Load website into DIV
You have to run a web server and create a proxy.php page with this content:
Then your JQuery load() function should be like this:
$("#your_div_id").load("proxy.php?url=http://some-site.com");
NB. I have tested this solution and it should not load all the CSS from the target page, probably you'll have to recreate them. For example the image files stored on the remote server will not loaded, I suppose due to authentication policy.
You will be also able to view only the target page without the possibility to browse the target site.
Anyway I hope this could be a step forward to your solution.
Get your entire webpage as text using ajax
document.open();
document.write(this.responseText);
document.close();
OR
document.documentElement.outerHTML = this.responseText;
But you need to change the path of css and js pages in original webpage if the resulting webpage is in another directory.

Changing the content type of an iframe to xml to display xml and manipulate it through DOM

I would like to use JavaScript to do the following:
Build an XML file
display it in an iframe
manipulate the content through DOM
I'm building an XML editor and am having trouble displaying the xml in an iFrame.
this is the code that I'm using at the moment.
function previewContent(what){//changes the content of an iFrame
var tsite = document.getElementById('xmlinside').contentDocument;
tsite.open();
tsite.contentType('text/xml');
tsite.writeln(what);
tsite.close();
}
function makeXML(){
var tester = '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\
<bookstore>test</bookstore>';
previewContent(tester);
}
without the tsite.contentType('text/xml') the iframe simply displays test.
when I check the source it's still in HTML with the added line <bookstore>test</bookstore> added and the xml version as a comment.
I would like it to display like a browser without a stylesheet. I know Safari displays it as a raw xml file if there is no formatting associated with it. This would be perfect. Is it the content type that is messing up? That's why I tried changing it but this is the wrong code. Any help would be great!
A few things to keep in mind...
1.) If it's content loaded via AJAX you will need to use the application/xml media type/mime and the first element has to have a namespace...
<div id="root_most_ajax_element" xmlns="http://www.w3.org/1999/xhtml">
<p>ajax content</p>
</div>
2.) Never use innerHTML (and frameworks as they rely heavily on innerHTML) and most especially never use it in conjunction with loading AJAX loaded content, the proprietary Microsoft method does not correctly register the DOM so you sort of see that the code is there but it's not really there thus making your code wholly unreliable at that point. If using JavaScript use the importNode method to load AJAX loaded content (instead of using an iframe, you can import it to a division element instead).
3.) You won't (and shouldn't) be able to access (X)HTML of an iframe if it's not loaded from the same domain so if it's being loaded from a third party website forget about it otherwise you could say manipulate the text and discover their information (phone, email, etc if they're signed in to something).
If you meet those three conditions you should be able to work with code as if there were no iframes or AJAX involved to begin with.

Categories

Resources