Improve performance and optimize your Website

Posted on Saturday January 12, 2013 / by Eric Potvin

... optimize front-end performance first, that's where 80% or more of the end-user response time is spent. This is my favorite quote from Professor Steve Souders and he I will agree with him. So is there something we can do to improve the user experience and optimize the front-end to render pages even faster? Obviously, yes and here's some simple tips that will help you accomplish these issues and make your customers/visitors happy.

Minimize HTTP Requests

Minimizing the number of HTTP requests in your website is the first step of optimization. Why? Simply because most of the traffic you get might be new traffic, or this traffic does not know anything about your site. Just do the test and look at your Google Analytics and see for your self. So help your traffic, specially for the first time user or for those who does not save any cache, and minimize your HTTP request.

The idea here is simple: reduce the number of requests means reducing the number of files the website loads.

Most of these request comes from the CSS, images, JavaScript files. For example, having multiple CSS files like this:

<link rel="stylesheet" type="text/css" href="/css/style.css">
<link rel="stylesheet" type="text/css" href="/css/main.css">
<link rel="stylesheet" type="text/css" href="/css/colors.css">

-or-

/* in the /css/main.css */
@import url("/css/style.css");
@import url("/css/colors.css");

Will create three (3) HTTP requests, by combining this into a single stylesheet file will only create one (1) HTTP request. This also applies to JavaScript files and images (CSS Sprites).

Minify/Optimize Code

A great technique to improve your loading time and, at the same time, save band-witch. This removes unnecessary characters, like spaces, new lines or tabs. This is a very common practice for JavaScript and CSS files. For examples, let's get this JavaScript code:

function urlencode(str) {
  str = escape(str);
  str = str.replace(/ /g, '%20');
  str = str.replace(/\+/g, '%2B');
  str = str.replace(/@/, '%40');
  return str;
}

Can be converted to:

function urlencode(str){str=escape(str);str=str.replace(/ /g,'%20');str=str.replace(/\+/g,'%2B');str=str.replace(/@/,'%40');return str;}

This applies also to CSS:

div.block {
  background: #fff;
  -webkit-border-radius: 10px;
  -moz-border-radius: 10px;
  border-radius: 10px;
  border: 20px solid #ddd;
  -webkit-box-shadow: 0px 0px 20px #000;
  -moz-box-shadow: 0px 0px 20px #000;
  box-shadow: 0px 0px 20px #000;
  display: none;
  float: left;
  font-size: 1.2em;
  left: 50%;
  padding: 20px;
  position: fixed;
  top: 50%;
  z-index: 9999;
}

Will become:

div.block{background:#fff;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;border:20px solid #ddd;-webkit-box-shadow: 0px 0px 20px #000;-moz-box-shadow: 0px 0px 20px #000;box-shadow: 0px 0px 20px #000;display:none;float:left;font-size:1.2em;left:50%;padding:20px;position:fixed;top:50%;z-index:9999;}

What about HTML?

You can also remove spaces, new lines or tabs in HTML as well. The only difference with JavaScript and CSS is HTML can be optimize by remove unnecessary tags. You don't need to put tags like em into an h3 tag if you want this h3 to become italic. Use CSS!

<h3><em>Header 3</em></h3>

Will become:

<h3>Header 3</h3>

Replace images with CSS

CSS can help to improve your loading time by replacing images. Webfonts, border radius, shadows, transition, transform and gradient are few examples where CSS replace images.

Custom Webfonts can be great if you have a lot of images that contains stylish text. Webfonts are pretty small to load and minimal impact on your page load versus the images you will need to include in your page.

Border radius, shadows, transition, transform and gradient will maximize your loading time and also, because everything is in CSS, it is very easy to use and dynamically adapt to practically any HTML tags.

One other tool you can use is the Data URI. The data URI scheme is a URI scheme (Uniform Resource Identifier scheme) that provides a way to include data in-line in web pages as if they were external resources. Basically, they are generated images from text. The disadvantage of data URI are not yet supported across all major browsers.

For example:

.smile {
   background:url(
    data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAATUlEQVQYlZ3QQQoAIAhE0X/BTtntvEDLaSOlpJuCIYKHpvB5BqCQ0SKteVLhi4ybAh8EpDtgh9bngYAkB8rV8x8tTRzfxUBvy35F1R43zcB6rPlo4VYAAAAASUVORK5CYII=
   ) no-repeat;
}

This represent a smiley face!

My favorite tool so far is: http://www.patternify.com/

Optimize Images AKA CSS Sprites

I created an article about css sprites

Load your JavaScript and CSS using external sites

By using external JavaScript or CSS files, you improve your loading time since these files are cached by the browser. These files reduces the number of HTTP requests that are needed since they will be loaded from another websites (like Google for example). Because other websites use the same file, it will be already cached by the browser and therefore will load instantly on your site. In addition, you don't have to maintain or update these files when a new version is launched.

https://developers.google.com/speed/libraries/devguide

For example, loading the jQuery file:

http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js

Use Ajax Requests

If you need to update a label or display tiny amount of information on your page, don't refresh the entire web page. For example, you have a form that allow the user to enter his zip code to get the weather information. Then he press the submit button to get the weather for is region. Then, the request is sent to the server and retrieve the information and display the information. With Ajax, you will only send what you request and get the answers you need without loading the entire page. In this case, you will get back few bytes of data to display.

Optimization with Apache mod_expires

When the user will come to your site for the first time, he will execute many HTTP requests to get the contents. Now, if the user refresh the page or go to another page, you can force him to look at the browser cache first to make sure he is not requesting again the same file from your server. This applies to any components in your page like JavaScript, CSS, images etc...

There's two (2) aspects you need to take in consideration when you set an expiration to any components.

Here's an example on Expires headers in your .htaccess:

  ExpiresActive On
  ExpiresDefault "access plus 5 days"

  ExpiresByType text/html "access plus 2 days"

  ExpiresByType text/css "access plus 1 month"

Compress output data

Compressing content works the same way as compression files (zip or tar.gz). If you want to send to your friend few Megs of data, you compress it and your friends uncompress it and then reads the content. This works the same way for web pages.

mod_deflate

Make sure the header contains:

Accept-encoding: gzip, deflate

To enable output compression using deflate in Apache is very simple, simply add the AddOutputFilterByType command to your .htaccess or Apache configuration file:

# compress text, html, JavaScript, css, xml:
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE application/JavaScript
AddOutputFilterByType DEFLATE application/x-javascript

mod_deflate might not be installed by default

mod_gzip

Make sure the header contains:

Accept-encoding: gzip, deflate

To enable output compression using gzip in Apache is very simple, simply add the mod_gzip commands to your .htaccess or Apache configuration file:

<IfModule mod_gzip.c>
  mod_gzip_on Yes
  mod_gzip_dechunk Yes
  mod_gzip_item_include file \.(html?|txt|css|js)$
  mod_gzip_item_include handler ^cgi-script$ mod_gzip_item_include mime ^text/.*
  mod_gzip_item_include mime ^application/x-javascript.*
  mod_gzip_item_exclude mime ^image/.*
  mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.*
</IfModule>

mod_gzip might not be installed by default