When writing javascript for a specific page in a site, when do you want to turn the javascript into a function and include it in application.js?
I've seen suggestions about doing this (and minifying or gzip-ing) to minimize HTTP requests. That makes sense, but what about maintainability? If I have js code specific to one view, it seems like more work to look into a potentially massive application.js. That code could be embedded into that view or put in its own .js (or .js.erb or .rjs) file in that view folder.
I've seen another suggestion that Rails automatically merges all javascript into one file. Is this true?
TLDR: how much or how little should a developer worry about optimization when writing javascript?
As I haven't seen an answer in about a month, I'll answer this question to the best of my current knowledge.
Rails 3.1 (currently at release candidate 4) introduces sprockets, which will compile all javascript in a rails project into one file. It even comes with tools to minify and compress javascript so that it's all delivered to the client at once.
Related to sprockets is the Rails 3.1 asset pipeline. As I understand, it's a folder hierarchy/abstraction. Javascripts can go into 3 folders:
/apps/assets/javscripts/
Javascript files specific to the application, including application.js. This should only contain the manifest of javascript files you want to include in your project. The rails new tool will generate this file and include jquery in the manifest.
/lib/assets/javascripts/
Javascript files written by the developer that are more general purpose. (My impression is that this would be for javascript libraries you develop to drop into multiple applications)
/vendor/assets/javascripts/
Third party javascript files (i.e. JQuery, Modernizr)
All files in these folders will appear to the client inside /assets/, abstracting out the server side file paths. I assume this is meant to help the developer organize javascript files.
To answer my own question
Put javascript functions into separate files, group them logically. My test app indicated that subfolders within .../assets/javascripts/ are ok if and only if the subfolder path is included in the manifest.
I.E. putting //= subfolder/js_file in the manifest will work. Putting //= js_file will not if js_file is inside .../javascripts/subfolder/
DHH mentions a "rule of 13" in his talk (linked below). If the number of javascripts in a folder exceeds 13, it starts to look messy and unmanageable. This would be a good time to group javascript files into subfolders.
Use the built in Rails 3.1 minifier and compressor (or install a preferred gem)
Refactor javascript code from time to time. Move functions to /lib/assets/javascripts/ over time. (The goal is to eventually recognize when you want to write general purpose javascript functions as opposed to application-specific ones and eliminate this refactor step)
More Resources
a blog post covering all changes in Rails 3.1
DHH's talk on Rails 3.1 changes, May 16 2011 (~1 hr)
Related
Doing translation in JavaScript in Django apps is covered in the documentation quite well. However, the built-in Django way is to load a JS file in a <script>. Of course, they suggest to cache this, but one either needs to use etags or another mechanism and it will normally add at least one more request to the page load.
However, most decent websites already have a build system for preparing static files, i.e. using gulp - for compiling SCSS, sprites and whatnot. This is the perfect place to build a JS translation catalog, concatenate it with the rest of the JS and make 1 single bundled JS file. There doesn't seem to be way to generate a static JS file from the current *.mo files. Reading through the Django code, it seems that the JavaScriptCatalog view is responsible for generating that JS code and it's not easily reusable for that purpose either.
TL;DR Is there an easy way to generate a static .js file with the current translation catalog in a fashion similar to using the built-in JavaScriptCatalog?
Take a look at https://github.com/zyegfryed/django-statici18n which I think does what you're asking for. Note however, that there will be one javascript catalog file per supported language, and you must serve only one of them to the browser. So to make "1 single bundled JS file" means making one bundled file per language.
Do i have to include all my javascript file while loading main index page?
In single page application when we are not logged in, we include all of our .js file in main index file. This contains js file that is only needed when users are logged in.
What is better approach of managing angular app in this context?
Simple answer: yes.
Your application is a single-page one, so you can combine all JS files into one and load it at one request. It saves time for processing in the future.
Alternatively, create two pages login.html and others.html, then load two different sets of JS files accordingly.
Normally, nowadays the bandwidth is not the bottleneck, loading a larger JS file does not make trouble (usually).
You can split your code into multiple modules and then just load the js needed for that module.
I suggest using Gulp with packages to inject HTML when appropriate. You then have single lines of code as place holders for your Javascript and you run the Gulp task to inject the Javascript into the areas where it is needed.
You could also run gulp tasks to minify your js into just a few minified files. You will need to be sure your js in min safe (gulp can do this too).
If you make AMD - most often using RequireJS - then you won't need to include all from the very beginning.
A while ago we did a similar project, although without AngularJS, and by using RequireJS we made the different pages, which use different files. And this way people's browsers will never download certain files if they never go to certain pages.
(Of course, we had many pages inside the app, not just 2 or 3, where this wouldn't make any difference.)
What are some standard practices for managing a medium-large JavaScript application? My concerns are both speed for browser download and ease and maintainability of development.
Our JavaScript code is roughly "namespaced" as:
var Client = {
var1: '',
var2: '',
accounts: {
/* 100's of functions and variables */
},
orders: {
/* 100's of functions and variables and subsections */
}
/* etc, etc for a couple hundred kb */
}
At the moment, we have one (unpacked, unstripped, highly readable) JavaScript file to handle all the business logic on the web application. In addition, there is jQuery and several jQuery extensions. The problem we face is that it takes forever to find anything in the JavaScript code and the browser still has a dozen files to download.
Is it common to have a handful of "source" JavaScript files that gets "compiled" into one final, compressed JavaScript file? Any other handy hints or best practices?
The approach that I've found works for me is having seperate JS files for each class (just as you would in Java, C# and others). Alternatively you can group your JS into application functional areas if that's easier for you to navigate.
If you put all your JS files into one directory, you can have your server-side environment (PHP for instance) loop through each file in that directory and output a <script src='/path/to/js/$file.js' type='text/javascript'> in some header file that is included by all your UI pages. You'll find this auto-loading especially handy if you're regularly creating and removing JS files.
When deploying to production, you should have a script that combines them all into one JS file and "minifies" it to keep the size down.
Also, I suggest you to use Google's AJAX Libraries API in order to load external libraries.
It's a Google developer tool which bundle majors JavaScript libraries and make it easier to deploy, upgrade and make them lighter by always using compressed versions.
Also, it make your project simpler and lighter because you don't need to download, copy and maintain theses libraries files in your project.
Use it this way :
google.load("jquery", "1.2.3");
google.load("jqueryui", "1.5.2");
google.load("prototype", "1.6");
google.load("scriptaculous", "1.8.1");
google.load("mootools", "1.11");
google.load("dojo", "1.1.1");
Just a sidenode - Steve already pointed out, you should really "minify" your JS files. In JS, whitespaces actually matter. If you have thousand lines of JS and you strip only the unrequired newlines you have already saved about 1K. I think you get the point.
There are tools, for this job. And you should never modify the "minified"/stripped/obfuscated JS by hand! Never!
In our big javascript applications, we write all our code in small separate files - one file per 'class' or functional group, using a kind-of-like-Java namespacing/directory structure. We then have:
A compile-time step that takes all our code and minifies it (using a variant of JSMin) to reduce download size
A compile-time step that takes the classes that are always or almost always needed and concatenates them into a large bundle to reduce round trips to the server
A 'classloader' that loads the remaining classes at runtime on demand.
For server efficiency's sake, it is best to combine all of your javascript into one minified file.
Determine the order in which code is required and then place the minified code in the order it is required in a single file.
The key is to reduce the number of requests required to load your page, which is why you should have all javascript in a single file for production.
I'd recommend keeping files split up for development and then create a build script to combine/compile everything.
Also, as a good rule of thumb, make sure you include your JavaScript toward the end of your page. If JavaScript is included in the header (or anywhere early in the page), it will stop all other requests from being made until it is loaded, even if pipelining is turned on. If it is at the end of the page, you won't have this problem.
Read the code of other (good) javascript apps and see how they handle things. But I start out with a file per class. But once its ready for production, I would combine the files into one large file and minify.
The only reason, I would not combine the files, is if I didn't need all the files on all the pages.
My strategy consist of 2 major techniques: AMD modules (to avoid dozens of script tags) and the Module pattern (to avoid tightly coupling of the parts of your application)
AMD Modules: very straight forward, see here: http://requirejs.org/docs/api.html also it's able to package all the parts of your app into one minified JS file: http://requirejs.org/docs/optimization.html
Module Pattern: i used this Library: https://github.com/flosse/scaleApp you asking now what is this ? more infos here: http://www.youtube.com/watch?v=7BGvy-S-Iag
I am reading a book about "Ruby on Rails" and one of the task includes modifying the code till now, creating additional JavaScript functionality. The JavaScript itself is easy, just few lines of code, so my question is conceptual at all.
I am executing the first activity and in the discussion folks said that the new code should be created in a separate js.erb file in the views folder.
My questions is what is the better way to solve the issue:
Create additional js.erb file in views folder
OR
Add the additional JavaScript code in the
assets->javascript->viewname.js.coffee
The people from the discussion use the second technique but is it more appropriate to add the JavaScript in the assets as it will be executed with the view?
EDIT:
I am using Ubuntu 12.04 and my Rails version is 3.2.8.
Number two is the way to go! Let the Rails 3 Asset Pipeline manage Javscript, CSS and image files for you. The .coffee extension is optional, depending on if you want to write in Coffeescript or not.
What are some standard practices for managing a medium-large JavaScript application? My concerns are both speed for browser download and ease and maintainability of development.
Our JavaScript code is roughly "namespaced" as:
var Client = {
var1: '',
var2: '',
accounts: {
/* 100's of functions and variables */
},
orders: {
/* 100's of functions and variables and subsections */
}
/* etc, etc for a couple hundred kb */
}
At the moment, we have one (unpacked, unstripped, highly readable) JavaScript file to handle all the business logic on the web application. In addition, there is jQuery and several jQuery extensions. The problem we face is that it takes forever to find anything in the JavaScript code and the browser still has a dozen files to download.
Is it common to have a handful of "source" JavaScript files that gets "compiled" into one final, compressed JavaScript file? Any other handy hints or best practices?
The approach that I've found works for me is having seperate JS files for each class (just as you would in Java, C# and others). Alternatively you can group your JS into application functional areas if that's easier for you to navigate.
If you put all your JS files into one directory, you can have your server-side environment (PHP for instance) loop through each file in that directory and output a <script src='/path/to/js/$file.js' type='text/javascript'> in some header file that is included by all your UI pages. You'll find this auto-loading especially handy if you're regularly creating and removing JS files.
When deploying to production, you should have a script that combines them all into one JS file and "minifies" it to keep the size down.
Also, I suggest you to use Google's AJAX Libraries API in order to load external libraries.
It's a Google developer tool which bundle majors JavaScript libraries and make it easier to deploy, upgrade and make them lighter by always using compressed versions.
Also, it make your project simpler and lighter because you don't need to download, copy and maintain theses libraries files in your project.
Use it this way :
google.load("jquery", "1.2.3");
google.load("jqueryui", "1.5.2");
google.load("prototype", "1.6");
google.load("scriptaculous", "1.8.1");
google.load("mootools", "1.11");
google.load("dojo", "1.1.1");
Just a sidenode - Steve already pointed out, you should really "minify" your JS files. In JS, whitespaces actually matter. If you have thousand lines of JS and you strip only the unrequired newlines you have already saved about 1K. I think you get the point.
There are tools, for this job. And you should never modify the "minified"/stripped/obfuscated JS by hand! Never!
In our big javascript applications, we write all our code in small separate files - one file per 'class' or functional group, using a kind-of-like-Java namespacing/directory structure. We then have:
A compile-time step that takes all our code and minifies it (using a variant of JSMin) to reduce download size
A compile-time step that takes the classes that are always or almost always needed and concatenates them into a large bundle to reduce round trips to the server
A 'classloader' that loads the remaining classes at runtime on demand.
For server efficiency's sake, it is best to combine all of your javascript into one minified file.
Determine the order in which code is required and then place the minified code in the order it is required in a single file.
The key is to reduce the number of requests required to load your page, which is why you should have all javascript in a single file for production.
I'd recommend keeping files split up for development and then create a build script to combine/compile everything.
Also, as a good rule of thumb, make sure you include your JavaScript toward the end of your page. If JavaScript is included in the header (or anywhere early in the page), it will stop all other requests from being made until it is loaded, even if pipelining is turned on. If it is at the end of the page, you won't have this problem.
Read the code of other (good) javascript apps and see how they handle things. But I start out with a file per class. But once its ready for production, I would combine the files into one large file and minify.
The only reason, I would not combine the files, is if I didn't need all the files on all the pages.
My strategy consist of 2 major techniques: AMD modules (to avoid dozens of script tags) and the Module pattern (to avoid tightly coupling of the parts of your application)
AMD Modules: very straight forward, see here: http://requirejs.org/docs/api.html also it's able to package all the parts of your app into one minified JS file: http://requirejs.org/docs/optimization.html
Module Pattern: i used this Library: https://github.com/flosse/scaleApp you asking now what is this ? more infos here: http://www.youtube.com/watch?v=7BGvy-S-Iag