What is the difference between obtrusive and unobtrusive javascript - in plain english. Brevity is appreciated. Short examples are also appreciated.
No javascript in the markup is unobtrusive:
Obtrusive:
<div onclick="alert('obstrusive')">Information</div>
Unobtrusive:
<div id="informationHeader">Information</div>
window.informationHeader.addEventListener('click', (e) => alert('unobstrusive'))
I don't endorse this anymore as it was valid in 2011 but perhaps not in 2018 and beyond.
Separation of concerns. Your HTML and CSS aren't tied into your JS code. Your JS code isn't inline to some HTML element. Your code doesn't have one big function (or non-function) for everything. You have short, succinct functions.
Modular.
This happens when you correctly separate concerns. Eg, Your awesome canvas animation doesn't need to know how vectors work in order to draw a box.
Don't kill the experience if they don't have JavaScript installed, or aren't running the most recent browsers-- do what you can to gracefully degrade experience.
Don't build mountains of useless code when you only need to do something small. People endlessly complicate their code by re-selecting DOM elements, goofing up semantic HTML and tossing numbered IDs in there, and other strange things that happen because they don't understand the document model or some other bit of technology-- so they rely on "magic" abstraction layers that slow everything down to garbage-speed and bring in mountains of overhead.
Separation of HTML and JavaScript (define your JavaScript in external JavaScript files)
Graceful degradation (important parts of the page still work with JavaScript disabled).
For a long-winded explanation, checkout the Wikipedia page on the subject.
To expand on Mike's answer: using UJS behavior is added "later".
<div id="info">Information</div>
... etc ...
// In an included JS file etc, jQueryish.
$(function() {
$("#info").click(function() { alert("unobtrusive!"); }
});
UJS may also imply gentle degradation (my favorite kind), for example, another means to get to the #info click functionality, perhaps by providing an equivalent link. In other words, what happens if there's no JavaScript, or I'm using a screen reader, etc.
unobtrusive - "not obtrusive; inconspicuous, unassertive, or reticent."
obtrusive - "having or showing a disposition to obtrude, as by imposing oneself or one's opinions on others."
obtrude - "to thrust (something) forward or upon a person, especially without warrant or invitation"
So, speaking of imposing one's opinions, in my opinion the most important part of unobtrusive JavaScript is that from the user's point of view it doesn't get in the way. That is, the site will still work if JavaScript is turned off by browser settings. With or without JavaScript turned on the site will still be accessible to people using screen readers, a keyboard and no mouse, and other accessibility tools. Maybe (probably) the site won't be as "fancy" for such users, but it will still work.
If you think in term's of "progressive enhancement" your site's core functionality will work for everybody no matter how they access it. Then for users with JavaScript and CSS enabled (most users) you enhance it with more interactive elements.
The other key "unobtrusive" factor is "separation of concerns" - something programmers care about, not users, but it can help stop the JavaScript side of things from obtruding on the users' experience. From the programmer's point of view avoiding inline script does tend to make the markup a lot prettier and easier to maintain. It's generally a lot easier to debug script that isn't scattered across a bunch of inline event handlers.
Even if you don't do ruby on rails, these first few paragraphs still offer a great explanation of the benefits of unobtrusive javascript.
Here's a summary:
Organisation: the bulk of your javascript code will be separate from your HTML and CSS, hence you know exactly where to find it
DRY/Efficiency: since javascript is stored outside of any particular page on your site, it's easy to reuse it in many pages. In other words, you don't have to copy/paste the same code into many different places (at least nowhere near as much as you would otherwise)
User Experience: since your code can is moved out into other files, those can be stored in the client side cache and only downloaded once (on the first page of your site), rather than needing to fetch javascript on every page load on your site
Ease of minimization, concatenation: since your javascript will not be scattered inside HTML, it will be very easy to make its file size smaller through tools that minimise and concatenate your javascript. Smaller javascript files means faster page loads.
Obfuscation: you may not care about this, but typically minifying and concatenating javascript will make it much more difficult to read, so if you didn't want people snooping through your javascript and figuring out what it does, and seeing the names of your functions and variables, that will help.
Serviceability: if you're using a framework, it will probably have established conventions around where to store javascript files, so if someone else works on your app, or if you work on someone else's, you'll be able to make educated guesses as to where certain javascript code is located
So for a long time now I have been under the assumption that, while it does performance gains, one of the primary reasons we minify javascript/css is to give a modicum of obfuscation to it so that it is harder to reverse engineer.
However a friend of mine just showed me how it is not only possible; but extremely simple to just reverse minification on minified javascript and css.
So my question is - other than performance gains, what is the point? Is there any other actual way to protect javascript from being simply stolen right from your site?
Javascript minification is done primarily to increase performance. Upon minification, it's not uncommon to see >25% reduction in script size. On top of this, some minify-ers/compilers will obfuscate your code a little as well, renaming functions and variables to less obvious names.
As you've pointed out, it can always been unminified or pretty-printed, but since Javascript is a non-compiled, client-side language there isn't a whole lot you can do to protect your javascript.
See this link on javascript obfuscation.
If you have proprietary code or code you really don't want users seeing, you'll have to keep it server side. Consider moving it to a server side language such as PHP, Python, C, etc and expose the functions via web services.
There is no way to prevent javascript from being stolen directly off your site. It is "stolen" the instant someone visits your site and loads the HTML page or file containing the javascript code. Minification will do nothing more from a security perspective than obfuscate your code from a casual browser. It's primary purpose is for performance.
Rule of thumb: If you don't want the user to have access to it, don't send it to the client/browser.
Is there a reason not to inline CSS & JS when I make a mobile-ONLY site, to save bandwidth?
The only possible benefit I can think of is a couple less HTTP requests, but you totally give up the benefits of having the files cached if you do so.
Caching is a good thing and it saves bandwidth, so I can't see why you'd want to lose that advantage.
Besides that (not related to performance), maintenance will be a nightmare with everything inline, as it would be with any site.
I wouldn't be the least bit surprised if there were even more compelling reasons not to.
Use separate files.
Yes. First of all, you'll either have to code like that or inline them dynamically. Dynamically = waste of processing power. Code like that = hard to maintain and bad practice. And for what? You barely save any bandwidth at all, and it makes caching impossible and might actually slow you down. Now minification, on the other hand... that's what you should do instead. Minify your CSS and JavaScript, combine them into one file, and it's okay if you do this dynamically because the benefits outweigh the problems.
In-lining everything has different effects:
Reduces number of requests -- but increases your HTML file size
Increased HTML file size -- Load time increases considerably
No caching -- you have lost a good opportunity
Maintenance is like hell -- unless you inline as a step of your development process
A good blog post you can read - Why inlining everything is not the answer
There he recommends only to inline very small files (less than 1KB)
Hey by the way, why not inline -- Google does it in their homepage. Anyone who has 'View-ed Source' Google has seen it. But still its your choice.
If you are still thinking to reduce the number of HTTP requests then it is better to use a build tool to do the inlining autonomously. Otherwise you'll have to go through the 'maintenance hell'.
Yes, this reason is named cache :-) not inline css and js will be cached (Mobile browsers with html support use cache)
The site I am developing has a large amount of javascript that is shared across various functionality, and an equally large amount of feature-specific javascript. I've read all about using one monolithic javascript file vs. many smaller ones.
For my purposes, the huge-file approach would not only result in a script difficult to maintain, but contain a lot of unneeded javascript as well. At the same time, separating the javascript so that only the required code is included would result in an excessive number of files / HTTP requests. The idea of including even a moderate amount of unneeded code seems contrary to the concepts of proper software design, besides the additional file size overhead for the user.
I have found the mod_concat module for Apache which seems like it would solve my problem entirely - I could separate my javascripts into as many files as I want, include only those necessary, and take almost no hit on performance.
Is this actually the case? Is the only potential drawback the need to manage many files? I know mod_concat has not been around forever, so I'm also looking for a bit of background on a) how this was handled before, and b) if, even with code concatenation, including a moderate amount of unneeded javascript is considered acceptable (or even a best practice).
Thanks, Brian
I don't think you need an apache module for that. Creating one minified JS file for production should be the best way to go, because it is only loaded once and then cached by the browser. Although for development of course, it makes sense to have your application split into separate files.
My personal favorite for JavaScript module management and compression is Steal JS which is part of the great JavaScript MVC framework (could be generally interesting for larger JS applications). It can load module files dynamically during development and for production you can create one compressed JavaScript file (it can do CSS, too).
Another alternative is RequireJS but I only had a quick look at it.
I would like to know when I should include external scripts or write them inline with the html code, in terms of performance and ease of maintenance.
What is the general practice for this?
Real-world-scenario - I have several html pages that need client-side form validation. For this I use a jQuery plugin that I include on all these pages. But the question is, do I:
write the bits of code that configure this script inline?
include all bits in one file that's share among all these html pages?
include each bit in a separate external file, one for each html page?
Thanks.
At the time this answer was originally posted (2008), the rule was simple: All script should be external. Both for maintenance and performance.
(Why performance? Because if the code is separate, it can easier be cached by browsers.)
JavaScript doesn't belong in the HTML code and if it contains special characters (such as <, >) it even creates problems.
Nowadays, web scalability has changed. Reducing the number of requests has become a valid consideration due to the latency of making multiple HTTP requests. This makes the answer more complex: in most cases, having JavaScript external is still recommended. But for certain cases, especially very small pieces of code, inlining them into the site’s HTML makes sense.
Maintainability is definitely a reason to keep them external, but if the configuration is a one-liner (or in general shorter than the HTTP overhead you would get for making those files external) it's performance-wise better to keep them inline. Always remember, that each HTTP request generates some overhead in terms of execution time and traffic.
Naturally this all becomes irrelevant the moment your code is longer than a couple of lines and is not really specific to one single page. The moment you want to be able to reuse that code, make it external. If you don't, look at its size and decide then.
If you only care about performance, most of advice in this thread is flat out wrong, and is becoming more and more wrong in the SPA era, where we can assume that the page is useless without the JS code. I've spent countless hours optimizing SPA page load times, and verifying these results with different browsers. Across the board the performance increase by re-orchestrating your html, can be quite dramatic.
To get the best performance, you have to think of pages as two-stage rockets. These two stages roughly correspond to <head> and <body> phases, but think of them instead as <static> and <dynamic>. The static portion is basically a string constant which you shove down the response pipe as fast as you possibly can. This can be a little tricky if you use a lot of middleware that sets cookies (these need to be set before sending http content), but in principle it's just flushing the response buffer, hopefully before jumping into some templating code (razor, php, etc) on the server. This may sound difficult, but then I'm just explaining it wrong, because it's near trivial. As you may have guessed, this static portion should contain all javascript inlined and minified. It would look something like
<!DOCTYPE html>
<html>
<head>
<script>/*...inlined jquery, angular, your code*/</script>
<style>/* ditto css */</style>
</head>
<body>
<!-- inline all your templates, if applicable -->
<script type='template-mime' id='1'></script>
<script type='template-mime' id='2'></script>
<script type='template-mime' id='3'></script>
Since it costs you next to nothing to send this portion down the wire, you can expect that the client will start receiving this somewhere around 5ms + latency after connecting to your server. Assuming the server is reasonably close this latency could be between 20ms to 60ms. Browsers will start processing this section as soon as they get it, and the processing time will normally dominate transfer time by factor 20 or more, which is now your amortized window for server-side processing of the <dynamic> portion.
It takes about 50ms for the browser (chrome, rest maybe 20% slower) to process inline jquery + signalr + angular + ng animate + ng touch + ng routes + lodash. That's pretty amazing in and of itself. Most web apps have less code than all those popular libraries put together, but let's say you have just as much, so we would win latency+100ms of processing on the client (this latency win comes from the second transfer chunk). By the time the second chunk arrives, we've processed all js code and templates and we can start executing dom transforms.
You may object that this method is orthogonal to the inlining concept, but it isn't. If you, instead of inlining, link to cdns or your own servers the browser would have to open another connection(s) and delay execution. Since this execution is basically free (as the server side is talking to the database) it must be clear that all of these jumps would cost more than doing no jumps at all. If there were a browser quirk that said external js executes faster we could measure which factor dominates. My measurements indicate that extra requests kill performance at this stage.
I work a lot with optimization of SPA apps. It's common for people to think that data volume is a big deal, while in truth latency, and execution often dominate. The minified libraries I listed add up to 300kb of data, and that's just 68 kb gzipped, or 200ms download on a 2mbit 3g/4g phone, which is exactly the latency it would take on the same phone to check IF it had the same data in its cache already, even if it was proxy cached, because the mobile latency tax (phone-to-tower-latency) still applies. Meanwhile, desktop connections that have lower first-hop latency typically have higher bandwidth anyway.
In short, right now (2014), it's best to inline all scripts, styles and templates.
EDIT (MAY 2016)
As JS applications continue to grow, and some of my payloads now stack up to 3+ megabytes of minified code, it's becoming obvious that at the very least common libraries should no longer be inlined.
Externalizing javascript is one of the yahoo performance rules:
http://developer.yahoo.com/performance/rules.html#external
While the hard-and-fast rule that you should always externalize scripts will generally be a good bet, in some cases you may want to inline some of the scripts and styles. You should however only inline things that you know will improve performance (because you've measured this).
i think the specific to one page, short script case is (only) defensible case for inline script
Actually, there's a pretty solid case to use inline javascript. If the js is small enough (one-liner), I tend to prefer the javascript inline because of two factors:
Locality. There's no need to navigate an external file to validate the behaviour of some javascript
AJAX. If you're refreshing some section of the page via AJAX, you may lose all of your DOM handlers (onclick, etc) for that section, depending on how you binded them. For example, using jQuery you can either use the live or delegate methods to circumvent this, but I find that if the js is small enough it is preferrable to just put it inline.
Another reason why you should always use external scripts is for easier transition to Content Security Policy (CSP). CSP defaults forbid all inline script, making your site more resistant to XSS attacks.
I would take a look at the required code and divide it into as many separate files as needed. Every js file would only hold one "logical set" of functions etc. eg. one file for all login related functions.
Then during site developement on each html page you only include those that are needed.
When you go live with your site you can optimize by combining every js file a page needs into one file.
The only defense I can offer for inline javascipt is that when using strongly typed views with .net MVC you can refer to c# variables mid javascript which I've found useful.
On the point of keeping JavaScript external:
ASP.NET 3.5SP1 recently introduced functionality to create a Composite script resource (merge a bunch of js files into one). Another benefit to this is when Webserver compression is turned on, downloading one slightly larger file will have a better compression ratio then many smaller files (also less http overhead, roundtrip etc...). I guess this saves on the initial page load, then browser caching kicks in as mentioned above.
ASP.NET aside, this screencast explains the benefits in more detail:
http://www.asp.net/learn/3.5-SP1/video-296.aspx
Three considerations:
How much code do you need (sometimes libraries are a first-class consumer)?
Specificity: is this code only functional in the context of this specific document or element?
Every code inside the document tends to make it longer and thus slower. Besides that SEO considerations make it obvious, that you minimize internal scripting ...
External scripts are also easier to debug using Firebug. I like to Unit Test my JavaScript and having it all external helps. I hate seeing JavaScript in PHP code and HTML it looks like a big mess to me.
Another hidden benefit of external scripts is that you can easily run them through a syntax checker like jslint. That can save you from a lot of heartbreaking, hard-to-find, IE6 bugs.
In your scenario it sounds like writing the external stuff in one file shared among the pages would be good for you. I agree with everything said above.
During early prototyping keep your code inline for the benefit of fast iteration, but be sure to make it all external by the time you reach production.
I'd even dare to say that if you can't place all your Javascript externally, then you have a bad design under your hands, and you should refactor your data and scripts
Google has included load times into it's page ranking measurements, if you inline a lot, it will take longer for the spiders to crawl thru your page, this may be influence your page ranking if you have to much included. in any case different strategies may have influence on your ranking.
well I think that you should use inline when making single page websites as scripts will not need to be shared across multiple pages
Having internal JS pros:
It's easier to manage & debug
You can see what's happening
Internal JS cons:
People can change it around, which really can annoy you.
external JS pros:
no changing around
you can look more professional (or at least that's what I think)
external JS cons:
harder to manage
its hard to know what's going on.
Always try to use external Js as inline js is always difficult to maintain.
Moreover, it is professionally required that you use an external js since majority of the developers recommend using js externally.
I myself use external js.