Short answer: One monolithic file with a far-future expires header.
Long answer: It depends. If you're Gmail and have over 1 megabyte of javascript in your application, then you're going to want to split that up to reduce load and improve user experience. For the rest of us though, the best solution I've found is to load your main library (such as jQuery) from a third-party CDN (like Google). Then split up your one monolithic file into two: lib.js
and app.js
. Lib should contain any third-party libraries, and app your site-specific code. The general idea being that you're very rarely going to be updating libraries or adding new ones, so that file will rarely ever have to be cache invalidated and re-downloaded by your users.
Use a technique such as the one described on this site to move almost all on-page <script>
tags without a src
attribute to an external file:
http://paulirish.com/2009/markup-based-unobtrusive-comprehensive-dom-ready-execution/
So what you should be left with are <script>
tags with a src
, and the only inline ones remaining should be because you need to pass data from your backend code to javascript (and want to avoid an AJAX request on page load that will block rendering). Say the namespace of my project is Foo
, then that one inline tag will look like:
<script type="text/javascript">
Foo.Context = {{ js_context|safe }};
</script>
js_context
is a variable I passed to my template from my backend, and is already a JSON object. The squiggly brackets and |safe
are just from the front-end template engine I happen to be using (in this case, Django's built-in templates). Now my page-specific code, living in app.js
, can look at the contents of Foo.Context
after document.ready
fires for any variables it needs while avoiding an initial AJAX request.
As usual for your static files, you should be serving them with far-future expires headers:
Cache-Control: public, max-age=31536000
When you update your scripts, your build step should either rename the concatenated and minified file or add a GET query parameter to the end of the <script>
src
, like so:
app.12345.js
or app.js?v=12345
That way your users will request the new file, breaking the cache. As a caveat, please be aware that old versions of some reverse-proxies (such as Squid) don't play nicely with GET parameters on static files, so the latter of those two options wouldn't work. But I have never run into that issue yet, so your milage may vary.
When you do get to the Gmail level of script sizes, you can start looking at using a library like LABjs or RequireJS, to dynamically only load the pieces of app.js
that you need for particular pages or functionality.
Last but not least, I hope your <script>
tags are at the bottom of your page, right before the closing </body>
. This prevents the browser from showing a blank white page while your scripts are downloaded, parsed, and executed. The only exception to this rule are libraries that absolutely must be in the <head>
to function, such as Modernizr.
Background
Web development is all about communication. In this case, communication between two (2) parties, over the HTTP protocol:
- The Server - This party is responsible for serving pages.
- The Client - This party requests pages from the Server, and displays them to the user. In most cases, the client is a web browser.
- The User - The user uses the Client in order to surf the web, fill in forms, watch videos online, etc.
Each side's programming, refers to code which runs at the specific machine, the server's or the client's.
Basic Example
- The User opens his web browser (the Client).
- The User browses to http://google.com.
- The Client (on the behalf of the User), sends a request to http://google.com (the Server), for their home page.
- The Server then acknowledges the request, and replies the client with some meta-data (called headers), followed by the page's source.
- The Client then receives the page's source, and renders it into a human viewable website.
- The User types Stack Overflow into the search bar, and presses Enter
- The Client submits that data to the Server.
- The Server processes that data, and replies with a page matching the search results.
- The Client, once again, renders that page for the User to view.
Programming
Server-side Programming
Server-side programming, is the general name for the kinds of programs which are run on the Server.
Uses
- Process user input.
- Compiles pages.
- Structure web applications.
- Interact with permanent storage (SQL, files).
Example Languages
- PHP
- Python
- ASP.Net in C#, C++, or Visual Basic.
- Nearly any language (C++, C#, Java). These were not designed specifically for the task, but are now often used for application-level web services.
Client-side programming
Much like the server-side, Client-side programming is the name for all of the programs which are run on the Client.
Uses
- Make interactive webpages.
- Make stuff happen dynamically on the web page.
- Interact with temporary storage, and local storage (Cookies, localStorage).
- Send requests to the server, and retrieve data from it.
- Provide a remote service for client-side applications, such as software registration, content delivery, or remote multi-player gaming.
Example languages
- JavaScript (primarily)
- HTML*
- CSS*
- Any language running on a client device that interacts with a remote service is a client-side language.
*HTML and CSS aren't really "programming languages" per-se. They are markup syntax by which the Client renders the page for the User.
Best Answer
RobertHarvey is totally right: it depends. It could be a good solution but it is a terrible solution also for some projects.
In you question you state:
Based on that he chose the wrong solution. Now you also note that there are animations. So maybe, if those are exceptional, it might be a good solution. Let's state those animation could also be made with normal solutions.
Whether it is good or right is then simple: If it should work like a normal website, so with a good ranking in search engines, good accessibility and all other standard webdevelopers take care of it is just wrong. You build a website with a goal. If that is: Have normal people visit it to subscribe/buy/view etc. it won't meet that goal.
His arguments:
Yes, but this is a small website right? http://c2.com/cgi/wiki?PrematureOptimization
It is easier to create new sections.
Same here, localisation is something much more complex than just translating some pieces of text anyway. Education is here also the key.
Might be correct, seems simple to do. If a user has to do it then it directly becomes more difficult. With a database for example it might be possible to create a form for that.
This is true but not undoable with other solutions. Loading pieces of content with ajax (with changing the browser history) might solve this well. https://developer.mozilla.org/en/docs/DOM/Manipulating_the_browser_history
To take this into a broader level: It is nonsense to build a dedicated framework if it is just a simple site. Use the basics or an existing system for it. On the other side, it's a nice learning experience. We all tried to build a CMS once right? ;) His arguments are not strong, if he want to work more in this area more knowledge would be advisable.