Every beginners guide to Javascript talks about the evils of embedded scripts.
And I get it: definitely good advice for novices who have no concept of modular design. But every rule has an exception, and since I'm fairly new at web development (but not development in general) I want to ask if the following is a good exception:
I'm building a web application using MVC on the server-side (Django, for the record), and Require.js on the client-side to manage application logic scripts. I'm careful to keep these scripts DOM-agnostic.
It makes sense to me to embed the remaining DOM-interacting code directly in the server-side HTML templates that are defining that DOM. Creating separate JS files that are so minimal and tightly coupled with the content of the templates just feels unnecessary. Am I wrong?
Assuming you've got all application logic tucked away nicely in external files, is it really so bad to sneak a few lines of jQuery in with your HTML to hook that logic up to the DOM?
If you've got JS that applies to only one page and there's not very much of it then yes, I would put it directly in the page rather than as a separate JS include.
If you have a lot of JS that applies to only one page then a separate JS include gives you the advantage that (after the first request) it will sit in the browser cache rather than being downloaded every time a user refreshes that page. So in that case I'd probably stick with the external JS file.
Having made the decision to include JS in a particular html page, I prefer to include it all as a single block either in the head or at the end of the body - I don't want to have to scan through the html looking for multiple small script blocks buried in the markup. Also if I later decide to move the script to an external file it is easy to do so.
See this on where it is going particularly comment around Angular js from google referred to
http://blog.stevensanderson.com/2012/08/01/rich-javascript-applications-the-seven-frameworks-throne-of-js-2012/
See this Comparison http://engineering.linkedin.com/frontend/client-side-templating-throwdown-mustache-handlebars-dustjs-and-more thorough test and comparison
It appears DOM Templates maybe the future. And for my mind better to deal with in terms of debugging.
Related
In my single-page JS-app, I've decided to dinamically load portions of HTML/JS in a JIT manner. I found 2 ways to do it, using JQuery:
First:
$("#target_div").load("html_and_js.html");
// the HTML file contains both HTML` and the corresponding JS code
Second:
$("#target_div").load("thtml_only.html", function() {
$.getScript('js/js_only.js');
}); // now the JS is kept separatelly from HTML
I would like to know your experiences and opinions regarding pros/cons of both approaches.
As I'm building an single-page AJAX app, I am particularly interested in the following aspects:
Browswer performance if the large number of those dynamic loadings/removings are made - how much memory the modern browsers reserve for DOM?
is the DOM structure kept safe and clean?
when the corresponding DIV (#target_div in my example) is removed - is the JS also removed from the browser memory? Eventual memory leaks?
Every opinion is highely appreciated.
From an architecture perspective you're separating out your presentation layer from business logic that may be held in the javascript - always good to do.
Separating your javascript into a separate file allows you to minify it easier, and re-use any of the functions that you develop into the javascript file.
Also, in the second option, the javascript will only get loaded once the html has completely loaded. Although as a rule of thumb I always recommend javascript goes as close to the end of the HTML document as possible, there are some (albeit rare) occasions where you need some portions of your javscript to run during the page load, not after it, and therefore the second approach (loading html first, then javascript on complete) wouldn't allow this javascript to run. Though... it could allow you to put the rare javscript that needs to be run into your HTML-only page (granted making it not-so-HTML-only), and keep the rest of the javascript separate for running at the end of the page.
Just my opinions, hope they help,
Kurt
Just curious about the current trend to put client-side templates for single-page Java applications in script tags in your HTML file. Seems like an interesting approach, but is this considered a best practice (or at least a better practice)? I tried to come up with a list of advantages and disadvantages, but the list of bad seems to outweigh the good.
So the way I see it is this:
Advantages:
Only one request to get all templates vs. an individual async request for each template file.
Disadvantages:
Creates a potential merge troublespot / bottleneck file if all templates are in one location
A bit cumbersome to edit templates all in one file
A bit cumbersome to find the template you need vs. using a keyboard shortcut to open file.
Have to wait until the DOM is ready before doing anything with a template.
It also seems that with having them in script tags, you can precompile and cache your templates so you're only querying the DOM once to get each template. However, couldn't you achieve the same effect using AMD / Require and a require/text! or dojo/text!? In the latter instance, you'd be lazily loading each template only once. You could then cache it and precompile it at that point.
I just am struggling to see the many advantages of templates in script tags. Am I missing something?
IMHO it really comes down to how many templates you have. When your site is first starting out and you don't have a lot of templates, keeping them all in script tags on a single HTML page makes a lot of sense.
However, as your number of templates grows, that soon becomes unwieldy; before long you're using server-side logic to concatenate a bunch of separate template files in to your master HTML file, and at that point I think it makes perfect sense to start considering other approaches.
Personally my company's codebase started out with script tags in an HTML file, but as we've since grown (and started using require) and now now we have tens if not hundreds of .handlebars (or more commonly, .hbs) files for all of our templates. We bring these in to our Javascript using Alex Sexton's HBS plug-in (https://github.com/SlexAxton/require-handlebars-plugin) for require, and that works great because:
we get to use our standard require system for our templates
templates get compiled to a single compressed JS file when we use the require optimizer
we can configure our IDEs to treat .handlebars files as HTML, giving us the appropriate syntax coloring and such when we edit them
I'm not sure which templating system you're using, but if you're using Handlebars and already using Require then the HBS plug-in is a great way to. If you use a different templating system you likely can find a similar plug-in for Require (if that system is popular enough), or even write your own using the HBS one as a basis.
For anyone with a decent number of templates, I think a system like that (especially for anyone already using Require) makes a whole lot more sense than script tags.
If I understand you correctly, you have some number of client-side templates you want to use, but you would like to separate them into individual files on the server side. When you have a lot of such templates, there is some obvious engineering advantages to such an approach.
You might consider using JSONP. With a half-decent handler on the server side, you get the benefits you're looking for:
Separate file for each template
Easy inclusion into your HTML pages.
The ability to assign each template to a variable, or send it through a compilation function as soon as it is received by the client.
Cache templates on the client side, so they don't have to be reloaded for every page.
Compatibility with caching proxies
The only part of the JSONP implementation that is non-trivial is the caching properties. You need to make sure your server-side controller that receives the request understands conditional GETs, how to send 304 responses, and sets caching headers properly.
If you aren't familiar with the technique, you might take a look at the JSONP wikipedia entry.
I guess what I'm asking is that if grouping JavaScript is considered good practice, why don't more websites place the JavaScript and CSS directly into one HTML document?
why don't more websites place the JavaScript and CSS directly into one HTML document
Individual file caching.
External files have the advantage of being cached. Since scripts and styles rarely change (static) and/or are shared between pages, it's better to just separate them from the page making the page lighter.
Instead of downloading 500kb of page data with embedded JS and CSS, why not load 5kb of the page, and load from the cache the 495kb worth of JS and CSS - saves you 495kb of bandwidth and avoids an additional 2 HTTP requests.
Although you could embed JS and CSS into the page, the page will most likely be dynamic. This will make the page load a new copy all the time, making each request very heavy.
Modular code
Imagine a WordPress site. They are built using a tom of widgets made by different developers around the world. Handling that many code stuffed in one page is possible, but unimaginable.
if some code just short circuited or just didn't work on your site, it's easier to take out that code linking the external file, rather than scouring the page for the related code and possibly accidentally remove code from another widget.
Separation of concerns
It's also best practice to separate HTML from CSS and JS. That way, it's not spaghetti you are dealing with.
When you have a lot of code in a single document, it's harder to work with the code because you need more time to find the necessary string to change.
That is why it's good practice to divide code into separate files, with each of them solving its own special task, and then include them in code where it's necessary.
However, you can a write script which will join your files from the development version, which has many files, to a release version, which has fewer files, but this brings two problems:
People are often lazy to do additional coding to create this script and then change it when the structure of your project becomes more complex.
If you find a bug or add a small feature, you will need to rebuild your project again both in developed and release versions.
They separated them so that multiple webpages can use the same file. When you change a single file, multiple pages can aromatically updated also. In addition, big HTML file will cause a long time to download.
In my project each page has a bunch of dependent Javascript and Css. Whilst developing I just dumped this code right into the page but now I'm looking to clean it up...
it appears that the general approach out there is to package all the Javascript/CSS for an application into two big files that get minimised.
This approach has the benefit that it reduces bandwidth since all the front-end code gets pulled in just once from the server... however, I'm concerned I will be increasing the memory footprint of the application by defining a whole ton of functions for each page that I don't actually need - which is why I had them on a per-page basis to begin with.
is that something anyone else cares about or is there some way to manage this issue?
yes, I have thought of doing conditional function creation since I need to run code conditionally for each page anyway - though that starts to get a bit hackish in my view.
also, is there much cost to defining a whole ton of Css that is never used?
Serving the javascript/CSS in one big hit for the application, allows the browser to cache all it needs for all your pages. If the standard use case for your site is that users will stay and navigate around for a while then this is a good option to use.
If, however, you wish your landing page to load quickly, since there is a chance that the user will navigate away, consider only serving the CSS/javascript required for this page.
In terms of a performance overhead of a large CSS file - there will be none that is noticeable. All modern browsers are highly optimised for applying styles.
As for your javascript - try not to use conditional function creation, conditional namespace creation is acceptable and required, but your functions should be declared only in one place.
The biggest thing you can do for bandwidth is make sure your server is compressing output. Any static document type should be compressed (html, js, css, etc.).
For instance the jQuery Core goes from approx. 90KB to 30KB only because of the compressed output the server is sending to browsers.
If you take into account the compression, then you have to create some mammoth custom JS includes to really need to split-up your JS files.
I really like minifying and obfuscating my code because I can put my documentation right into the un-minified version and then the minification process removes all the comments for the production environment.
One approach would be to have all the shared javascript minified and compressed into one file and served out on each page. Then the page-specific javascript can be compressed/minified to its own files (although I would consider putting any very common page's javascript into the main javascript file).
I've always been in the habit of compressing/minifying all of the CSS into one file, rather than separate files for each page. This is because some of the page-specific files can be very small, and ideally we share as much css across the site as possible.
Like Jasper mentioned the most important thing would be to make sure that your sever is GZIPing the static resources (such as javascript and css).
If you have a lot of javascript code you can take a look on asynchronous loading of js files.
Some large project like ExtJs or Qooxdoo have build in loaders to load only required code, but here is a lot of libs which simplify this, and you can use in your project (e.g. head.js, LAB.js).
Thanks to them you can build application which loads only necessary files, not whole javascript code which in case of big apps can be a heavy stuff for browser.
some time ago, I was reading an article(a library built by some guy) about how his library can do
lazy loading of JS
resolve dependencies between JS
(typically encountered when trying
to "include" one js from another)
include files only once. thought
specified multiple times regardless
of how they are called (either
directly specifying it as file or
specifying it as one of the
dependencies)
I forgot to bookmark it, what a mistake. Can some one point me to something which can do the above. I know DOJO and YUI library have something like this, but I am looking for something which I can use with jQuery
I am probably looking for one more feature as well.
My site has asp.net user controls
(reusable server side code snippets)
which have some JS. Some of them get
fired right away, when the page is
loading which gives a bad user
experience. Yahoo performance
guidelines specify that JS should
be at the bottom of the page, but
this is not possible in my case as
this would require me to separate the
JS and the corresponding server side
control into different files and
maintenance would be difficult. I
definitely can put a jQuery
document.ready() in my user control
JS to make sure that it fires only
after the DOM has loaded, but I am
looking for a simpler solution.
Is there anyway that I could say "begin executing any JS only after DOM has loaded" in a global way than just writing "document.ready" within every user control ?
Microsoft Research proposed a new tool called DOLOTO. It can take care of rewriting & function splitting and enable the on-demand js loading possible.
From the site..
Doloto is a system that analyzes
application workloads and
automatically performs code splitting
of existing large Web 2.0
applications. After being processed by
Doloto, an application will initially
transfer only the portion of code
necessary for application
initialization. The rest of the
application's code is replaced by
short stubs -- their actual function
code is transferred lazily in the
background or, at the latest,
on-demand on first execution.
OK I guess I found the link
[>10 years ago; now they are all broken]
http://ajaxian.com/archives/usingjs-manage-javascript-dependencies
http://www.jondavis.net/techblog/post/2008/04/Javascript-Introducing-Using-%28js%29.aspx
I also found one more, for folks who are interested in lazy loading/dynamic js dependency resolution
http://jsload.net/
About the lazy-loading scripts thingy, most libraries just adds a <script> element inside the HTML pointing to the JS file to be "included" (assynchronously), while others like DOJO, fetches it's dependencies using a XMLHttpRequest and then eval's its contents, making it work synchronously.
I've used the YUI-Loader that is pretty much simple to use and you don't need the whole library to get it working. There are other libraries that gives you just this specific funcionality, but I think YUI's is the safe choice.
About your last question, I don't think there's something like that. You would have to do it yourself, but it would be similar to using document.ready.
i did in my framework a similar thing:
i created a include_js(file); that include the js file only if it isn't included reading and executing it with a synchronous ajax call.
Simply put that code in top of the page that needs dependencies and you're done!