2013-08-05



Remember back to when we had to spend a lot of time optimizing our project’s assets (images, CSS, etc..)? Well today, users have a much faster Internet connection and it appears that we can afford to use bigger images or bigger flash files with a lot of video and pictures inside. However, with the rise of mobile development, we are again back in that same situation. It is extremely important to create well optimized sites, so that we have faster applications, which download less content and respond immediately.

Images

Serve the Proper Size

Often times we use the same images for different parts of our websites. For example, in an online shop, all the products have an overview picture. Let’s say that we have three pages where we have to show those images – one page for listing the products, another page for the product’s details, and a third page which shows only the picture in its original size.

So, we need three different image sizes and if we use the same file for all three different places, then the browser will download the full size image even for the listing page, where we actually may only need a 200×200 picture. If the original file is around 1MB and we have ten products per page, then the user would download 10MB. That’s not a very good idea. If you can, try to generate different images for the different parts of your site, this will save a lot of KBs for your users. It is a good idea to have in mind the current screen resolution. For example, if somebody opens your site on their iPhone, there is no need to serve the giant header image, which you normally use. By using CSS media queries you are able to send an image with a smaller size:

Compression

Sending an image with just the proper dimensions is not always enough. Some file formats can be compressed a lot without losing their quality. There are many programs which can help you out. For example, Photoshop provides a nice feature called Save for Web and Devices:



There are loads of options in this dialog, but one of the most important ones is Quality. Setting it to something like 80% could decrease the file size considerably.

Of course, you can use code to compress the files, but I personally prefer Photoshop and I’m using it whenever possible. Here is a simple example written in PHP:

Sprites

One of the things that you can do to increase the performance of your application is to reduce the number of requests to the server. So, every new image means a new request. It’s a good idea to combine your images into one. The resulting image is called a sprite and with changing the background-position CSS style you are able to show the exact portion of the image, which you need. For example, Twitter Bootstrap uses sprites for its internal icons:



Then in the CSS, you can do something like this, to show whichever portion of the sprite you’d like:

Caching

The browser’s caching mechanism is your friend. Yes, sometimes during development it could lead to some very funny situations, but it really helps to improve your site’s performance. Every browser caches content like images, JavaScript or CSS. There are several ways to control the caching and I suggest that you check out this great article for a detailed review. In general, you can control the process by setting headers, like so:

Prefetching

HTML5 is moving forward every day. There is a nice feature called prefetching which tells the browser that you will need some resource in the near future and it should be downloaded now, in advance. For example:

Data URI Scheme / Inline Images

A couple of years ago I had to develop a simple web page, which was supposed to be just one HTML file. Of course there were several images, which I had to include. Data URI scheme helped me to solve the problem. The idea is to convert your images into a base64 encoded string and place it in the src attribute of the img tag. For example:

By using this approach, your image is actually in the HTML and you save one HTTP request. Of course, if you have a big image the string will be really long. Here is a simple PHP script which converts images to base64 strings:

You may find this useful in some cases, but keep in mind that it doesn’t work very well in IE.

CSS

I like to think that writing CSS is like writing code. You still have to organize your styles, to define different blocks and the relationship between them. That’s why I think CSS management is really important. Every part of the application should have its own styles and they should be nicely separated. Keeping everything into different files provides good organization, but also comes with its own problems.

We all know that the usage of the @import statement is not a very good idea. That’s because every new @import means a new request to the server. And if you have, for example, 20 different .css files it means that the browser will make 20 requests. And the browser doesn’t render/show the page before downloading all the styles. If some of your .css files are missing or it is very large, you will get a big delay before seeing something on the screen.

Use CSS Preprocessors

CSS preprocessors solve all the problems above. You still divide your styles into different files, but at the end, the preprocessor compiles everything into a single .css file. They actually offer a bunch of cool features like variables, nested blocks, mixins and inheritance. The code still looks like CSS, but it is well formatted/structured. There are few popular preprocessors that are worth checking – Sass, LESS, and Stylus. Here is a simple example written in LESS:

will produce

Or, for example if you have styling for a button and want to produce just the same button but with another color for the text, you could do this:

Efficient CSS

Normally, most developers don’t think about efficient CSS. The efficiency of the CSS reflects on the page’s rendering and if your styles are inefficient your application will be rendered slowly by browsers. An interesting fact is that browsers parse the CSS selectors from right to left. Which means that the following code:

… is not efficient at all. That’s because the engine will get all the <a> tags and will have to evaluate each of the parent elements to finally collect the needed style. You should also know that in terms of efficiency, the selectors are kind of ranked in the following order: ID, class, tag, and universal. This means that an element with an id set will be rendered faster than an element with just a tag selector. Of course, there is no sense to add ids on all the elements in the DOM tree, but you should definitely check your code and improve it where possible. For example, if you have something like this:

You should remove the ul part, because you have only one #navigation element on the page. Or in the following selector:

It is clear that the .content element is a child of the body tag. All the elements are actually children of this element.

Here are two helpful links on the this topic: developers.google.com and css-tricks.com

File Size

