Read size of current document from Javascript - javascript

I'm starting to play around with Boomerang for measuring performance. It's very promising. While it allows me to measure latency, bandwidth and page load times, I'm also interested in trying to get the time it took to render the initial HTML page server-side. Wile it seems straightforward to log the time at which the browser started parsing the javascript (which is close to when it initally arrived) in order to get an estimate of the server time, I need to work out how much network time to deduct. So to do that, I need to know how large the html document is.
How can I tell this from Javascript?
The document object does not appear to have an innerHtml property
I tried
totsize=document.HEAD.innerHTML.length + document.BODY.innerHTML.length;
The HEAD and BODY entities appear in the DOM browser within Firefox - but when I try the code above I get an undefined error - also tried with 'head' - to no avail.
Any ideas?
(note that javascript is in a seperate file and will be cached in most cases - so that's not a big problem).
I did try google - but I just get lots of pages describing the on-screen size of html elements and the window dimensions :(
TIA

How about document.documentElement.innerHTML.length ?

document.documentElement.innerHTML.length as per #meder is probably good enough. It won't be exact because it returns a serialisation of the current page DOM and not the original HTML source.
For static pages that won't matter as it'll just be the case of an extra close tag here, different attribute quoting there... but if there's lots of page content created on the fly from script, that content will count in innerHTML despite not being present in the original source, which could throw your calculation out.
If you need to find out the actual resource length, you'd need to fetch the page again, which you could do using an XMLHttpRequest on the current URL:
var xhr= new XMLHttpRequest();
xhr.onreadystatechange= function() {
if (this.readyState!==4) return;
alert(this.responseText.length);
};
xhr.open('GET', location.href, true);
xhr.send();
(This can't be done if the page is the result of a POST request though.)
This will give you a size in characters. If you are using an single-byte encoding like ISO-8859-1, the network-load byte size will be the same. If you're using UTF-8, then you can find out the byte size by converting the string to UTF-8-bytes-as-code-units, for which there's a quick idiomatic hack:
var bytes= unescape(encodeURIComponent(this.responseText));
alert(bytes.length);
If you are unfortunate enough to be using a non-UTF-8 multibyte encoding you can't really do much here; you'd have to include full mapping tables for the encoding, which for East Asian encodings would be insanely large.

How about this?:
/*
* This script determines the size of the current page in bytes.
* But why does the 2nd length differ from the first?
*/
var len=document.getElementsByTagName("html")[0].innerHTML.length;
var len2=document.getElementsByTagName("head")[0].innerHTML.length + document.getElementsByTagName("body")[0].innerHTML.length;
//document.body.innerHTML.length
alert('Page Size: '+len +' bytes');
alert('Page Size2: '+len2+' bytes');
It seems to work ok, BUT NOT great. As it gives two different lengths. But why?
Ugh! This formatting is killing me.
EDIT: Can somebody please fix this formatting? My browser isn't working right, apparently. Firefox 15.x
EDIT: fixed formatting

Related

How to replay an animated GIF in javascript (vanilla) - Without JQuery

My current issue is that I have a loading bar animation on my web-based app that is shown (obviously) when the whole page or specific things are loading up. It is supposed to look like one of those Samsung TV Apps so it needs to be quite polished with the UX.
What me and my team are doing right now is a mix between creating an element for it and I assumed it gets cached in the local device which is an issue. I've known of a few ways that I can go around this like adding a Math.random() query at the end of the src url but I'd rather not follow that route for now.
I also saw a way that I believe involved simply setting the element.src = 'theSameUrl.gif' URL to be the same and I assume forcing the device to reload the file instead of using the cached one.
I would also be open to trying new file types that could make this a lot easier but I must keep in mind that this app will work on a LOT of different hardware, from Samsung TV's to BT Boxes or even Virgin Media Tv Boxes, amazon firestick etc.
At this point I'll take anything :P
You can "force it" to reload by wiping it source: img.src = ""
Then you set it again: img.src = "your_src_path"
This way your .gif will start from zero, at least on Edge, Chrome and Firefox, it should work the same way on a TV.

Download progress in HTML5

If I have 5 javascript files and each of different size and same with CSS, is it possible to show "real time" progress bar when scripts/css get downloaded?
I know this can't be possible in HTML4 and would require Flash/Silverlight. But can I achieve this in HTML5? If yes, how would I do it?
I want to show a text like "Downloading" and as each script/css get downloaded real time, each letter of Downloading should start filling up. I am not asking for any code. Just want a high level concept of how that is possible.
Thanks.
Here's what I've been able to come up with; In HTML5 there is a <progress> element that you may be able to use. The bad news is that support for this element isn't as good as it could be. See the support chart here: http://caniuse.com/#search=progress There's no support in Safari 5 and below or IE9 and below. Partial support is in IE10 and any relevant versions of FireFox. If you need more support try a polyfil like this one: http://lea.verou.me/polyfills/progress/
If you choose to use the <progress> element here's a link about how to style it: http://www.useragentman.com/blog/2012/01/03/cross-browser-html5-progress-bars-in-depth/
Now the trick about making this work, you'll need to know the file size of the file(s) you'll be downloading and the number of bytes downloaded. As the files are being downloaded you'll have to get the header info that tells you how many bytes are transferred. You can see a sample of how to do that with jQuery here: http://markmail.org/message/kmrpk7w3h56tidxs#query:jquery%20ajax%20download%20progress+page:1+mid:kmrpk7w3h56tidxs+state:results
Note that this method will not work with IE. IE does not expose the header data of the XHR object.
At this point set the max attribute of the <progress> element to the total file size and using the setTimeout sample, update the value attribute of the <progress> element.
Knowing all this, maybe finding some kind of package solution with a built-in Flash fallback might be much easier to implement, and have better support. Anyone else have any ideas?
Good luck.

Stupefyingly weird IE 9 Javascript bug: Altering doc title makes subsequent code execute

I don't understand this at all. Here is some Javascript code that works in every browser but IE 9. It is called from a Flash movie using ExternalInterface, and is meant to dynamically resize the movie in the DOM if the size of the movie changes internally
function vResizeFlash(swfId, ht) {
document.getElementById(swfId).height = "100%";
document.getElementById('flashContainer').style.height = ht + "px";
}
But it works fine if I alter the document.title:
function vResizeFlash(swfId, ht) {
// IE 9 won't run the rest of this function unless
// we go through the charade of changing the document title.
if (navigator.appName.indexOf("Microsoft") != -1) {
var docTitle = document.title.replace(/^(.+?)\s*$/,"$1");
document.title = docTitle + " ";
}
// Well-coded browsers begin here
document.getElementById(swfId).height = "100%";
document.getElementById('flashContainer').style.height = ht + "px";
}
Here I simply trim any white-space from the right side of the document.title, then add a single white-space character to it. Suddenly the following lines get executed. Note: there are other ExternalInterface calls on the page, and all of them work fine, even in IE 9, so it's not a Flash/IE 9 problem.
I stumbled on the fix because I was altering the title to show the function arguments (as a quick debugging test), just to make sure the function was getting run. And suddenly the code worked. Take it out? Doesn't work. 100% reproducible.
Anybody know why this absolutely stupefying behavior takes place?
UPDATE
#c69 has posed the question: "Maybe its IE9's dead code remover?"
I didn't know about this, so I went and Googled and found this article on the topic, as well as some discussion of it elsewhere. I don't know enough about it to evaluate how this would affect a two-line Javascript function, however, especially since one of the lines does have a referent on the page (although it is late-loading through the SwfObject code). Still, it would be a pretty bad bug for a code "optimizer" to remove lines of code it deemed unnecessary because it doesn't understand how they are called. And if it did fail to understand how the lines are called, how does inserting a line making a bogus change to the document.title render that code suddenly "necessary"?
UPDATE 2
Another piece of the puzzle This may have something to do with IE 9's compatibility mode. The page starts out in IE 9's standards mode.
Now, if I turn on IE's compatibility mode,
the problem goes away without using the above hack. Turn it off, and the problem returns (if no hack present).
But when I tried to make a simple test using the exact same HTML (minus a couple of JSP tags) and a stripped down SWF that only contains the resize code and the tools to test, everything works fine. In that case, however, no compatibility icon is displayed at all.
We're using Tomcat 6.0.32. I'm not aware that we are using any special headers, and there are no meta tags regarding IE compatibility mode (in either the main app or in my test app).
like InvertedSpear mentions, check your doc type out, i've had problems with IE9 recently and most of it boiled down to the Doc type tags triggering a compatability mode i didn't need, the same can be true of the meta tags so it might boil down to your Meta tags.
You can always impose a working compatibility mode using the links below too.
from: http://evolpin.wordpress.com/2011/02/25/ie9-compatibility-and-the-meta-tag/
I’ve discovered that this is indeed documented by Microsoft…
http://msdn.microsoft.com/en-us/library/cc288325(VS.85).aspx
“The X-UA-Compatible header is not case sensitive; however, it must appear in the header of the webpage (the HEAD section) before all other elements except for the title element and other meta elements.”
Whenever I see something like this happen in any language it's because there is other code that has a bug. As you pointed out your simple case doesn't produce the problem. Try removing other code a few lines at a time until the problem disappears - the last removed code should contain the problem.
Cheers

Google Map Points Not Working in IE

I've got a problem with a Google map on a site I've been working on. The map has loads of points marked on it which are loaded from a database.
You can see the map here - http://www.vineyardchurches.org.uk
This works fine in Firefox and Chrome, but not in IE.
I read some other stuff that suggested that I needed to fire an onload event on the body tag for it to work with IE so I've done that, still no difference.
Any pointers would be greatly appreciated.
The real problem is around lines 41-43 of mapping.js.
You correctly use the form $(data) to convert an XML string into a DOM tree; however http://www.vineyardchurches.org.uk/getMappings.php includes the XML preamble <?xml version="1.0"?>, which is not part of a DOM Tree and cannot be parsed as such.
In this case you're just unlucky that Firefox and Chrome seem to ignore it.
Either make it so that getMappings.php does not print the XML header (though it would no longer be a valid XML document on its own; perhaps you could make this an option in the querystring), or strip it from the data variable before you tree-ise it (which may not be entirely efficient):
$(data.replace('<?xml version="1.0"?>','')).find("marker").each(...);

Safari issues with javascript + css

I have some strange behavior going on with safari, im using the jQuery.GridLayout plugin and css for styling.
Just for some context, this website layout is a simple header followed by the content which are a collection of blocks (each block is a div) positioned by the javascript and rearranged every time the window is re-sized.
When I direct safari to the website url all the blocks overlap to some degree (like 50%) but as I re-size the window if they have to move, automatically all goes to the correct place and only breaks if I refresh the page.
So it seems that loading the page is messing it up either because something fails to register or because something does not happen until I re-size the window.
As anyone experienced such behavior within safari?
It works perfectly in firefox and opera, its an valid html 4.01 transitional page and the css is also validated (wc3 wise that is).
I know that publishing the code is invaluable to sort this kind of issues but this is a production project and I'm obliged not to it.
Either way I appreciate any advice on were to start looking?
How do one goes about debugging this issues in safari?
Thank you.
Safari fires DomReady before linked resources are loaded. This race condition regarding calculating sizes of elements defined in CSS can usually be avoided by loading your CSS resources before any JavaScript (eg: make sure the tags appear in the before ANY tags (which are blocking, but give a change for CSS to load asynchronously). Worse case scenario, move your blocks to the last element in , leaving your tags above.
CSS concatenation of multiple files (if you have them) is also recommended.
If you aren't able to post the actual code of the page for us, you might find your solution while trying to reproduce the problem without your specific content. In the past, I've solved some of my own problems while trying to generate a page that shows the problem to post on IRC / SO. If you are able to reproduce the problem without your content, post it for the community, and an answer will be much easier to find.
My shot-in-the-dark guesses lead towards:
You may find that one of your content blocks is causing the issue.
You may find that a different library you are using is causing the issue.
Some javascript code for your layout may be running before everything is ready / filled in. From my memory, Safari is quick to display pages before images are loaded for instance.
Perhaps you need to specify the an exact width/height of some of your Grid Containers.
Small update:
(new update at bottom)
http://www.howtocreate.co.uk/safaribenchmarks.html
And also something that is working is this small script:
<script language="JavaScript">
// CREDITS:
// Automatic Page Refresher by Peter Gehrig and Urs Dudli www.24fun.com
// Permission given to use the script provided that this notice remains as is.
// Additional scripts can be found at http:
//www.hypergurl.com
// Configure refresh interval (in seconds)
var refreshinterval=20
// Shall the coundown be displayed inside your status bar? Say "yes" or "no" below:
var displaycountdown="yes"
// Do not edit the code below
var starttime
var nowtime
var reloadseconds=0
var secondssinceloaded=0
function starttime() { starttime=new Date() starttime=starttime.getTime() countdown()
} function countdown() { nowtime= new Date() nowtime=nowtime.getTime() secondssinceloaded=(nowtime-starttime)/1000
reloadseconds=Math.round(refreshinterval-secondssinceloaded) if (refreshinterval>=secondssinceloaded)
{ var timer=setTimeout("countdown()",1000) if (displaycountdown=="yes")
{ window.status="Page refreshing in "+reloadseconds+ " seconds"
} } else { clearTimeout(timer) window.location.reload(true) } } window.onload=starttime
</script>
I find it odd that a refreshing script solves the issue in safari, but if i manually refresh the page the page havoc ensues...
########UPDATE##########
Well I finally got some more time to work on this and after doing some reading a rather obvious thing came to my mind, let the content load and then format it, so for now all of my js sits between </body> and </html>.
Its not perfect since now you can catch a glimpse of the content without being properly placed when the page first loads.
Maybe ill try calling the js a second time after a few ms have passed of loading.
I know this was proposed a bit upper the thread I just needed time to get my hands dirty thanks all, Ill keep updating till I get it solved in a more proper fashion :)

Categories

Resources