I have just realized a major slowdown in my app. I use modal dialogs to load other pages of my site into a pop up. Up until recently these loaded very fast. Lately they are taking a vary long time, about 4 seconds. I did some profiling and it seems that my javascript isn't loading asynchronously, each one waits until the other has completed downloading.
This seems to be the major slow down. Each javascript file is just included in the loaded page like so...
<script src="/js/jquery.ae.image.resize.min.js"></script>
<script type="text/javascript" src="/js/jquery.raty.min.js"></script>
<script type="text/javascript" src ="/js/entry.js"></script>
<script type="text/javascript" src="/js/bjqs-1.3.min.js"></script>
I sort of fixed this by moving these files to the page showing the dialogs, but that seems like a hack, especially when they were loading fast enough in the past. Also, this isn't dynamic javascript so it can be cached, I think the time parameters come from $.ajaxSetup({ cache: false }); but that isn't a recent code addition.
If you want to load scripts asynchronously, async attribute helps:
<script async="true" type="text/javascript" src ="/js/entry.js"></script>
Related
With my somewhat limited JavaScript knowledge I'm trying to get a particular script execution order nailed. I'm using JQuery for this.
I have a main page using JQuery which, when it is fully loaded, dynamically adds an iframe, in which it loads an extra page. I want another piece of script in the main page to run once the initial scripts in the extra page have fully ran. (So just the regular inline scripts, I don't care about setTimeout scripts in the extra page). The extra page always registers it's script to run using JQuery's $(document).ready (it's something I have no control over).
What I ended up with and what works for me in FireFox and Edge is this:
Main page:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
console.log('main: loading')
$(document).ready(function() {
console.log('main: ready')
let iframeElement = $('<iframe></iframe>').appendTo($('body'))
iframeElement.on('load', function() {
console.log('main: iframe loaded')
setTimeout(function() {
console.log('main: after iframe loaded')
}, 0)
})
iframeElement.attr('src', 'extra.html')
})
</script>
</head>
<body>Main</body>
</html>
Extra page:
<html>
<head>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script>
console.log('extra: loading')
$(document).ready(function() {
console.log('extra: ready')
})
</script>
</head>
<body>Extra</body>
</html>
In FireFox the events are logged in this order:
main: loading
main: ready
extra: loading
main: iframe loaded
extra: ready
main: after iframe loaded
I don't give a hoot for 3 and 4, but what's important for me is that 6 always fires after 5. The only way I could get it to work that way is by both registering a handler using on('load') on the iframe instead of using JQuery's ready on it, and using setInterval in that handler to further delay the handler. If I do it any other way, 5 and 6 get inverted.
I just read up on the defer option for loading scripts, which does seem promising, but I can't control it's usage (I only have control over a single JavaScript file that is loaded in the main page). And to my current knowledge the page's onload event fires after JQuery's ready event, which in turn occurs at an equivalent time as the DOMContentReady event, right? But it's mainly the parallel event order between the two pages involved here I'm quite unsure of.
So what I fail to grasp is if this is the correct way to do it, and whether there are more sure-fire / correct ways to achieve the same. And whether it works in Chrome too, since I haven't installed that thing on this laptop :) And ofc any other tips wrt my (ab)use of JavaScript are welcome too :)
I am using a banner ad from an ad service provider, similar to google adsense.
Instruction from their site state clearly and simply that all we need to do is to copy the below code to the body of our webpage
<!-- Begin Hsoub Ads Ad Place code -->
<script type="text/javascript"><!--
hsoub_adplace = [my account id];
hsoub_adplace_size = '728x90';
//--></script>
<script src="http://ads2.hsoub.com/show.js" type="text/javascript"></script>
<!-- End Hsoub Ads Ad Place code -->
I have copied and pasted into my rails app, inside a body of a view file but the banner is not getting displayed and I can see javascript error (with browser inspect source)
TypeError: document.getElementById(...) is null
ps: On old browsers the banner is getting displayed but never on recent versions of browsers.
ps2: The support of hsoub confirmed multiple times, there is no problem from their side (their code is fine and working on thousands of websites, and my account is active with no issues). And it must be a problem from my code.. I am thinking the way Rails handles javascript...
Can you please help me solve this error and get the banner displayed.
ps3: I am using rails 6.0.1 and turbolinks 5.2.0
you can check the error/source code online at https://tafqit.com/
The problem is caused by Rocket Loader feature of CloudFlare cdn service
Rocket Loader improves paint times for pages that include Javascript.
Visitors will have a better experience by seeing content load faster
and speed is also a factor in some search rankings.
Rocket Loader improves paint times by asynchronously loading your
Javascripts, including third party scripts, so that they do not block
rendering the content of your pages.
I disabled it and banner is appearing now.
I am going to guess that this is a script positioning issue. It looks like the script is possibly looking for elements that are not rendered yet, i.e. the document and document body is not ready. Move the scripts to the end of the page i.e. after the body tags and see if that helps. Otherwise please add the exact error and perhaps show a condensed view of your page and the scripts relative to the other elements.
<!DOCTYPE html>
<html>
<head></head>
<body>
<h1>Hello world</h1>
</body>
<script type="text/javascript">
hsoub_adplace = 12345;
hsoub_adplace_size = '728x90';
</script>
<script src="http://ads2.hsoub.com/show.js" type="text/javascript"></script>
</html>
I managed to get the iframe to load by moving the scripts
Scripts are (still) inside the body tags.
I am developing an HTML5 game with jQuery. However, sometimes the page hangs up when loading (For now I only saw this happen on Chrome for mac). When it hangs, sometimes there is a string "waiting app cache" at the bottom. The webpage won't respond to any user mouse event during that time. The same will happen even if you reload the page. However, if you go to settings and clear cached images and files, the webpage won't hang on loading again.
I have no idea why this happen. There is no error in the console so I don't know where the problem could be. What's worse, when the webpage hangs it will be hard to even open the debug console. Any ideas or guesses as to why this happens? Thanks in advance!
Follow up, my javascript entry point:
$(window).ready(function() {
middleLayerInitialize();
initialize();
addEventListeners();
});
Here is how I include jQuery:
<link rel="stylesheet" href="./styles/jquery.mobile-1.3.2.css" />
<script type="text/javascript" src="./js/jquery-1.10.1.js"></script>
<script type="text/javascript" src="./js/jquery.mobile-1.3.2.js"></script>
<script type="text/javascript" src="./js/jquery.mousewheel.js"></script>
The two most common reasons for this are (1) you are including jQuery twice or (2) you are loading a ton of html and jQuery has to wait on your html to finish loading. If you download jQuery directly into your directory and include it in the HTML header, it may help.
http://jquery.com/download/
<head>
<script src="jquery-1.11.0.min.js"></script>
</head>
Make sure that you aren't downloading it like below.
<head>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.0.min.js"></script>
</head>
And make sure there is only one line including jQuery.
A final option (least likely to help). I don't know your setup, but try:
$(document).ready(function() {
// put all your javascript here.
});
instead of using (window).ready. I say this because you usually don't use (window).ready. You either use what I have written above or
window.onload=function(){SomeJavaScriptCode};
<script type="text/javascript"
src="http://s7.addthis.com/js/250/addthis_widget.js"></script>
I am using this code for facebook, twitter etc, but there is a script in this which makes the page loading speed extremely slow. Can you please help with the solution for this, the entire code is below
<!-- AddThis Button BEGIN -->
<div class="addthis_toolbox addthis_default_style ">
<a class="addthis_button_preferred_1"></a>
<a class="addthis_button_preferred_2"></a>
<a class="addthis_button_preferred_3"></a>
<a class="addthis_button_preferred_4"></a>
<a class="addthis_button_compact"></a>
<a class="addthis_counter addthis_bubble_style"></a>
</div>
<script type="text/javascript">
var addthis_config = {
"data_track_addressbar": true
};
</script>
<script type="text/javascript"
src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4dfeea6f5bf22ac6">
</script>
<!-- AddThis Button END -->
Besides moving everything to the bottom of the page as Mudshark already said, you can also use the async addthis version:
http://support.addthis.com/customer/portal/articles/381221-optimizing-addthis-performance#.USyDXiVuPYo
<script type="text/javascript" src="http://s7.addthis.com/js/250/addthis_widget.js#async=1"></script>
function initAddThis(){
addthis.init()
}
// After the DOM has loaded...
initAddThis();
One of the solutions would be to use deferred JavaScript loading pattern for AddThis library.
There are several nice JavaScript libraries helping you out with that problem. I personally use mostly Modernizr.load (or yepnope.js by itself)
You can read more on that issue and improvement in Improve Your Page Performance With Lazy Loading article.
As a side note, I was able to improve page load by about 35% average in my past projects by using deferred JavaScript loading patter. I hope that will help.
One obvious thing to do would be to move the javascript to the bottom of your page, right before </body> so that everything else can load before it.
put async="async" attribute to your script tag
<script type="text/javascript"
src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4dfeea6f5bf22ac6" async="async">
</script>
There are few things to note:
you really don't need to load addthis immediately, you can load it relatively late during page rendering process,
addthis .js file is huge, currently around 118kb, minimized and gzipped (sic!),
due to its size it will always take relatively a lot of time for browser to compile and process it, especially on mobile devices.
Using async attribute in the script tag might help, however browsers consider mostly network resources when they see the attribute. Browsers don't take into account what impact the script might have on CPU usage, page rendering tree etc. (in browsers defence there's no way for them to determine it). For example scripts that take a long time to execute might block rendering of first frame or other crucial early paints. Even if we ignore network resources (connection slot, bandwidth etc.) required to fetch the addthis .js file it still may turn out that the script has severe impact on page loading process.
Note that while the async attribute hints browser that the resource can be loaded asynchronously it says nothing about the script execution when it is finally retrieved. JS in browsers is mostly single threaded and once browser start to process the .js file it can't back out of it and it has to let it finish running.
On my computer, evaluating the script in Chrome takes ~130-140ms and it blocks ParseHTML event for that long. On less powerful mobile devices it may easily jump to 500ms.
Because addthis is so big it would be best give browsers a little help and defer .js file fetch until other, more important components of page are displayed. You should use dedicated .js deferring library for this task to make sure that it is processed after DOMContentLoaded event and after other important resources are processed. I personally use Lab.js for this as it's small and does its job well.
Note also that there exists defer attribute that you can add to script tag, however specification clearly states that the script with defer tag present has to be processed before DOMContentLoaded event - so no wins here.
I am using EmbeddedWB (A TWebbrowser extension) to do like a "live preview" of some dynamically generated content.
I am trying to add jQuery into the mix, so I can get some fancy effects going on, however since IE9 always asks "Allow blocked content" for each and every damn page, a dynamically generated one (Webbrowser.LoadFromString) certainly wont be allowed to have fun. To put it simple: It wont allow Javascript execution.
I tried adding a SecurityManager to my TEmbeddedWB, however that did not do it either. I tested my dynamic code in Firefox, and in IE9, and it works (of course, in IE9 I have to allow first, which was how I found it was a security issue).
Is there a painless way to get around this, without having to manually go into IE and tweak something? Or am I completely wrong about the cause of the issue?
EDIT: After trying this article's method, IE does not ask if it should allow stuff anymore, however my script is still not being executed within my TEmbeddedWB/TWebbrowser..
EDIT 2: Okay, by removing the jQuery code, and displaying a plain Alert, I am forced to conclude that JS is now being executed, however jQuery is not.
EDIT 3: Here is the (stripped down) HTML code that my app generates, where jQuery is not working in my EmbeddedWB/TWebbrowser control - however, it works in Internet Explorer 9 itself:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=9" />
<script type="text/javascript" src="file://C:\jQuery.js"></script>
</head>
<body>
<center>
<p>
Some stuff here!
</p>
</center>
<script type="text/javascript" language="javascript">
$(document).ready(function(){
alert('I Am jQuery!!!!');
});
</script>
</body>
</html>
EDIT4: I have also tried switching the src to a Google Hosted jQuery, and that did not work either. Removing the Metatag did not fix it either. Just letting you know of stuff I tried before you waste time on suggesting it :)
EDIT5: By navigating to a site that uses jQuery (Webbrowser.Navigate) the site was working as expected. However when doing it from my local test.html, or by doing .LoadFromString();, it will not work.
Will not work = jQuery code not executing.
It seems to work if you use correct URL for the jquery.js file:
<script type="text/javascript" src="file://C:/jQuery.js"></script>
<script type="text/javascript" src="file:///jQuery.js"></script>
or a relative path, you can also omit the file:// protocol:
<script type="text/javascript" src="../../jQuery.js"></script>
The above works when you load the HTML from a file. The question is however, if content from memory and javascript from file system is not considered crossing a security context boundary and rejected for that reason by the embedded browser. In that case, embedding jquery directly in the HTML content (using the <script> tag) should work.