I'm trying to organize my website in a modular way using a server side include system. The idea is that every module will have it's own css and own javascript and will only be loaded once included on the page - so any page not having the module wont load that modules css/js either.
I've done it like this:
header.html
-----------
<!-- header start -->
<link rel="stylesheet" href="css/header.css">
<header class="module-header">
<div class="links">
links...
</div>
</header>
<script src="js/header.js"></script>
<!-- header end -->
footer.html
-----------
<!-- footer start -->
<link rel="stylesheet" href="css/footer.css">
<header class="module-footer">
<div class="links">
links...
</div>
</header>
<script src="js/footer.js"></script>
<!-- footer end -->
and then on the index.html:
<!DOCTYPE html>
<head>
<title>Modular page</title>
</head>
<body>
<!--#include virtual="html/header.html" -->
<!--#include virtual="html/footer.html" -->
</body>
</html>
This works fine, and since the scripts are loaded after each module the content is guaranteed to exist before running the scripts. Css is loaded just before and makes sure it will have a nice layout.
However - I've run into some issues with my solution:
In case I were to include a module several times, like for example a product.html, which will be repeated say 20 times - I would have the css and js files included also 20 times. Not good.
Generally I've seen css being included in the head tag, and js in the end of the body. Will having them all coming as the document is being built up induce any issues?
Those includes can be exchanged with any include, php, asp or jsp... this is using apaches SSI.
Is the whole idea going in the wrong direction? I'd imagine this for development setup, but having some kind of smart nodejs rhino script that loads the page - finds the loaded scripts and css, concats and minifies and adds as single includes for production.
To overcome issue of including js or css for times, you should include that files in top of the file in which you gonna include and not inside that included file. Means your product.css/js should be removed from that and should be placed in your index.html or header .html for once
including same js for times may stop your javascript so make sure that they are not conflicting each other
Use a javascript module system. Javascript AMD modules requirejs to load javascript increamently is a very good option. requirejs.org is a very good place to start.
For your context use
//inside header.html
require(['header.js'], function(){
//call this require() multiple times it will load the javascript only once.
//user header.js ... once this line is require() line is executed the
//header.js will be loaded forever
});
footer
//inside footer.html
require(['footer.js'], function(){
//call this require() multiple times it will load the javascript only once.
//user header.js ... once this line is require() line is executed the
//header.js will be loaded forever
});
Now comes the problem of CSS loading in a modular way. Requirejs CSS plugin is also available.
Now once you start using this kind of system, the script loading happens asynchronously using javascript. So the scripts arrive a little late in the screen. Even the css arrives a little late. So if you are writing global event handler like window.onload= func(){}, these are going to fail as most of your javascript would not have loaded yet. If you are doing styling on top of CSS which was dynamically loaded that too requires to be done after CSS loading completes. Using !DomReader in requirejs is a good option. Someday I will write a blog which will discuss these in depth.
The smartness of minifying is there in requirejs as well. requirejs optimizer
Related
I am little new to web development and when I was searching internet about other topics, I have seen many people has put popular JS Libraries in Different Places of their websites.
eg: Inserting JS Libraries on the Very Beginning or Start of the <head> </head> section. (Before loading any JS Code or a CSS File)
eg: Inserting JS Libraries on the End of the <head> </head> section. (After loading all JS Codes and CSS Files)
eg: Inserting JS Libraries on the End of the <body> </body> section. (After loading all JS Codes, Texts, Images, Videos, CSS Files etc...)
So my question is this.
What is the best practice for inserting (where) following JS Libraries, Plugins and CSS Style Sheets to a web page for the most faster loading times and other advantages? - Please mention the reason -
JQuery and it's Plugins
Bootstrap 3.js
Modernizr.js
Angular.js
And another widely used JS Libraries which I couldn't mention here...
Normalize.css
reset.css
bootstrap.css + more
Thank You..!
There is no so called "standard" method. The choice of where to put the lines boils down to one question: When will I need the library?
You see, web files loads line by line, let's take the following as an example of what I mean:
<script>
document.getElementById("target").innerHTML = "changed"
</script>
<p id="target">unchanged</p>
#target isn't altered because the script was loaded before the element did. Web files loads procedurally. When the line of JavaScript is loaded. It is executed immediately, but the target element isn't. So it couldn't change the element.
Even with jQuery, there is the same problem:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$("#target").text("changed");
</script>
<p id="target">unchanged</p>
Therefore, we often use $(function(){}).
Back to the loading problem
People who put their <script> tags or <link> tags in the body (in front) or in the head, wanted to execute the script immediately, sometimes they won't use $(function()) or document.onload
People who put their <script> tags or <link> tags in the body (in the end) wanted to ensure all elements are loaded then execute the script or load CSS.
Conclusion
You should load independent resources such as jQuery first, then load dependent resources such as jQuery plugins. Then you try to decide when you want the resources to start loading, then put the lines in places.
You should put CSS links in the <head> tag because you don't want visitors seeing unstyled content before loading the CSS files.
If you can't decide or don't care about the time, put every <script> and <style> tags in the <head>.
Here is another post you might be interested in: Load and execution sequence of a web page?
CSS can added inside header tag & but put all JS Libraries and custom files just before closing closing body tag
<body>
//other tags
<script> All Scripts here </script>
</body>
By doing so you wont have to check if DOM content has loaded.
It decrease page loading time.Otherwise a js need to be completely loaded before DOM loading.
It also makes sure that all events are attached properly to DOM element.
I think this address all your concern specially the third one
CSS Sheets go in the < head >. The order of the CSS files matter so libraries should be put in first then you can put in the specific ones you have.
Javascript links go in the < body > but place them at the very end. That way your HTML content loads first then the JS loads and it will recognize all your selections. It is more efficient to do it this way.
The most important thing to note when placing your css and script tags is that the order you place them determines the order they are loaded in and if style or code is loaded later it over writes the code written before. So if you have css styling that assigns different styles to the same attributes of the same element then it is the one loaded later that takes effect. And with script tags it's important to remember that for dependency reasons. You should load the dependencies first so that they are there for the other scripts to use. Aside from that normally css tags are in the head and script tags at the bottom of your body element
My page templates have a assets javascript array with assets list of css, js to use in that page, eg.:
<!DOCTYPE html>
<html>
..........
..........
<script type="text/javascript">
var assets= ["/css/my.css", "/js/my.js", "/js/other.js"];
</script>
<script type="text/javascript" src="/js/head.js" async="async"></script>
</body>
</html>
with head.js (loaded asynchronously), load assets list of page:
// head.core code - v1.0.2
// head.css3 code - v1.0.0
// head.load code - v1.0.3
head.load(assets);
now, Google Page Speed on mobile tab (not on desktop) says Optimize CSS Delivery of my.css
but my.css is loaded asynchronously from head.js loaded asynchronously.
What am I doing wrong?
Optimize CSS delivery need not necessarily mean to load them asynchronously alone. It could also mean that CSS may be bloated and it has class that may not be used to render Above the fold or not on this given page itself.
When developer using tool minify their CSS, this happens where in all CSS across pages are bundled together and is bloated!
One way to handle is use CSS inline that required to render the Above the fold and move rest of the CSS to bottom of the page. If not you can try to use Google Apache or Ngnix page speed plugin. https://developers.google.com/speed/pagespeed/module/
I am aware its a best practice to put your javascript/jquery at the bottom of the page.
But how exactly can i achieve this "best practice"?
In my current webproject (MVC4) I have placed my javascript at the bottom.
But i am unable to make anything work unless i put my javascript in the header(which is considered bad practice?).
<body>
<div id="container">
<div id="header">
</div>
<div id="content">
<!--js function that calls upon jQuery (slider) -->
</div>
</div>
<!--Javascript declaration-->
</body>
For example:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="js/slider.js"></script>
The function slider.js requires jQuery to make my slider work.
Is there a way to keep all my javascript files (including jQuery) at the bottom and load jQuery (or a other function / library) if a function needs to access it?
Update
The problem seems to be with the MVC bundles.
When i put the javascript files in the normal syntax at the bottom everything works.
Are separate bundles required? Not sure in what kind of order MVC loads the bundles.
When applying this kind of bundle (jquery first followed by the js function) the order of exection is wrong.
Because of this i cannot really see the advantage of bundles, someone care to explain?
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-1.7.1.js",
"~/Scripts/js/slider.js"));
Thanks.
The reason why this is good is because browsers load scrips synchronously with the web page. So if you put them at the top, loading big scrips will stall the content loading. If you place it at the bottom before the close of the body tag, the content will load first, thus making the page pop up much faster without the stall of scripts.
To fix your problem, wrap all of your executing code in a document.ready, or the jquery equivalent:
$(function(){
//your code here
})
If jQuery is not loaded yet, you can check with a console.log:
if(!window.jQuery)
{
console.log("problem");
}
You haven't provided much information here, which makes it hard to debug. All I can do is give you the steps to do it. You just have to make sure that jQuery is loaded before any other script runs on the page.
Do you have inline script tags in your page?
You should be able to put those at the bottom as long as the jQuery import is before your script. Do you have other javascript in your page which depends on either of those scripts?
I fresh installed MediaWiki on my own server (latest version)
I tried adding some JavaScript code to MediaWiki:Common.js
In localsettings.php, $wgAllowUserJs is set to true
I also tried adding the JavaScript to User:Admin/vector.js and User:Admin/common.js
I cleared cache/cookies, used different browsers, JavaScript enabled, tried different computers
The JavaScript code does not work at all. I viewed source and it's not there.
<!-- BEGIN Tynt Script -->
<script type="text/javascript">
if(document.location.protocol=='http:'){
var Tynt=Tynt||[];Tynt.push('cAe5WESDOr4BZUacwqm_6r');Tynt.i={"ap":"Read more:"};
(function(){var s=document.createElement('script');s.async="async";s.type="text/javascript";s.src='http://tcr.tynt.com/ti.js';var h=document.getElementsByTagName('script')[0];h.parentNode.insertBefore(s,h);})();
}
</script>
<!-- END Tynt Script -->
Do not include <script> and </script> on the *.js page - it will be included as a separate JS file, not inline in the HTML page.
Note that you don't need $wgAllowUserJs for javascript pages in the MediaWiki namespace, only for ones in the User namespace. (There is a separate setting called $wgUseSiteJs for enabling scripts in the MediaWiki namespace, but it is on by default).
Writing an application for a custom gallery, and all the script files are put in a resource folder inside each gallery folder-
is it possible to have a variable enabled that would prevent the page from loading its local JavaScript files but instead load from the main page's resource folder? trying to avoid having to hard-code it as well.
esentially all i really want is for my script files to be able to have a variable starting path- IE
(script src="(path)load.js" type="text/javascript")(/script)
where path is either blank "" or main main site- "http://www.site.com/resources/"
some of the files are CSS files so im not sure the class method would work well-
also- is there a way to refer to the root of a site? similar to using ../ but just to get the root html path.
More Info-----
The layout i have is that each gallery made is a separate folder- (for example, photography, painting, drawings, etc- would all be separate folders). They each would contain their own resources withing their folder. this is so i can just upload 1 gallery to a site and everything would be packaged nicely. But- if im running multiple gallery on one site- as with a portfolio site, each page is loading its own set of resources, which is probably not a great idea.
The resources are - thumbnails, images, xml( which are all specific to individual gallery) but then they also each have a couple javascript files for functions, a css file, and a few images that make the gallery maneuverable(arrows and the like).
I just want to be able to have the scripts which are loaded in the header- load from the root site resource folder if there are multiple gallerys
you can put all the code under a single class name e.g. Mydata.yourvariable
and then check ..
if (Mydata) { //your script has already been loaded }
it's similar to what jQuery does with $
Check out Javascript file dependencies - Selective load resource files & prevent duplicates Also check out this http://toscawidgets.org/documentation/ToscaWidgets/require_once.html
Perhaps you could try something like this:
in index.html (or another html file) you do:
<html>
<head>
<!-- use this if you need custom location, omit for the default one -->
<script type="text/javascript">
var GALLERY_PATH = "/gallery/";
</script>
<!-- ------------------- -->
<script type="text" src="/gallery/gallery.js"></script>
</head>
<body>
...
</body>
</html>
gallery.js:
var GALLERY_PATH = GALLERY_PATH || "http://mysite.com/default-gallery-location/";
document.write('<script type="text/javascript" src="' + GALLERY_PATH + '/js/_gallery.js"></script>')
document.write('<link rel="stylesheet" type="text/css" href="' + GALLERY_PATH + '/css/gallery.css">');
...
This way you easily include all files you need with the 1-liner and all files are loaded once. Hope it helps, of course if I understood the problem correctly ;)
If you found too much hard to handle it with javascript, you can do from server. That depends if the problem is the double call, or the Kb download resource used.
On the last case you can simply enable some cache driver to your web server, like Varnish or MemCache. Once you put a cache you have not to worry about double file loading anymore.
If you want to avoid lot of loads from the same javascript script, you can add a local counter then put 1 when it has loaded once. You will edit the initial call function to test if it's currently loaded, then avoid.
If you have lot of js files, and just wanna avoid calling the same resource twice of more, use session cookie to store the counter.