I'm using a CMS which has a lot of javascript, both in size and quantity.
I'm trying to add iframe.ly to it so that card previews can be generated for posted URLs.
It works perfectly fine on all pages except for ones that have posts (which are the most important), since posts are loaded via a javascript called stream, and it seems that iframely's script is loading before the stream.
I know this is the issue because I can trigger the script directly using iframely.load(), which does the trick. But I need this to happen automatically on every page load.
This is the script that I added to my header: <script defer charset="utf-8" src="//cdn.iframe.ly/embed.js?key=[my-api-key]" ></script>
Iframely offers another option in their docs, which is this:
<script defer type="text/javascript">
function loadIframelyEmbedJs() {
// Replace 'iframe.ly' with your custom CDN if available.
if (document.querySelectorAll("[data-iframely-url]").length === 0
&& document.querySelectorAll("iframe[src*='iframe.ly']").length === 0) return;
var iframely = window.iframely = window.iframely || {};
if (iframely.load) {
iframely.load();
} else {
var ifs = document.createElement('script'); ifs.type = 'text/javascript'; ifs.async = true;
ifs.src = ('https:' == document.location.protocol ? 'https:' : 'http:') + '//cdn.iframe.ly/embed.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ifs, s);
}
}
// Run after DOM ready.
loadIframelyEmbedJs();
</script>
This is supposed to make iframely "load only when required", as in when embeds are detected in the page. But that doesn't fix the problem either because that too is loaded before the stream.
I don't mind using jquery if needed.
Edit: Removed mentions of the CMS. It adds unnecessary confusion. This is a javascript question.
Fixed it by wrapping it in this function:
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "//cdn.iframe.ly/embed.js?key=[my-api-key]";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
Strange that it's so hard to achieve something like this, or find information on how to do it.
Source: Some SEO website that I can't find anymore.
Related
This question already has answers here:
How do I include a JavaScript file in another JavaScript file?
(70 answers)
Closed 6 years ago.
I am trying to add a script tag dynamically through Javascript in my HTML page. Just after the code I am trying to call a few functions of the newly added script. However, I am getting JS errors because by that time the script has not loaded yet. I have gone through multiple posts but none of them explains how to execute your script added explicitly.
You need to listen for the onload event of your newly added script, or onreadystatechange for IE < 11.
var script = document.createElement('script');
script.onload = function() {
// it's ready, so call your functions here
}
// now insert your new script into the document
For IE < 11:
script.onreadystatechange = function() {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
// it's ready, so call your functions here
}
}
This will allow you to execute scripts when and only when the whole page has loaded. There are other ways to do this but I think this one is simple and effective:
<script>
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = './js/ding.js';
document.body.appendChild(element);
var element1 = document.createElement("script");
element1.src = './js/dong.js';
document.body.appendChild(element1);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
Place it on your page at the end of the body tag. Anything imported by this block of code will execute dead last, ensuring all scripts called in the head will be there.
I use this pattern all over the place because it is semantic. My 'library' type scripts are loaded in my head, and then my custom code waits for the whole dom to render before it executes.
Google said my page was rather slow and showed me some 'techniques' to defer load those JS.
Apparently, after I used the technique, it seems that my site other scripts doesn't load because it's slower than External Script fetching. Specifically:
SCRIPT :
function downloadJSAtOnload() {
var jq = document.createElement("script");
jq.src = "path/to/jquery.min.js";
document.body.appendChild(jq);
var bs = document.createElement("script");
bs.src = "path/to/bootstrap.min.js";
document.body.appendChild(bs);
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
//Scripts here aren't able to load even though jquery is called above
$('.tips').tooltip();
$(document).ready(function() {/**something here**/
});
How can I solve this problem?
I'm using joomla site, and Forced to use extra java script.
My Question is:
How to force loading the javascript ONLY after page complete
I dont mean DELAY them, But make them in Queue till the page complete loading.
I tried many of links tutorial but nothing helps me.
Please,
Would you provide correct example in order to make me understand.
Example to JS file I inserted to buttom of my page:
<script src="/js/easing.js" type="text/javascript"></script>
Can you provide Jquery code to force all those script to wait till the page load complete?
Thank you
Tariq
Ales Kotnik answer's in great, and also if you want to do it in your own specifiec time, you can do something like that:
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
this will load a script only when you call it, and then you activate it like this:
<script type="text/javascript" src="http://your.cdn.com/first.js"></script>
<script type="text/javascript">
loadScript("http://your.cdn.com/second.js", function(){
//initialization code
});
</script>
Use <script src="..." async="async"/>. In modern browsers (HTML5)it will spawn fetching javascript files separately and won't delay loading of your HTML. You can just put script tags at the end of your <body>.
If you would like to get to the point, here is my question:
Is there any way to call a specific script to load first in javascript?
For more detail, please read below:
I have a javascript file that is loading from the bottom of my HTML <body>. Unfortunately, there is no JQuery in the head, so I have to add it through this javascript file.
What I need to do is add a JQuery lightbox plugin.
My problem is that when I load the page, sometimes JQuery isn't the first thing loaded. So I receive the error "jQuery is not defined". Which will then raise more errors for undefined methods from the plugin.
This doesn't happen all the time, only sometimes. Which makes me think it's a loading/order of operations issue.
Is there any way I can guarantee that my JQuery script is the first thing loaded?
Here is some of my javascript file.
//Get head element
var head = document.getElementsByTagName("head")[0];
//Create and insert JQuery
var jquery = document.createElement('script');
jquery.type = 'text/javascript';
jquery.src = 'http://image.iloqal.com/lib/fe6b/m/1/jquery.1.7.2.js';
head.insertBefore(jquery,head.childNodes[4]);
function thescripts() {
var fancybox = document.createElement('script');
fancybox.type = 'text/javascript';
fancybox.src = 'http://image.iloqal.com/ilejquery.fancybox-1.3.4.pack.js';
head.appendChild(fancybox);
var thebody = document.getElementsByTagName('body')[0];
thebody.appendChild(thediv);
thediv.appendChild(theimg);
//Run fancybox
thebody.onload = function() {
$('#lightbox').ready(function() {
$("#lightbox").fancybox().trigger('click');
});
}
};
if(jquery.attachEvent){
jquery.attachEvent("onload",thescripts());
} else {
jquery.onload = thescripts();
}
Any help is appreciated!
Try this. Add this piece of code inside your javascript file which is called from your footer.
<script type="text/javascript">
if(typeof jQuery == 'undefined'){
document.write('<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></'+'script>');
}
</script>
This will include jquery if its not loaded. I think this will fix your issue.
Using $(function() {...do your stuff here...}); is the way to go to be sure jQuery is loaded before the script is executed, but you could probably make it harder for yourself and do:
thebody.onload = function() {
RunMyjQuery();
}
function RunMyjQuery() {
if (typeof $ === 'undefined') {
setTimeout(RunMyjQuery, 500);
}else{
$('#lightbox').ready(function() {
$("#lightbox").fancybox().trigger('click');
});
}
}
You're calling thescripts immediately, although you try not to. Use this:
jquery.onload = thescripts; // notice no parentheses
Also, your thebody.onload strategy will not work. Use $(document).ready instead:
$(document).ready(function{
$('#lightbox').ready(function() {
$("#lightbox").fancybox().trigger('click');
});
});
All of my JavaScript files are already at the bottom but Google Page Speed is giving this suggestion to improve speed:
Defer parsing of JavaScript
88.6KiB of JavaScript is parsed during initial page load. Defer
parsing JavaScript to reduce blocking of page rendering.
http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
(76.8KiB) http://websiteurl/js/plugins.js (11.7KiB) http://websiteurl/
(109B of inline JavaScript)
This is the my html (example)
<html>
<head>
<!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<head>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.5.1.min.js"%3E%3C/script%3E'))</script>
<script src="js/plugins.js"></script>
<script>$(document).ready(function() {
$("#various2").fancybox({
'width': 485,
'height': 691,
});
});</script>
</body>
</html>
What should I do to increase performance by using defer?
Is it only for Google chrome or for all?
If you're looking for page performance then first and foremost you should move those scripts to the bottom of your page to allow the other assets to load.
Also use dns prefetch in the head to set the base domain for google-code
<link rel="dns-prefetch" href="//ajax.googleapis.com">
Since this is just a small piece of code, you could simply add it to your plugins.js file at the bottom then defer the plugins file.
<script src="js/plugins.js" defer></script>
That's what I'd do anyway, all my sites are optimized to 98 and 97 respectively in yslow and page speed.
Hope it helps.
-V
Add in <script type="text/javascript" defer="defer"> tag like that it works for me.
<script type="text/javascript" defer="defer" src="<?php echo $this->getSkinUrl();?>js/jquery.bxslider.js"></script>
I see this is an old question, but since I was looking for a good answer myself, I am going to share the method I currently use.
As far as inline Javascript is concerned, what I do is change all the type attributes to text/deferred-javascript, or something similar, so that the code within the script tag is not evaluated during page load. Then I attach a function to the page onload event; said function finds all the scripts matching the type above and evaluates the code inside using eval(). I know in general eval() is evil but it seems to be helpful here.
For external Javascript files, I do something very similar. Instead of adding the script tags to the page, I record them and insert them one-by-one after page load has completed.
One problem I'm having is that if one of the inline deferred Javascript contains an error (say a parse error), the subsequent scripts are not loaded (but that might depend on my current implementation).
That's probably a generic response/suggestion for when it encounters a certain level of performance.
Although, it specifically mentions jQuery, a plugin, and 109 bytes of inline JavaScript. Do you have any inline JavaScript? Are you also placing your JavaScript includes at the bottom of the <body>?
Example
Loading Performance article
EDIT:
Based on recently posted HTML...
As a test, remove these two items to see if it makes any difference:
<!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.5.1.min.js"%3E%3C/script%3E'))</script>
Also, the warning message mentions 109 bytes of inline JS, yet I don't see anything like that in the HTML you've posted.
Hi recently we have created an opensource nodejs framework called "elegant framework" that help you building fast web application and we succeeded to get 100% google page speed in both desktop and mobile in all pages :
you can check it at:
https://developers.google.com/speed/pagespeed/insights/?url=getelegant.com
there is a lot of things you can learn from it by viewing the page source also if anything you cannot understand please comment so i can help you with
so far you can try this method:
// Load script element as a child of the body
function loadJS(src, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
if (callback) {
callback();
}
}
};
} else { //Others
script.onload = function () {
if (callback) {
callback();
}
};
}
script.src = src;
document.body.appendChild(script);
}
// Load style element as a child of the body
function loadCSS(href,callback) {
var element = document.createElement("link");
element.rel = "stylesheet";
if (element.readyState) { //IE
element.onreadystatechange = function () {
if (element.readyState == "loaded" || script.readyState == "complete") {
element.onreadystatechange = null;
if (callback) {
callback();
}
}
};
} else { //Others
element.onload = function () {
if (callback) {
callback();
}
};
}
element.href = href;
document.body.appendChild(element);
}
// Load All Resources
function loadResources() {
// css
loadCSS("/compressed/code-mirror-style.css?please1");
loadCSS("/compressed/all.css?please2");
// js
loadJS("/compressed/code-mirror.js", function () {
loadJS("/compressed/common.js", function () {
$("[data-lang]").each(function () {
var code = $(this).addClass("code").text();
$(this).empty();
var myCodeMirror = CodeMirror(this, {
value: code,
mode: $(this).attr("data-lang"),
lineNumbers: !$(this).hasClass('inline') && !$(this).hasClass('no-numbers'),
readOnly: true
});
});
});
});
}
// Check for browser support of event handling capability
if (window.addEventListener) {
window.addEventListener("load", loadResources, false);
} else if (window.attachEvent) {
window.attachEvent("onload", loadResources);
} else {
window.onload = loadResources
}