How to force immediate javascript parsing / execution - javascript

The following is the outline of www.abc.com/index.html
<html>
<head>
..
..
</head>
<body>
<script>
var js1 = document.createElement('script');
js1.type = "text/javascript";
js1.async = true;
js1.src = "cdn/js1.js";
document.getElementsByTagName('head').appendChild(js1);
console.log('Start: ' + new Date().getTime());
</script>
<img src="img1.jpg">
<img src="img2.jpg">
....
</body>
</html>
This is the contents of js1.js
console.log('End: ' + new Date().getTime());
var img = new Image();
img.src = "img3.jpg";
var f1 = function() {
..
}
var f2 = function() {
..
}
...
The observation is that there is a pretty large difference being observed between the 'End' and 'Start' outputs. In the browser network tab, I find that this is the order of network requests being made:
js1.js
img1.jpg
img2.jpg
img3.jpg
The question is - why does it take so long for the script to begin executing? I tried removing the other images from the page, this causes the script to execute much quicker. Why do the other requests execute before the script executes (I find this happens even if the call is made synchronously)? Is there a way to make the script execute completely first before the rest of the page does?

Related

Displaying Page Load Time On Webpage

I want to display the loading time of a webpage on site. I can get this working by writing to console.log but writing the information to a page is beyond me.
In my head I have
<!-- Loading Time -->
<script type="text/javascript">
var loadTime = window.performance.timing.domContentLoadedEventEnd- window.performance.timing.navigationStart;
</script>
Then I have this to write to the console log
<script type="text/javascript">
window.onload = function () {
var loadTime = window.performance.timing.domContentLoadedEventEnd-window.performance.timing.navigationStart;
console.log('Page load time is '+ loadTime / 1000);
}
</script>
This works perfectly but I really want to display the loading time on a webpage. How do I achieve this? My page is a simple html / css site.
Three possible methods are:
Just writing to the document directly (should not be used because of the reasons described here):
document.write(loadTime);
Adding an HTML element and setting its inner text to loadTime:
function displayLoadtime(loadtime){
document.getElementById("loading-time").innerText = loadtime;
}
<p id='loading-time'>Loading...</p>
Creating the element in Javascript and displaying the loadTime using it:
function displayLoadingtime(loadtime){
let p = document.createElement("p");
p.innerText = loadtime;
document.getElementById("loading-time-container").appendChild(p);
}
<div id='loading-time-container'></div>
I know what I answered is some beginners' stuff and you probably know it, but I will edit the answer in case you give more details, because I don't see any problems in displaying it if you already have the loadTime.
You can write the time you calculated into an element of the webpage using the innerText property of a Node.
window.onload = function() {
var loadTime = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart;
console.log('Page load time is ' + loadTime / 1000);
performanceDisplay = document.getElementById("performance-display") // get a reference to the paragraph
performanceDisplay.innerText = loadTime / 1000 // put the value of the variable loadTime into the paragraph
}
<body>
<p id="performance-display"></p>
</body>
Or, if you do not want to put the paragraph manually into the HTML, you can create it in the JavaScript using document.createElement:
window.onload = function() {
var loadTime = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart;
console.log('Page load time is ' + loadTime / 1000);
performanceDisplay = document.createElement("p") // create a new paragraph element
performanceDisplay.innerText = loadTime / 1000 // put the value of the variable loadTime into the paragraph
document.body.appendChild(performanceDisplay) // add the paragraph element to the body of the document
}
Welcome to StackOverflow, Rylad!
You can easily put it into your webpage by referencing an HTML element.
Ie. add an element with the id timeContainer to your page and set its innerHTML to your variable, loadTime. Here's an example:
<body>
<span id="timeContainer">
The load time will be displayed here when the page is finished loading
</span>
<script type="text/javascript">
window.onload = function() {
var loadTime = window.performance.timing.domContentLoadedEventEnd - window.performance.timing.navigationStart;
console.log(loadTime)
document.getElementById("timeContainer").innerText = loadTime;
}
</script>
</body>
Try this,
Simple way to get loading time
<body>
<span id="loadingTime"></span>
<script>
window.addEventListener('load', (e) => {
let timestemp = new Date(e.timeStamp).getTime()
console.log('loading time is', timestemp)
document.getElementById('loadingTime').innerText = "loading time is "+timestemp
})
</script>
</body>

execute script on the page that will open by clicking href javascript

