JavaScript partial files loading order different to what is in code - javascript

I have put the JS files in order that they should load to avoid any errors in console and get everything working, however when I look at the network tab in developer tools, the files are being loaded differently to what is in the web page...
Here is the order in code:
<script src="/js/lib/jquery-3.3.1.min.js"></script>
<script src="/js/lib/jquery-ui.min.js"></script>
<script src="/js/lib/bootstrap.bundle.min.js"></script> <!-- Includes popper.js -->
<script src="/js/lib/toastr.min.js"></script>
<!-- Page specific scripts -->
<script src="/js/lib/moment.min.js"></script>
<script src="/js/lib/daterangepicker.js"></script>
<script src="/js/lib/Chart.min.js"></script>
<script src="/js/partials/daterange.js"></script>
<script src="/js/partials/utils.js"></script>
<script src="/js/partials/charts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.32/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/v/bs4/jszip-2.5.0/dt-1.10.16/b-1.5.1/b-html5-1.5.1/b-print-1.5.1/cr-1.4.1/datatables.min.js"></script>
<script src="/js/partials/dataTable.js"></script>
<script src="/js/mainBundle.js"></script>
And this is what I get in dev tools:
errors in console, that jQuery is loaded too late... (it is 1st in the code...)
Things I think can have an impact - I am using some JS files stored locally, some fetched from cdnjs.
I am using templating (blade) within Laravel (some script calling is from main template, some from 'page-specific'). But I would think that php parses everything together beforehand.

When you load multiple JavaScript files, the browser will load handfuls at a time (usually about 5). They may finish or even start in a different order.
But, that is okay. Even if they finish loading in a different order, they will still be run in the order that you have specified (unless you are using defer or async which affect the run order).

Related

What names should js files have, to which urls with a strange ending lead: ".../filename.js?crc=6»?

In html pages, I saw some strange are the paths to js documents:
— attached the code at the end of the question —
I noticed the "?crc=6" after the usual ".js".
As I understand it, "?crc=6" is used to indicate the version of this file in case any of its previous editions will be in the browser cache. There were presumably five of them here (each time the file was changed in the URL this number also changed so that the browser considered the file different and did not take the old one from the cache).
What names should the js files to which these links lead have? Should they be spelled out together with "?crc=6" or use a simple notation with ".js"?
<script src="/js/jquery.fancybox.min.js?crc=6" type="text/javascript"></script>
<script src="/js/jquery.cookie.js?crc=6" type="text/javascript"></script>
<script src="/js/popper.min.js?crc=6" type="text/javascript"></script>
<script src="/js/bootstrap.bundle.min.js?crc=6" type="text/javascript"></script>
<script src="/js/bootstrap.min.js?crc=6" type="text/javascript"></script>
<script src="/js/jquery.formstyler.js?6" type="text/javascript"></script>
<script src="/js/wavesurfer.min.js?6" type="text/javascript"></script>
<script src="/slick/slick.min.js?6" type="text/javascript"></script>
<script src="/js/common.js?99" type="text/javascript"></script>
I noticed the "?crc=6" after the usual ".js". As I understand it, "?crc=6" is used to indicate the version of this file in case any of its previous editions will be in the browser cache. There were presumably five of them here (each time the file was changed in the URL this number also changed so that the browser considered the file different and did not take the old one from the cache).
What names should the js files to which these links lead have? Should they be spelled out together with "?crc=6" or use a simple notation with ".js"?
The filename on the webserver should end in only .js. Question marks are invalid in filenames anyway on some operating systems.
The only purpose of the query parameter is to force the client to make a new request to the webserver if that version of the script is not in the browser cache yet - on a static site, a request to /js/jquery.fancybox.min.js?crc=6 will result in the site returning the file located at /js/jquery.fancybox.min.js.

Angular custom scripts loader

I have an Angular 7 CLI app which is served by ASP.NET MVC.
In Index.cshtml file I have these lines:
<script type="text/javascript" src="~/app/runtime.js"></script>
<script type="text/javascript" src="~/app/polyfills.js"></script>
<script type="text/javascript" src="~/app/scripts.js"></script>
<script type="text/javascript" src="~/app/vendor.js"></script>
<script type="text/javascript" src="~/app/main.js"></script>
Everything works fine.
However sometimes during development these files are not generated due to compilation errors etc.
I'm wondering is there a way to write a custom manual loader that will try to fetch these files and if any of these are not found will pop up a nice message to the developer.
Basically a really simple pre-loader to the application.
Any input is greatly appreciated.
In my case, what I do when it comes to altering the index.html is having a controller, which I call SpaController with an Index (default) action. Then, I load the index.html file (which is really small) and patch it with all the changes I want to apply. After being patched and downloaded on the browser, the rest of the communication is done through API REST, so it's just a small patch.
In your case, I would use that action of that controller I mentioned above and check if all the tag scripts are included. If not, you have flexibility to alter index.html and do what you want, like showing an error, or even stop the application.

