I admit, I don't know too much about javascript, mostly I just "steal and modify" from Javascript.com and Dynamic Drive.
I've run across a few scripts that call two .js files
<script type="text/javascript" src="lib/prototype.js">
</script>
<script type="text/javascript" src="src/aptabs.js">
</script>
and was wondering why, can I safely merge them both with my external javascript or is there a sort of incompatibility that prevents all the code from sharing the same file?
It's often good to separate code with different concerns. Those two files might come from different places. Say prototype is upgraded and you want the new goodness. Then you can just replace the prototype.js file on your server rather than editing your huge file and do the surgery on it.
EDIT: It's also "nicer" for the browser to be able to cache the files individually. If your question comes from a concern of duplicating that block of code in several html files I suggest you make one snippet of it from the server side and include it your html files through whatever means you have at hand/feel comfy with.
It's actually better performance wise to have them both in the same file- Depending on how your site is architected. The principle is to reduce the number of http requests, as each one carries some overhead.
That said, that's something best left to the very end of production. During development it's easier to have everything seperate. If you're going to join them, it's best to have an automated build script to do the operations.
I'm pretty sure the javascript has no idea which file it has loaded from, so there shouldn't be a problem merging it, however...
Personally, I'd keep them separate. It will make it simpler to co-ordinate versioning etc. For most repeat visits, the script will be cached by the browser anyway, so 2 vs 1 isn't really a huge issue. But when you do upgrade one (or the other), the client only needs to download half as much. But again, since it is generally cached it isn't a biggie!
So for simplicity - keep the scripts in their original forms. Given your opening comment "I don't know too much about javascript", this is by far the best approach; I don't mean that disparagingly - simply that if something goes wrong, you don't want to have to find if you broke it, or it was broke already.
Edit: it also makes it easy to re-order, for example if you are using two scripts that use the same terminology like $ in jQuery, which also supports a mode with the explicit naming.
Related
I'm new to JavaScript.
How should I split my functions across external scripts? What is considered good practice? should all my functions be crammed into one external .js file or should I group like functions together?
I would guess more files mean more HTTP requests to obtain the script and that could slow down performance? However more files keep things organized: for example, onload.js initializes things on load, data.js retrieves data from the server, ui.js refer to UI handlers...
What's the pros advice on this?
Thanks!
As Pointy mentioned, you should try a tool. Try Grunt of Brunch, both are meant to help you in the build process, and you can configure them to combine all your files when you are ready for prod (also, minify, etc), while keeping separate files when you are developing.
When releasing a product, you generally want as little HTTP requests as possible to load a page (Hence image sprites, for example)
So I'd suggest concatenating your .js's for release, but keeping them separated in a way that works well for you, during development.
Keep in mind that if you "use strict", concatenating scripts might be a source of errors.
(more info on js strict mode here)
It depends on the size, count of your scripts and how many of them you use at any time.
Many performance good practices claim (and there's good logic in this) that it's good to inline your JavaScript if it's small enough. This leads to lower count of HTTP requests but it also prevents the browser from caching the JavaScript so you should be very careful. That's why there're a practices even to inline your images (using base64 encoding) in some special cases (for example look at Bing.com, all their JavaScript is inline).
If you have a lot of JavaScript files and you're using just a little part of them at any time (not only as count but as size) you can load them asynchronously (for example using require.js). But this will require a lot of changes in your application design if you haven't considered it at the beginning (and also make your application complexity bigger).
There are practices even to cache your CSS/JavaScript into the localStorage. For further information you can read the Web Performance Daybook
So let's make something like a short retrospection.
If you have your JavaScript inline this will reduce the first load of the page. The inline JavaScript won't be cached by the browser so every next load of your page will be slower that if you have used external files.
If you are using different external files make sure that you're using all of them or at least big part of them because you can have redundant HTTP requests for files which actually are unnecessary loaded. This will lead to better organization of your code but probably greater load time (still don't forget the browser cache which will help you).
To put everything in at single file will reduce your HTTP requests but you'll have one big file which will block your page loading (if you're using synchronous loading of the JS file) until the file have been loaded completely. In such case I can recommend you to put this big file in the end of the body.
For performance tracking you can use tools like YSlow.
When I think about good practice, then I think of MVC patterns. One might argue if this is the way to go in development, but many people use it to structure what the want to achieve. Usually it is not advisable to use MVC at all if the project is just too small - just like creating a full C++ windows app if you just needed a simple C program with a for loop.
In any case, MVC or MV* in javascript will help you structure your code to the extent that all the actions are part of the controllers, while object properties are just stored in the model. The views then are just for showing purposes and are rendered for the user via special requests or rendinering engines. When I stared using MV*, I stared with BackboneJS and the Guide "Developing BackboneJS Applications" from Addy Osmani. Of course there are a multitude of other frameworks that you can use to structure your code. They can be found on the TodoMVC website.
What you can also do is derive your own structure from their apps and then use the directory structure for your development (but without the MV* framework).
I do not agree to your concern that using such a structure lead to more files, which mean more HTTP requests. Of course this is true during development, BUT remember, the user should get a performance enhanced (i.e. compiled) and minified version as a script. Therefore even if you are developing in such an organized way, it makes more sense to minify/uglify and compile your scripts with closure compiler from Google.
What is the best way to deal with multiple client side templates?
I noticed that if I keep them in my "mother" html file, it soon gets bloated with stuff, so I thought that maybe it would be better if I just put them in separate js files and load them one by one.
Another idea of mine was to avoid putting them separately as templates, but rather write them as strings and sort of couple them with the backbone.js views which are going to use them. I know that this would bring a lot of negative from designers, web developers, and software engineers in general, but for the projects I am working on, this seems like a very speedy way to develop because I have logic and layout at the same place. Plus, by reverse engineering, I proved that a bunch of prominent web services are doing the same so ...
One option is to use RequireJS, which includes a 'text' plugin for templates.
You can then use the r.js optimizer to combine all of these (plus JS modules, if you go that route) into a single file.
The optimizer can be run either as part of your build process, or in-process if you're using node.js.
You can have them in separate files, but combine into one file on a server side.
And take a lot of negative from me for your idea to keep templates in strings :). It might work until they are simple, but when they get more complex it gets badly, because html structure is not so obvious, so it is harder to write css and so on.
As #stusmith said, require.js is a good option.
also, take a look at the boilerplate's examples
http://backboneboilerplate.com/
https://github.com/thomasdavis/backboneboilerplate/blob/gh-pages/js/views/backbone/page.js
cheers
I've seen a few ways that you can make a javascript file include other javascript files, but they all seem pretty hacky - mostly they involve tacking the javascript file onto the end of the current document and then loading it in some way.
Why doesn't javascript just include a simple "load this file and execute the script in it" include directive? It's not like this is a new concept. I know that everyone is excited about doing everything in HTML5 with javascript etc, but isn't it going to be hard if you have to hack around omission of basic functionality like this?
I can't see how it would be a security concern, since a web page can include as many javascript files as it likes, and they all get executed anyway.
The main problems with the current inclusion system (ie, add additional script tags) involve latency. Since a script tag can insert code at the point of inclusion, as soon as a script tag is encountered, further parsing has to more-or-less stop until the JS downloads and is executed (although the browser can continue to fetch resources in parallel). If the JS decides to run an inclusion, you've just added more latency on top of this - now you can't even fetch your scripts in parallel.
Basically, it's trying to solve a problem that doesn't exist (since JS can already tack on additional script tags to do an inclusion), while making the latency problem worse. There are javascript minifiers out there that can merge JS files; you should look into using those instead, as they will help improve latency issues as well.
Actually, YUI 3 solves this problem beautifully. Feel free to check out the documentation: http://developer.yahoo.com/yui/3/yui/#use (that's the specific Use function which does this magic). Basically it works like this:
You define modules
When you create the core YUI object with YUI(), you specify which modules your code needs
Behind the scenes, YUI checks if those modules are loaded. If not, it asynchronously loads them on the page.
I've also read that the jQuery team's working on something similar (someone back me up here).
As to the philosophical argument that it'd be nice if this was built in, I think that may be a good feature. On the other hand, the simplicity of javascript is nice too. It allows a much lower point of entry for beginning programmers to do their thing. And for those of us that need it, great libraries like YUI are getting better every day.
the requirejs project attempts to solve this problem, please see for example
http://requirejs.org/docs/why.html
(I don't use it yet, though)
my rails applications (all 2.3.5) use a total mix of inline javascript, rjs, prototype and jquery. Let's call it learning or growing pains. Lately i have been more and more infatuated with unobtrusive javascript. It makes your html clean, in the same way css cleaned it up.
But most examples i have seen are small examples, and they put all javascript(jquery) inside application.js
Now i have a pretty big application, and i am thinking up ways to structure my js. I like somehow that my script is still close to the view, so i am thinking something like
orders.html.erb
orders.js
where orders.js contains the unobtrusive javascript specific to that view. But maybe that's just me being too conservative :)
I have read some posts by Yehuda Katz about this very problem here and here, where he tackles this problem. It will go through your js-files and only load those relevant to your view. But alas i can't find a current implementation.
So my questions:
how do you best structure your unobtrusive javascript; manage your code, how do you make sure that it is obvious from the html what something is supposed to do. I guess good class names go a long way :)
how do you arrange your files, load them all in? just a few? do you use content_for :script or javascript_include_tag in your view to load the relevant scripts. Or ... ?
do you write very generic functions (like a delete), with parameters (add extra attributes?), or do you write very specific functions (DRY?). I know in Rails 3 there is a standard set, and everything is unobtrusive there. But how to start in Rails 2.3.5?
In short: what are the best practices for doing unobtrusive javascript in rails? :)
I do not think there is one best practice, but I'll let you know what I do.
I have a series of js files each for with their own purpose in the public/javascripts/ directory. Some examples could be utility.js chat.js shopping_basket.js and so on.
I use asset packager and define one big fat collection for all my general use functionality and another for admin only functionality. Round trips to the server cost way too much. I basically include all the js in on first page load minified into one blob (in general)
I allow basic $(document).ready hooks inline in the pages, and keep them really short.
Data that my js files needs to access is rendered inline with the page. (Usually in the DOM, sometimes as vars - Eg. var xyz = 100)
I will usually develop my controllers with javascript off (and make sure it all works), then I turn it on and sprinkle a few if request.xhr? where needed.
Keep in mind, Rail 3.1 introduces a built-in best practice, see: http://guides.rubyonrails.org/asset_pipeline.html - on a personal note I have had performance and configuration issues with the new pipeline, however many others have had great success with it.
I recently documented how I have been managing javascript in Ruby on Rails. I basically break things down into many small, granular files, each with an appropriate namespace and then merge them all into a single file for production using asset_packager.
I found this post while trying to solve the same problem, but none of the existing solutions struck me as the right one. I wrote up my approach here. I love Rails' convention over configuration, so I wanted the same approach to including Javascripts that are applicable only to a particular action page. If nothing else, it's at least another approach to add to your options.
One of my co-workers is thinking that it is simpler to just include the document.ready() calls (MULTIPLE) for jquery anywhere in an html document, rather than trying to have them all in the head, foot or in an external js file. Can you give me your thoughts about this?
The document.ready stuff is loaded by modules that are included in a main template. I think this is messy. But I need a good argument point.
There are a number of problems with your coworker's approach:
It's not DRY. You must repeat the code each time you want to invoke it.
No ability to cache the same Javascript; it must be loaded with each new page.
If you decide to do it a different way later, N files are now different instead of one.
It will not be immediately obvious to a maintainer that this code is repeated across N different files.
Your coworker's approach is actually quite reasonable and pragmatic.
For the sake of completeness I'll point out that putting too much in ready() in the external JS file is a mistake. I started doing this once and ended up with a page load time of 500-1000ms with all this unnecessary JS code that was being executed. The external JS file(s) should be for declaring functions. The page itself should declare which of those things to actually run. This combines the best of minimal code execution and maximises caching (since the JS file is the same for all your pages).
At the top of the page you don't know what modules/components will be included in the document unless you declare it there as well, which (imho) is a worse case of repeating yourself.
The ideal approach would be some sort of multi-pass templating process that would allow included modules/components to trigger code that needs to be run and your template processor will combine all that and put it at the top of the page. I've actually written systems like this and it is quite doable but it's also more tedious.
You say it's messy but the other side of that coin is that when you look at a page it's easy to determine what code belongs to which module/component because they're adjacent. If you had a big blob of JS at the top of the page, how do you know what relates to what?
As long as you don't end up with dozens of script blocks I think your cowowrker's approach is fine. Any alternative needs to be just as clear and not execute more code than necessary.
If it's not single page specific, I wouldn't recommend it because maintenance is going to be a pain. If it is page specific, it can be better to place it as low in the document as possible, especially if it loads external scripts. Check out Cuzillion, a tool that helps you find the best combination for loading times.
If they're in the document itself, you can use server-side variables in the javascript itself, if your page is dynamic (php, asp.net). This can be very handy, but it prevents the javascript from being usable outside the page as a standalone. But if you're sure you're never going to need that javascript outside the page, that's definitely an advantage.
It depends.
One motivating factor for putting Javascript in the body is for progressive loading. If the Javascript is just before the </body> then it'll be downloaded last. In fact, even Google Analytics recommends this approach when including their tracking snippet.
However, most of the time even if you're worried about progressive loading you should use an external js file. External js files can be cached aggressively to save bandwidth so they're generally preferred. The only exceptions to that are when it's a small piece of Javascript that only one page uses, or if the Javascript itself needs to be created dynamically with a server-side language and writing it inline is just plain easier to do in that case.
EDIT:
There are multiple ways to do whatever you're doing, I'm sure. And I don't know what you're doing exactly. But since you mentioned Javascript next to every module, that gave me an idea. You could create unique id's for a div around each module. And then you could have a js file which performs operations on each module by those div id's (via a jQuery selector). That'd be a very jQuery-able solution.