I am currently working on features that infuencent web loading. I succeeded
to find a script that displays those .But my problem how to execute this script on the page that will open by clicking href
<html>
<head>
<script type="text/javascript">
// Add load event listener.
window.addEventListener("load", loadTime, false);
function loadTime() {
var x = performance.timing.connectEnd+"f";
// Get current time.
var now = new Date().getTime();
// Calculate page load time.
var page_load_time = now - performance.timing.navigationStart;
// Write the load time to the F12 console.
if (window.console) { console.log(window.performance.timing);
window.alert(x)}
}
</script>
<script>
var someAnchor = document.getElementById('someAnchor');
someAnchor.onclick = function(){
loadTime();
};
function loadTime() {
// Get current time.
var now = new Date().getTime();
// Calculate page load time.
var page_load_time = now - performance.timing.navigationStart;
// Write the load time to the F12 console.
if (window.console) {
console.log(window.performance.timing);
}
}
</script>
</head>
<body>
<a id="someAnchor" target="_blank" href="https://www.youtube.com/">youtube</a>
</body>
</html>
The first script shows these carachteristics on current page but the second does not work on load youtube page
so you basically just want to run your function upon clicking an anchor?
var someAnchor = document.getElementById('someAnchor');
someAnchor.onclick = function(){
loadTime();
};
function loadTime() {
// Get current time.
var now = new Date().getTime();
// Calculate page load time.
var page_load_time = now - performance.timing.navigationStart;
// Write the load time to the F12 console.
if (window.console) {
console.log(window.performance.timing);
}
}
<a id="someAnchor" href="#">some anchor</a>
What you want to do is illegal and impossible, because of security reasons, once you close a page or navogate away from it, every javascript function will stop immedialitely. Just imahine what would happen, if a page would navigate you back every time you leave it.

Why does calling a function onclick not work all the time in Chrome and FF, but works in IE?

I have the below code:
<HTML>
<HEAD>
<SCRIPT>
function myFunction(atlasTrackingURL)
{
var atlasURL = atlasTrackingURL;
if (!atlasURL) return;
//Build a cache busting mechanism
var timestamp = new Date();
var queryString = "?random=" + Math.ceil(Math.random() * 999999999999) +
timestamp.getUTCHours() + timestamp.getUTCMinutes() +
timestamp.getUTCSeconds();
//Build the final URL
atlasURL = atlasURL + queryString;
if (!document.getElementsByTagName || !document.createElement
|| !document.appendChild)
{return false;}
else
{ //Activate the JACTION call
var script = document.createElement("script");
script.type = "text/javascript";
script.src = atlasURL;
document.getElementsByTagName("head")[0].appendChild(script);
return true;
}
}
</SCRIPT>
</HEAD>
<BODY>
Test - Click Me
</BODY>
</HTML>
It works in Internet Explorer every time, but rarely works in Chrome and Firefox. Why would this be?
Can these browsers not handle a function onClick very well? Are there any other options I can take?
I am trying to help a client figure out why one of their tracking tags are not firing off all the time on click in these browsers.
Thanks,
You've got some kind of browser-dependent race condition going on, as Musa pointed out.
Try hiding the link initially, waiting for the document to load, and then adding the onclick attribute and revealing the link with javascript.
So, for example, change the link HTML to something like:
<a id="microsoft-link" href="http://www.microsoft.com" style="display: none;">Test - Click Me</a>
And add in your javascript, below the myFunction(), something like:
document.addEventListener('DOMContentLoaded', function(){
var link_elem = document.getElementById("microsoft-link");
link_elem.onclick = function() {
myFunction('http://view.atdmt.com/jaction/adoakb_PiggybackJSTest_1');
};
link_elem.style.display = 'inherit';
});
jsfiddle -- http://jsfiddle.net/m8VTy/3/
edit: I realized I may be misinterpreting what you're trying to do. What exactly is myFunction() supposed to accomplish ?

JavaScript synchronization

I don't know how I can synchronize next code:
javascript: (function() {
var s2 = document.createElement('script');
s2.src = 'http://192.168.0.100/jquery.js';
document.body.appendChild(s2);
s = document.createElement('link');
s.rel = "stylesheet";
s.href = "http://192.168.0.100/1.css";
s.type = "text/css";
document.body.appendChild(s);
})();
//var startTime = new Date().getTime();
//while (new Date().getTime() < startTime + 1000);
$(document).ready(function(){
b="c:\\1.txt";
var fso, f1;
fso = new ActiveXObject("Scripting.FileSystemObject");
f1 = fso.CreateTextFile(b, true);
f1.WriteLine("Testing") ;
document.writeln("File " + b + " is created.");
});
When I run this script at first I get an error SCRIPT5009: '$' is undefined. I think that is because jQuery library is yet no loaded. When I try to run the same script after error's appearencing - it behavior is corect. For synchonization I try to use code that is commented in upper listing. Is works (not always). But I understand that is no strict synchronization (it dependet of concrete situation). How can I use more clever synchronization?
(function($){
//use $ now
$(function(){
//dom ready
});
})(jQuery);
Be sure to load this libary in the footer below the jquery library.
This is due to the fact that putting in the script tag via appendChild dhtml method makes it evaluate async. To listen for it getting 'ready' as youre doing it on the document - follow this pattern
(function() {
var s2 = document.createElement('script');
s2.src = 'http://192.168.0.100/jquery.js';
document.body.appendChild(s2);
s2.onload = s2.onreadystatechange = function(){
if(s2.readyState == "complete") $(document).ready(function(){
b="c:\\1.txt";
var fso, f1;
fso = new ActiveXObject("Scripting.FileSystemObject");
f1 = fso.CreateTextFile(b, true);
f1.WriteLine("Testing") ;
document.writeln("File " + b + " is created.");
});
}
s = document.createElement('link');
s.rel = "stylesheet";
s.href = "http://192.168.0.100/1.css";
s.type = "text/css";
document.body.appendChild(s);
})();
The issue is that the line with the $ is being hit when the script tag has been added but before the file has been downloaded. Normally browsers block while loading JavaScript which prevents this issue, but since you're doing it programatically you don't get the standard synchrony.
Your best bet would be to wait for the script to be loaded. There's information here:
Dynamic, cross-browser script loading
On catching the load event for the completion of the script download. You can then call your existing $ ready function as a callback to that event. I'd suggest using a loader that is made for this stuff, or just use a standard script tag in the DOM unless you have a compelling reason not to.

