I have the following at the bottom of my HTML:
<script defer="defer" src="http://localhost:8080/bower_components/jquery/dist/jquery.min.js"></script>
<script defer="defer" src="http://localhost:8080/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script defer="defer" src="http://localhost:8080/apps/promotion/active.js">
// "Gulped" angular, ngAnimate, ui.bootstrap, and my angular app; in that order.
</script>
</body>
</html>
At random times, I will get this error when I refresh the page:
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.4.9/$injector/modulerr?p0=activePromos&p1=Err…20(http%3A%2F%2Flocalhost%3A8080%2Fapps%2Fpromotion%2Factive.js%3A1%3A7124)
Sometimes it will happen for multiple refreshes in a row, and sometimes it will work for multiple refreshes in a row. Nevertheless, there are times when I get the error and it's getting annoying.
What I found out is the following: If I remove the jquery and bootstrap scripts so that I only have the one script (active.js) with the defer attribute, it always work. I am trying to load the scripts after the page is done loading in the specified order.
Should I be doing this a different way (requirejs?)? I assumed using defer and putting the scripts in order would help since I've done it before, but not with AngularJS. I am mainly trying to take advantage of parallel downloads from the browser instead of having one huge JS file, since the page only has 1 image and 2 CSS files.
The angular app will not be able to initialize properly until after all of the required JavaScript files are loaded.
Since you are deferring the load of those files, you will need to wait until all of the files are loaded, and then manually initialize the app using AngularJS's bootstrap function.
Related
I am trying to add bootstrap-select to my Flask app and I keep running into the error "TypeError: $(...).selectpicker is not a function". Everything I've read says this only occurs if you load jQuery again after loading bootstrap-select.js, so I went through and cleaned up my scripts, ensuring that jQuery was being loaded before all my other JS scripts, like so:
<script src="http://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"> </script>
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js"></script>
However, I was still getting the same problem. I decided to take a look at the order of loading in the chrome developer tools window, and now I think my problem is this: jQuery is being queued for loading before bootstrap-select, but it's not actually starting the download until after bootstrap-select has already finished. I suspect this is because of the difference in size between the two.
Is there any way I can force my other scripts to delay loading until after jQuery has already loaded? Or if I figure out how to cache a copy of jQuery in my static directory, will that help?
Edit: Wow, okay, I got a lot of comments on this! To try and clarify as much as possible, I'm just going to make some notes:
After thoroughly checking all my scripts, I can confirm that only one copy of jQuery is being loaded.
This is not an https page, I'm running it locally on a Flask development server.
I checked the bootstrap-select url I have in my code and it is the correct one. Sorry, I'm not sure why it left out the dash when I was copy-pasting. I have corrected the question accordingly.
I have been using the Network tab in chrome's dev tools to check loading successes/times.
I moved my jQuery to the very beginning of the file to ensure it would load first, and I can now confirm it is finished loading before bootstrap-select loads.
Despite all this, I'm continuing to get the same error, so if anyone has other suggestions I would appreciate them. I'm completely out of ideas at this point.
You should put defer at the end of both script tags, so they are loaded in order no matter what, like this:
<script src="http://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous" defer></script>
...
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrapselect/1.13.1/js/bootstrap-select.min.js" defer></script>
Try changing the URL for your bootstrap select library to:
https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/js/bootstrap-select.min.js
I have the solution and it's dumb as heck.
I was adding my scripts to the same place the previous developer added theirs, in the base template that all my other templates extend. The thing is, they added theirs to the end of the page, after the body tag was closed (presumably to make page loading faster). The little bit of jQuery which was using selectpicker was in the body, and was thus trying to load the function prematurely.
Thanks for all your answers!
I'm using a external JavaScript library called Masonry (Cascading grid layout library) https://masonry.desandro.com/.
I have created a demo page using this library and everything seems to work fine, However once i incorporate this library in a React app it doesn't work.
Scripts
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://unpkg.com/masonry-layout#4/dist/masonry.pkgd.min.js"></script>
<!-- <script src="../src/assets/js/JQuery/masonry.js"></script> -->
<script>
$(window).on('load', function(){
var $content = $('.content-container').masonry({
// options
itemSelector: '.masonry',
percentPosition: true,
singleMode: true
});
$content.imagesLoaded().progress( function() {
$content.masonry('layout');
});
console.log('Works!')
});
</script>
</html>
I have tried two methods, adding an external JavaScript file masonry.js and adding the code in a script tag within the index.html page. whenever i use the external JavaScript file it doesn't work at all (the console.log('Works!') doesn't even show in the console). But if i use the code within the Script tag in the index.html page the masonry works occasionally if i do a few page refreshes and the console.log('Works!') shows up in the console every time.
I'm not sure if its because Reactjs has a different way in adding external JavaScript libraries / files, but i have searched online what is the correct way to set up external JavaScript files in a react app and it came up with multiple methods so i'm kind of confused to witch is the correct / best.
Also i have checked the Network in the browser developer tools and the external library / JS file imports seems to be loading in fine.
Just a note: the .content-container child elements change on button clicks in the Reactjs but not in the demo page.
I have a magento site which has a very heavy theme that I'm trying to optimize. It uses quite some JS scripts that when I'm testing the site speed it's recommended to me should be deferred.
e.g.
<script type="text/javascript" src="/skin/frontend/default/forest_fashion/js/prototype.and.jquery.min.js"></script>
<script type="text/javascript" src="http://www.princessly.com/media/js/f8a453ce8ffc122a8a56247434d1ac82.js"></script>
<script type="text/javascript" src="http://www.princessly.com/skin/frontend/default/forest_fashion/js/princessly.js"></script>
<script type="text/javascript" src="http://www.princessly.com/skin/frontend/default/forest_fashion/js/overlaybox.js"></script>
But I never wrote all the JS code so I'm not sure if I can simply add a defer attribute to the script tags without breaking anything because I also heard despite adding defer attribute would make my site render faster client side some features may rely on the script being parsed before the page is rendered.
Is this true? Can I simply add defer to any JS script on my page without first discriminating? How do I know if I can safely add a defer attribute to a script on my page?
If the code is meant to be loaded before page load then adding it after page load would cause errors.
e.g. this particular code block will not execute if the page has already loaded
window.addEventListeners('load',function(){
//do stuff
alert('Foo');
},false);
So I am 99% sure that by simply adding a defer attribute will NOT make code problem free. It will all depend on how it was meant to be used.
After I read pagespeed (chrome) suggestion to defer javascript, I modified the javascript link tag for three files, not all files.
However, when I load the website, pagespeed continues to suggest that I defer javascript, and the modified files continue to appear under the suggestion's list.
I have attached two images, one shows that pagespeed is suggesting I defer these javascript files, and the other is showing the pagesource, which lcearly shows that the javascript link tag includes the defer attribute.
PAGE SPEED IMAGE
WEB PAGE SOURCE CODE
For live website: http://redesign.com.s136249.gridserver.com/
Do you have any insight as to why this is happening (perhaps this files are not being deferred?) do you have any suggestions of what can I do to have pagespeed reflect the deferral of these javascript files?
Update:
Consider using the defer attribute!
Old Answer:
The concept is, that a script loading should be deferred, that is, it should appear after all of your contents.
Like just before the closing </body> tag, and that's the right way of saying it as deferred.
For now, what you have done, is just like ordering scripts.
And why is it asking you to defer it?
Whatever external files you specify in your code, needs an extra call to be loaded.
Until that call is resolved, the rest of the content of your page cannot be rendered by the browser, and have to wait, until your scripts are loaded.
Making this call in the initial part of the code, makes your site appear a bit slow.
I am trying to compare having a 1 page app with clientside routing to having a asp mvc app which just routes to html files, to see which is more appropriate for my current project. As I have no need for any Asp Mvc features its all javascript/html which communicates with a web service.
However one problem I can forsee with the one page app is that my site isnt really 1 page, so I would be having to have on main index.html which contained all shared resources. Then dynamically load in new pages based on the hashbang and add in any required scripts and css. This doesn't seem to hard as Jquery I believe provides a .load() method or something similar to get external resources... my problem though is getting rid of them once I am done...
Is there any way to do this, so you target ONLY certain script/link tags, can you give them Ids or something?
Any help on this would be great...
== EDIT ==
Added a simple example to show what I mean:
<!-- Script already in page -->
<script type="text/javascript" src="scripts/script1.js"></script>
<!-- Dynamically added script -->
<script type="text/javascript">
// some javascript
</script>
How can you tell which ones you should remove? If you could apply an id or uniqueness to each script then it may be ok, but thats what i am getting at with this question.
There are zero benefits to "removing resources." When a script has been loaded, removing the script tag from the page later has no purpose--it won't improve your browser performance at all, nor will it harm it to keep the files around.
Simply add your resources as needed and write your code such that it won't execute erroneously.
I'm not shre i understand why you would like to do that but link element (for css) and script (for js) are elements like any other and they can be deleted with remove().