As we mentioned above, it is good to have as little code as possible, because the browser doesn’t render the page before downloading the CSS. Here are few tips to reduce the file size.

Combine similar styles:

… transforms to:

Use shorthands. Instead of:

Write it in this fashion:

Minify your CSS code. I.e. use a tool which generally removes all the spaces and new lines. For example CSSOptimiser or Minifycss. It’s a common practice to use such instruments on the server side of the application. I.e. something written in the language of the back-end. Normally these components minify your code and serve it to the user.

Put Your CSS Files in the <head> Tag

It is good practice to include your .css files in the head tag, that way the browser will download it first.

JavaScript

Reduce the Number of HTTP Requests

Same as with your CSS - it's good to reduce the number of requests being to sent to the server. In most cases, the loading of the JavaScript files will not stop the rendering of the page, but it will make some portions of the page nonfunctional.

Minify Your Code

There are bunch of libraries that do JavaScript minification. It's something that will reduce the files' size, but keep in mind that in a development environment it is good to keep your code clean. Most of these tools change the name of your variables and converts everything into a one-line string, which makes the debugging process almost impossible.

CommonJS, AMD, RequireJS - Give It a Try

JavaScript natively doesn't have a mechanism for managing modules. So, all those things are invented to solve this problem. They provide an API which you can use to define and use modules. For example, here is an example taken from http://requirejs.org/:

Inside of main.js, you can use require() to load any other scripts you need:

Use Namespaces

If we're talking about code organization then we can't skip the part about namespaces. Natively, there is no such feature in JavaScript, but you can still achieve the same thing with a little code. For example, if you want to build your own MVC framework, you will probably have the following classes:

If you leave things as they are in the above code, then they become public and there is a greater chance of producing conflicts with other libraries in your project. So, grouping them in an independent object (namespace) makes the framework protected:

Follow Design Patterns

There is no need to re-invent the wheel. JavasScript became really popular and there are a lot of good practices out there. Design patterns are reusable solutions for common problems in programming. Following some of them will help you to build a good application. However, if I try to cover them all here, I'd have to write a book, so here are just a few of them:

Constructor Pattern

Use this pattern to create an instance of a specific object type. Here's an example:

Or you may try this:

Module Pattern

The module pattern gives us the ability to create private and public methods. For example, in the code below, the variable _index and the method privateMethod are private. increment and getIndex are public.

Observer Pattern

Wherever you see subscription or dispatching of events, you'll likely see this pattern. There are observers which are interested in something related to a specific object. Once the action occurs, the object notifies the observers. The example below shows how we can add an observer to the Users object:

Function Chaining Pattern

This pattern is a nice way to organize the public interface of your module. It saves time and improves readability:

I strongly recommend checking out this book by Addy Osmani. It's one of the best resources that you could find about design patterns in JavaScript.

Assets-Pack

Now that we're nearing the end of this article, I want to share a few thoughts on CSS and JavaScript code management on the server. It's a very common technique to add merging, minification, and compiling into the logic of the application. Often there is some kind of caching mechanism, but all things are happening during runtime. I.e. you probably have code logic, which handles the request for .js or .css files and serves the proper content. Behind this process is the compilation, minifcation or whatever you are using to pack your assets.

In my latest projects I used a tool called assets-pack. It's really helpful and I'll explain in detail what exactly it does, but the more interesting part is how I used it. This library is meant to be used only in development mode, it's not something that stays in your codebase and it's not something that you should deploy on your production server.

The idea is to use the packer only while you are working on the assets (CSS, JS). It actually watches for changes in specific directories and compiles/packs the code into a single file. By using this approach you don't need to think about the minification or compilation. All you have to do is just send the compiled static file to the user. This increases the performance of your application, because it only serves static files and of course makes things simpler. You don't need to set anything on your server or implement unnecessary logic.

Here is how you can setup and use assets-pack.

Installation

This tool is a Nodejs module, so you should have Node already installed. If you don't, just go to nodejs.org/download and grab the package for your operating system. After that:

Usage

The module works with JSON configuration. When it is used via the command line, you should place your settings in a .json file.

Via the Command Line

Create an assets.json file and execute the following command in the same directory:

If your configuration file uses another name or is in another directory, use:

In Code

Configuration

The configuration should be a valid JSON file/object. It's just an array of objects:

Asset Object

The basic structure of the asset object is like so:

The pack property is not mandatory. If you miss it, then its value is equal to watch. minify by default is false.

Here are a few examples:

Packing CSS

Packing JavaScript

Packing .less Files

The packing of .less files is a little bit different. The pack property is mandatory and it is basically your entry point. You should import all the other .less files there. The exclude property is not available here.

If you find any problems, please check the tests/packing-less.spec.js of the repository in GitHub.

Packing Other File Formats

assets-pack works with any file format. For example, we can combine HTML templates into a single file by doing something like this:

The only one thing that you should know here is that there is no minification.

Conclusion

As front-end web developers, we should try to deliver the best performance possible for our users. The tips above aren't supposed to cover all aspects of asset organization and performance, but they are the ones I have dealt with personally during my daily work. Please feel free to share some of your tips below, in the comments.

Show more