How to force a script reload and re-execute?

I have a page that is loading a script from a third party (news feed). The src url for the script is assigned dynamically on load up (per third party code).
<div id="div1287">
<!-- dynamically-generated elements will go here. -->
</div>
<script id="script0348710783" type="javascript/text">
</script>
<script type="javascript/text">
document.getElementById('script0348710783').src='http://oneBigHairyURL';
</script>
The script loaded from http://oneBigHairyURL then creates and loads elements with the various stuff from the news feed, with pretty formatting, etc. into div1287 (the Id "div1287" is passed in http://oneBigHairyURL so the script knows where to load the content).
The only problem is, it only loads it once. I'd like it to reload (and thus display new content) every n seconds.
So, I thought I'd try this:
<div id="div1287">
<!-- dynamically-generated elements will go here. -->
</div>
<script id="script0348710783" type="javascript/text">
</script>
<script type="javascript/text">
loadItUp=function() {
alert('loading...');
var divElement = document.getElementById('div1287');
var scrElement = document.getElementById('script0348710783');
divElement.innerHTML='';
scrElement.innerHTML='';
scrElement.src='';
scrElement.src='http://oneBigHairyURL';
setTimeout(loadItUp, 10000);
};
loadItUp();
</script>
I get the alert, the div clears, but no dynamically-generated HTML is reloaded to it.
Any idea what I'm doing wrong?
How about adding a new script tag to <head> with the script to (re)load? Something like below:
<script>
function load_js()
{
var head= document.getElementsByTagName('head')[0];
var script= document.createElement('script');
script.src= 'source_file.js';
head.appendChild(script);
}
load_js();
</script>
The main point is inserting a new script tag -- you can remove the old one without consequence. You may need to add a timestamp to the query string if you have caching issues.
Here's a method which is similar to Kelly's but will remove any pre-existing script with the same source, and uses jQuery.
<script>
function reload_js(src) {
$('script[src="' + src + '"]').remove();
$('<script>').attr('src', src).appendTo('head');
}
reload_js('source_file.js');
</script>
Note that the 'type' attribute is no longer needed for scripts as of HTML5. (http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#the-script-element)
Creating a new script tag and copying the contents of the existing script tag, and then adding it, works well.
var scriptTag = document.createElement('script');
scriptTag.innerText = "document.body.innerHTML += 'Here again ---<BR>';";
var head = document.getElementsByTagName('head')[0];
head.appendChild(scriptTag);
setInterval(function() {
head.removeChild(scriptTag);
var newScriptTag = document.createElement('script');
newScriptTag.innerText = scriptTag.innerText;
head.appendChild(newScriptTag);
scriptTag = newScriptTag;
}, 1000);
This won't work if you expect the script to change every time, which I believe is your case. You should follow Kelly's suggestion, just remove the old script tag (just to keep the DOM slim, it won't affect the outcome) and reinsert a new script tag with the same src, plus a cachebuster.
Small tweak to Luke's answer,
function reloadJs(src) {
src = $('script[src$="' + src + '"]').attr("src");
$('script[src$="' + src + '"]').remove();
$('<script/>').attr('src', src).appendTo('head');
}
and call it like,
reloadJs("myFile.js");
This will not have any path related issues.
Use this function to find all script elements containing some word and refresh them.
function forceReloadJS(srcUrlContains) {
$.each($('script:empty[src*="' + srcUrlContains + '"]'), function(index, el) {
var oldSrc = $(el).attr('src');
var t = +new Date();
var newSrc = oldSrc + '?' + t;
console.log(oldSrc, ' to ', newSrc);
$(el).remove();
$('<script/>').attr('src', newSrc).appendTo('head');
});
}
forceReloadJS('/libs/');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
I know that is to late, but I want to share my answer.
What I did it's save de script's tags in a HTML file,
locking up the scripts on my Index file in a div with an id, something like this.
<div id="ScriptsReload"><script src="js/script.js"></script></div>
and when I wanted to refresh I just used.
$("#ScriptsReload").load("html_with_scripts_tags.html", "", function(
response,
status,
request
) {
});

Categories

Resources