Sails.js: load script on a specific view

In Sails.js how can I load a javascript file in a specific view, because I have an script that I want to load only in one view (.ejs).
I see that in layout.ejs all the javascript files are loaded for all views, so the idea is to exclude the javascript file from the layout and load inside the view.
<!--SCRIPTS-->
<script src="/js/dependencies/sails.io.js"></script>
<script src="/js/dependencies/angular.js"></script>
<script src="/js/dependencies/angular-ui-router.js"></script>
<script src="/js/dependencies/angular-route.js"></script>
<script src="/js/dependencies/angular-translate.js"></script>
<script src="/js/dependencies/ui-bootstrap.js"></script>
<script src="/js/dependencies/textAngular-rangy.min.js"></script>
<script src="/js/dependencies/textAngular-sanitize.min.js"></script>
<script src="/js/dependencies/textAngular.min.js"></script>
<script src="/js/dependencies/angular-color-picker.js"></script>
<script src="/js/dependencies/angular-click-outside.js"></script>
<script src="/js/dependencies/angular-bootstrap-tpls.min.js"></script>
<script src="/js/dependencies/angular-filemanager.js"></script>
<script src="/js/dependencies/resource.js"></script>
<script src="/js/app.js"></script>
<script src="/js/locales/ca.js"></script>
<script src="/js/locales/en.js"></script>
<script src="/js/locales/es.js"></script>
<script src="/js/controllers/IndexController.js"></script>
<script src="/js/controllers/LoginController.js"></script>
<script src="/js/controllers/LogoutController.js"></script>
<script src="/js/controllers/NewVideoController.js"></script>
<script src="/js/controllers/PreviewController.js"></script>
<script src="/js/controllers/VideoConfigController.js"></script>
<script src="/js/controllers/layoutController.js"></script>
<script src="/js/services/LoginService.js"></script>
<script src="/js/services/VideoConfigService.js"></script>
<script src="/js/services/VideoService.js"></script>
<script src="/js/services/authInterceptor.js"></script>
<script src="/js/services/authToken.js"></script>
<script src="/js/test/controllers/IndexController-spec.js"></script>
<!--SCRIPTS END-->
The code above are the scripts of the layout. I would like to remove the textAngular scripts from the layout and load only in the view that uses textAngular.
Has someone an idea?
If you're loading different scripts on different pages as part of the actual behavior of your application, I'd advise against it. (But it looks like you're using Angular, so that's probably not the case, since you're probably attaching UI controllers to a particular page via ng-controller).
So, on the other hand, assuming you're looking into doing this for performance reasons, then here's what I'd suggest:
First lift with --prod and check to see what each page load feels like. Now that you're using a minified bundle, it should be considerably faster. Pay particular attention to what subsequent page loads feel like, since your browser will have cached everything by then. Because of the way the browser (and HTTP v1) work, in most cases you'll find that using a single bundle in production is actually faster then including only those scripts used on a particular page. (Plus it makes switching to a CDN much easier if that ever comes up).
That said, if you're using tons of JavaScript files (megabytes and megabytes), that might not always be an option. What we usually do at my company in that scenario is what #KevinLe suggested: manually include the really heavy scripts on the page that needs them. (Even then, you can probably still use the linker for everything else-- or vice versa).
Alternatively, you could get fancy with Grunt or Gulp-- just keep in mind that, when you go to production and you consider using a CDN, you'll have to bundle up those scripts for each individual view into separate payloads.
So to recap:
avoid writing front-end code that does stuff immediately when it is loaded without first checking the DOM
for most apps, you should just use a single bundle (performance will be better)
if you need to separate things out, include scripts manually in the views where you need them (note that if you do this and also decide to continue using the linker, then you'll probably want to move the linker tags out of layout.ejs and into each individual view as well-- that keeps your script tags in one place in the code)

Asynchronously load to eliminate render-blocking js & css?

I've just spent a really long time googling... and only find half answers everywhere. I am using the google page speed insights to improve my website and it tells me to asynchronously load my javascript. I found a couple of codes, but they didn't explain how to load MORE than one js file AND how to load the css as well. I also couldn't find anywhere where it tells me in what order to load it. Can anyone help?
NOTE: I DID try to move the js to the footer, but then my mobile menu no longer works (which uses the expand.js file)
The Javascript files I need to asynchronously load are:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script language="javascript" type="text/javascript" src="js/h5.js"></script>
<script language="javascript" type="text/javascript" src="js/expand.js"></script>
My CSS:
<link rel="stylesheet" type="text/css" href="style.css">
Asynchronous loading of scripts can get pretty complicated. Have you tried using the async attribute? E.g.:
<script async src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script async language="javascript" type="text/javascript" src="js/h5.js"></script>
<script async language="javascript" type="text/javascript" src="js/expand.js"></script>
However, this can cause undesired race conditions. All this means is the rest of your site is not going to wait for these three JavaScript files to load before loading other resources. This may or may not improve the speed of your site depending on what is contained, and can produce some wonky results in terms of dependency management which you'll have to account for in your scripts.
It is usually recommended by the big G to create two small files: a CSS and a JavaScript file to be included in your <head/> which contains all the styles and logic for the above-the-fold content (or better yet: inline them, even though this increases the DOM size). Source.
How To Asynchronously load Javascript File?
Well to load javascript file you just need to include "async" attribute in <script> tag i.e.
<script src="your path" async></script>
Now this script will be downloaded in background while it will not cause JS rendering issue.
Note: If you're using some jquery plugin i.e. image zoom or any thing else, it will take an extra time to load but after that it will work properly.
Why to use "DEFER" keyword with "ASYNC" ?
You can also use defer attribute along with async attribute. <script> tag with async attribute forces file to be downloaded in background and execute as soon it is downloaded. but async with defer attribute forces <script> tag to execute once entire site is loaded.
<script src="" async defer></script>
How To Asynchronously load CSS file?
If you want to load your CSS file asynchronously first you have to place provided <script> in your head file and then you can use loadCSS() function to load you CSS file asynchronously.
<script>
// https://github.com/filamentgroup/loadCSS
!function(e){"use strict"
var n=function(n,t,o){function i(e){return f.body?e():void setTimeout(function(){i(e)})}var d,r,a,l,f=e.document,s=f.createElement("link"),u=o||"all"
return t?d=t:(r=(f.body||f.getElementsByTagName("head")[0]).childNodes,d=r[r.length-1]),a=f.styleSheets,s.rel="stylesheet",s.href=n,s.media="only x",i(function(){d.parentNode.insertBefore(s,t?d:d.nextSibling)}),l=function(e){for(var n=s.href,t=a.length;t--;)if(a[t].href===n)return e()
setTimeout(function(){l(e)})},s.addEventListener&&s.addEventListener("load",function(){this.media=u}),s.onloadcssdefined=l,l(function(){s.media!==u&&(s.media=u)}),s}
"undefined"!=typeof exports?exports.loadCSS=n:e.loadCSS=n}("undefined"!=typeof global?global:this)
</script>
Now you just have to use loadCSS function.
<script>
loadCSS("https://www.yourCSSLinkHere.com");
</script>
In this way you can load your CSS and JS file Asynchronously.
You can use HTTP/2.0 to overcome speed issue because HTTP/2.0 allows your file to be downloaded parallel but HTTP/1.0 won't allow your file to be download parallel, in other way HTTP/1.0 follows FIFO(First In First Out) rule.

javascripts aren't executed sequentially in modern browser?

I know that in general, the scripts are loaded and executed in the order. But I have a problem that they are not executed in the right order, sometime the second script is executed and then the first script.
I am using jsp and tile. In the jsp template, I only load the common js files and then load specific js files for specific tile
It seems like browser loads and executes the scripts asynchronously
How to force it to load and execute scripts sequentially?
I've searched a lot of places for the answer but not work.
Template:
<html>
<head>
<title></title>
//load common js files
</head>
<body>
<tiles:insert attribute="header"/>
<tiles:insert attribute="content"/>
<tiles:insert attribute="footer"/>
</body>
</html>
Specific tile:
<div>
Test
</div>
//load js files
<script type="text/javascript" src="1.js"></script>
<script type="text/javascript" src="2.js"></script>
<script type="text/javascript" src="3.js"></script>
Edit:
These javascript files are very simple, they just print out number 1,2 and 3
But sometime It prints the wrong order.
The "content" div will be replaced by the tile and I don't know whether it is a type of loading resource dynamically: Dynamically loading JavaScript synchronously
There is a great article on html5rocks about script loading.
http://www.html5rocks.com/en/tutorials/speed/script-loading/
the simplest way would be to use defer but it's not supported by IED<10 and opera mini.
<script src="//other-domain.com/1.js" defer></script>
<script src="2.js" defer></script>
Spec says: Download together, execute in order just before
DOMContentLoaded. Ignore “defer” on scripts without “src”.
IE < 10 says: I might execute 2.js halfway through the execution of 1.js. Isn’t that fun??
The ultimate solution but less supported would a combination of dynamic inclusion and forcing async attribute to false.
[
'1.js',
'2.js'
].forEach(function(src) {
var script = document.createElement('script');
script.src = src;
script.async = false;
document.head.appendChild(script);
});
it requires a work around using onreadystatechange on IE<10

Categories