Tuesday, January 29, 2008

How to speed up your website.

Reduce the number of colors in your graphics

Reduce the number of colors in your graphics in order to lower the size of your graphics.

Avoid using flash as much as possible

Avoid using flash as much as possible because, usually, flash loads harder due to their sizes.

Remove the HTML comments from your pages

Yes, comments can slow your website down. Big or small, comments have something to say when it comes to page size.

Use caching

Set the browser?s cache expiration. This can be easily done using PHP in order to send some headers. For example, let's take a js file called scripts.js. In order to use caching we will create a new file called scripts.js.php and add the following code at the very beginning of it which will set the cache to expire in 3 days:




By using this method you will not speed the first (initial) download but it will have some impact on the overall experience when you're browsing multiple pages or for returning visitors since the content will be already cached.

Combine multiple files into one

Your browser has a limited number of open connections with a certain website. You can use a script to combine multiple .js or .css files into one and reduce the HTTP requests.

Read this article if you want to go deeper into this technique and do some advanced stuff:
Web page optimizer

Choosing the Right DOCTYPE

A page that was built using the Strict doctype will load faster than one that was built using the Traditional doctype or much faster than one that was built with no doctype at all. Of course, it's not a good idea to go ahead and change your doctype without knowing some facts.

Do not use images to display text

Why should you use images to display text? Think of all those HTTP requests again. We talked about the limited number of open requests a browser can have with a certain website. A very good solution is to use stylesheets instead of images. Having all your stylesheets into one file solves many many problems. You result with one request for a lot of needs. Here's an example that creates a mouseover effect on a button using nothing more than css:

a:link
{
color: #ffffff;
background: #ff9900;
text-decoration: none;
padding: 0.2em;
border: 4px solid;
border-color: #99f #008 #008 #99f
}

a:hover
{
color: #ffffff;
background: #ffaa11;
text-decoration: none;
padding: 0.2em;
border: 4px solid;
border-color: #008 #99f #99f #008
}



Use CSS to call images used for decoration

Browsers usually download the background images after everything else. By loading your background files using css you have a huge advantage because the text content will be displayed first and, in most cases, this is the content that your visitor is interested in. They will start reading your text much faster and, in the meantime, your page will download the rest of the content. Here's an example of a css based background:





And this CSS:

.background-image
{
background: url(filename.gif);
width: 200px;
height: 100px
}



You may want to enjoy the alt attribute and here's a way to do it:

description



where something.gif can be a 1px x 1px transparent image.

Use contextual selectors

This is inefficient:

This is a sentence


This is another sentence


This is yet another sentence


This is one more sentence





.text
{
color: #03c;
font-size: 2em
}



Instead of assigning a value to each individual paragraph, we can nest them within a
tag and assign a value to this tag:


This is a sentence


This is another sentence


This is yet another sentence


This is one more sentence






.text p
{
color: #03c;
font-size:2em
}



This second CSS example basically says that every paragraph within class="text" should be assigned a colour value of #03c and a font size of 2em. At first glance this doesn't look too important, but if you can apply this properly throughout your document you can easily knock off 20% of the file size. You may have noticed the color values are shorter than normal. #03c is a shortened version of #0033cc - you can assign this abbreviated value to any colour value like this.

Use shorthand CSS properties

You can use the following shorthand properties for the margin CSS command.

Use:

margin: 2px 1px 3px 4px (top, right, bottom, left)



...instead of

margin-top: 2px;
margin-right: 1px;
margin-bottom: 3px;
margin-left: 4px



Use relative url's

An absolute url like is much bigger than and this will have a huge effect on the file size again.

Remove unnecessary META content

Most META tags have no importance at all. For SEO purposes we can talk about the keywords and description tags but, due to abuse, I don't believe they're so important any more. Anyways, if you're gonna use it, my advice is to keep it under 200 characters to reduce the overall size and also keep some sort of balanced keyword density.

Use a trailing slash at the end of directory links

By placing a simple trailing slash at the end of your link you can tell the server that you're pointing to a directory and not a file. Your server will have more time to take care of other important aspects. Here's an example:
Instead of this:

Do this:

Try to have less HTTP Requests

I think this is the most important step of all. The most time consuming task a browser has to do is to satisfy all the HTTP requests in order to display the full page by downloading all the images, stylesheets, javascript files, flash etc. Reducing this requests will have a massive effect when it comes to user experience. You don't have to cut the whole page and leave out important stylesheets or javascript files. Read this whole article and you will learn how to combine multiple files (css, js), use css to display images and lots of other tricks to keep your page as simple as possible, fast and functional.

Use image maps to combine multiple images into a single image

Image maps combine multiple images into a single image. The overall size is about the same, but reducing the number of HTTP requests speeds up the page. Image maps only work if the images are contiguous in the page, such as a navigation bar. Defining the coordinates of image maps can be tedious and error prone.

CSS Sprites are the preferred method for reducing the number of image requests. Combine all the images in your page into a single image and use the CSS background-image and background-position properties to display the desired image segment.

Inline images use the data: URL scheme to embed the image data in the actual page. This can increase the size of your HTML document. Combining inline images into your (cached) stylesheets is a way to reduce HTTP requests and avoid increasing the size of your pages.

Turn on Http Keepalives

If Http Keepalives are not turned on, you can get 30% to 50% improvements just by turning this on. Keepalives allow multiple HTTP requests to go over the same TCP/IP connection. Since there is a performance penalty for setting up new TCP/IP connections, using Keepalives will help most websites.

Use CSS to keep the important stuff at beginning of your source

Even if this technique won't have so much of an effect on your website's speed it will play a huge role in the user experience. You need to find a way to display the text content (or whatever your visitor is there for) at first and let the browser work in the background in order to finish downloading the rest of the content. Let's take for example a simple page with menu at top, categories on the left and text content on the right. We're interested in the text content but we have to wait for the browser to download and display the top navigation and the left categories until it reaches what we're there for. Well...not necessarily. We can float the categories at the left and the text content at the right and in the source, we can place the text content before the left categories as it will have the same result when it comes to source code but, you achieve something very important: the text will show up first.

Use a Content Delivery Network

This might not be a good solution for small websites since it's not so cheap to use a content delivery network (CDN). Not everyone can own a CDN or pay a provider such as Akamai or Limelight in order to deliver the content from the server with the smallest response BUT, if you think it will worth the investment, this is a big step in optimizing your website for speed and we're talking about 10% - 15%.

Add an Expires Header

"The Expires HTTP header is an instruction to the client about the document's validity and persistence. If cached, the document may be fetched from the cache rather than from the source until this time has passed. After that, the cache copy is considered "expired" and invalid, and a new copy must be obtained from the source."

The expires HTTP header tells all browsers how long an object is active (fresh) for and after that amount of time caches should check back with the server for changes, if any. The expires HTTP header are very good for caching static images like the ones used for navigation or buttons where can be set a big amount of time as expiry in order to make the website much more responsive to it's visitors.

This trick is very important for your returning visitors and for those that browse multiple pages of your site because setting an expires header somewhere in the future will tell the browser to cache the content (scripts, css, images) for that amount of time as it won't change during this period. This way, you avoid sending informations to the browser by a http request and increase the number of cached components. Let's take for example firefox which has, by default, a storage quota of 50Mb for cached content. That's a lot of space which can hold a lot of content which, otherwise, needs to be downloaded.

When you're setting an expires header far in the future and decide to make changes to the cached files you might wanna change the name of the file as well. For example a file that is named myfile.js and is cached via expires header for a long period should be renamed somewhat when we change the content in order to tell the browser that we updated it. A good idea would be to keep versions (myfile1.js, myfile2.js) or timestamps (myfile_11352617289.js) in it's name.

Gzip Components

Gzip is a very popular compression utility that is used on most websites, designed as a replacement for compress and adopted by the GNU project. Gzip is very very handy if you ask me since it manages to reduce the size of the response by nearly 60% - 70%, accelerates the browsing experience and also can cut down the bandwith used with more than a half.

Servers choose what to gzip based on file type, but are typically too limited in what they decide to compress. Most web sites gzip their HTML documents. It's also worthwhile to gzip your scripts and stylesheets, but many web sites miss this opportunity. In fact, it's worthwhile to compress any text response including XML and JSON. Image and PDF files should not be gzipped because they are already compressed. Trying to gzip them not only wastes CPU but can potentially increase file sizes.

It's not such a good idea to gzip files that are smaller than 1k since you might end up with the same result or worse. Anything that is bigger than 1k should be faster than not gzipping it at all. Also try to remember that the result might be a faster web page but a bigger load on the server. The balance is in your hands.

Try to remember that Apache 1.3 uses mod_gzip while Apache 2.x uses mod_deflate so you also depend on versions to benefit from this compression method. You can get the same benefits by adding some very simple PHP code to your web pages.





Gzip can be the real deal when you have your page mostly on text/html, it won't have such a big effect on image-based websites and it might fail on some plugins and PDF files since they're already compressed.

Ayways, you can define in apache what files should and shouldn't be compressed.

Multiple Servers:

As we've seen already, most browsers support a limited number of open connections (http requests) with a server and everything that passes this limit should wait for them to finish a certain task. Let's take for example a browser that has a limit of open connections of 4 and a webpage that is composed of 16 images. 16 / 4 equals 4 so we end up with 4 downloads. What if....we put 4 images on server1, another 4 on server2, another 4 on server3 and the rest on server4? We might notice a huge speed improvement by almost 4 times since the browser will open 4 connections at a time with each server in part since they're different.

You might notice that some websites use different servers for storing images and static content. Of course this limit can be changed by tweaking the browser's settings but you can't ask your visitors to do that for a "better browsing experience" on your website.

AJAX:

Ajax won't necessarily speed your website but has a huge effect when it comes to responsiveness and user experience. Keeping the visitor on the same page and displaying content only on demand/on action makes the page load faster and more interactive. A lot of Java and Flash based websites have switched to Ajax for the same result but in less bytes.

Put CSS at the Top

When a new visitor reaches our website is very important to show him that we have a progressive website that loads fast. Putting CSS at the top helpes the browser to render the page in a progressive way and not wait for the whole page to load in order to figure out how the display should be. This is a huge advantage when we use external stylesheets, tableless layouts, stylesheet based backgrounds etc. Since the css is placed in the header of the pages and, along with it, the structure of the page, the browser knows from the very beginning how the page should look and where should be what. It also increases the browsing experience by showing the visitor the progress of the page (think at a file transfer....if the computer fails to show you the load bar you might think that the transfer failed even if it's not because you see no true progress...think of an ajax indicator - load bar - that tells you to wait until it finishes).

Move Scripts to the Bottom

If moving the stylesheet file in the document head will help the browser show a progressive rendering, it's the other way around with the scripts. When the browser reaches scripts it will stop the progressive rendering of the page until that script is loaded. This method might not work in all cases since there are situations over situations where a script could and should be used but there are workarounds. It's a very good idea to try this small trick when you have a lot of javascript for transitions and various effects etc.

Avoid CSS Expressions


CSS expressions allows you to set the properties in a dynamic way and can be used in a big number of situations. For example a background color that changes every hour by using a Javascript expression:

background-color: expression( (new Date()).getHours()%2 ? "#B8D4FF" : "#F08A00" );



This way of setting the properties is problematic because it evaluated by the browser at very simple events such as scrolling, resizing or even when we move the mouse over the content.

One way to reduce the number of times your CSS expression is evaluated is to use one-time expressions, where the first time the expression is evaluated it sets the style property to an explicit value, which replaces the CSS expression. If the style property must be set dynamically throughout the life of the page, using event handlers instead of CSS expressions is an alternative approach. If you must use CSS expressions, remember that they may be evaluated thousands of times and could affect the performance of your page.

Make JavaScript and CSS External

At a simple evaluation, the advantage is huge since an external css file or javascript file can be cached by the browser avoiding the precious http requests on the future. When using inline styles and declarations, we force the browser to download and evaluate them on each request. The result is obvious...

Reduce DNS Lookups


Each time you type in your addressbar a website, the browser contacts the DNS resolver which is supposed to respond with the server's IP address. Nothing takes place until this task is over which, usually, takes between 20 and 120 milliseconds. This operation is called a DNS lookup. The good news is that it can be cached by the operating system's DNS cache and sometimes by the browser.

Going back to the part when we talked about the advantage of using multiple servers you might say that these 2 methods are not so "brother and sister" since it's an advantage in using more servers to allow more http requests but a disadvantage since it creates more DNS Lookups. You should always have a balance in mind when using them. I won't recommend using more than 3 - 4 servers.

Don't use regular expressions where you don't have to

"In computing, a regular expression is a string that is used to describe or match a set of strings, according to certain syntax rules."
Regular expressions are almost a whole language. Very complex and doing real wonders where anything else would fail but they come with a big price: time. Yes they need time to perform the complex operations. There are many situations where you could replace preg_replace and eregi_replace which perform operations based on regular expressions with str_replace which "Replace all occurrences of the search string with the replacement string". My advice is to use them with care and only if you have to.

Minify JavaScript

A good idea would be to remove the comments from your js files, the unnecessary characters from code, white space etc. in order to reduce the size of the files and the time needed to download them. This process is called minification and is an alternative (or vice versa) to obfuscation which also removes comments and whitespace from files but also obfuscates (makes it difficult to be reversed) it. While minification can be a safe process, obfuscating your files can damage them irreversibly. You should always keep backup files before obfuscating.

Avoid Redirects

There are many ways of doing redirects (meta refresh, php's header location, javascript etc.) but all of them take time to be processed since the file needs to be read by the browser in order to understand your message. The best way of redirecting the user to another page is to use the traditional 301 or 302 status codes in a .htaccess file like in the following example:

HTTP/1.1 301 Moved Permanently
Location: http://someurladdress.com/newpage
Content-Type: text/html



or:

Redirect permanent /forum/discussion/17/ http://www.someuri.com/17.html



Another advantage in using this method is that the content won't be cached unless instructed so and we still have a functional back command in the browser that will take us to the previous page.

Remove Duplicate Scripts

This usually happens when a certain website is developed in a team and there's some lack of communication between individuals or when the webmaster/developer is not paying attention to this fact that forces the browser to execute the same piece of code twice or more no matter if it's cached or not and some times even worse when it also needs a new HTTP request to execute it.

Configure ETags

An Etag is a small string that represents the HTTP response header returned by an HTTP/1.1 compliant web server used to uniquely identify the version of a page component (image, stylesheet, script etc.) when compared with what's already cached in the browser. Among other informations the Etag will return the "Last-modified" time and content length of the specific component.

HTTP/1.1 200 OK
Last-Modified: Tue, 12 Dec 2006 03:03:59 GMT
ETag: "10c24bc-4ab-457e1c1f"
Content-Length: 12195



The problem with ETags is that they typically are constructed using attributes that make them unique to a specific server hosting a site. ETags won't match when a browser gets the original component from one server and later tries to validate that component on a different server, a situation that is all too common on Web sites that use a cluster of servers to handle requests. By default, both Apache and IIS embed data in the ETag that dramatically reduces the odds of the validity test succeeding on web sites with multiple servers.

If you're not taking advantage of the flexible validation model that ETags provide, it's better to just remove the ETag altogether. The Last-Modified header validates based on the component's timestamp. And removing the ETag reduces the size of the HTTP headers in both the response and subsequent requests. This Microsoft Support article describes how to remove ETags. In Apache, this is done by simply adding the following line to your Apache configuration file:

FileETag none

Use CSS For Faster Pages

I sense a huge struggle in today's design to avoid using tables which can be a mistake. It's ok to use them for rendering tubular data and it's not ok to use them for design purposes but making a tableless website just because everyone seems to claim that you're not a real designer unless you cut down all the tables might give you headaches due to the bad results.

It's again about the cached content in an external css file placed in the header of your page which is supposed to hold the structure of your page and all it's properties. This is the real advantage because, using tables for design purposes, you force the browser to parse the whole table until it knows how should the page look. Using nested tables is much worse but that's another chapter.

Use External Scripts

Supposing that you have a script to animate your menu that is present on every page. It's very small. You might think that it won't be such a good idea to create a whole new file to make it execute from that file. That's a bad idea. If you have no external javascript file to add it too you still have an advantage: the file will be cached on the next visit or page, and, if you already have js files, you can add it at the end of one but make sure you won't generate conflicts and the code will remain functional.

In the worst case, this method will create a new http request but will save you tons in size and speed since it will be cached and reused directly from the browser.

Remove Anything You Don't Really Need

Yes...I know...it's obvious. So obvious that everyone is leaving behind. A good website is not one that is full of cool javascript effects, shining colors, sliding divs and whatever fancy idea you might have. In my opinion, you should keep only what's functional and needed to enhance the browsing experience. While making a website some while ago for someone, I was asked to put a certain song on the homepage to make it cool. The result was a loaded page, hated by many since the song was always starting unless otherwise instructed by the visitor (another wish of my client) and imagine yourself at night with 5-6 websites in your tabs and one of them starting to sing....auuughh!! Do you really need such things?! Keep it simple and functional....in balance with a nice design if you can and not loaded with all your dreams, full of your talent and creation.

Avoid Nested Tables

Content and presentation should be separate. As said above, tables are good to render tubular data but a bad idea when it comes to building a layout based on them since the browser can't show any progress (like we've talked on the CSS part) until it finishes to read that table...what happens when that table has another table inside which has another...? I'm sure you guessed: NOTHING...until everything is read!

Avoid Full Page Tables for Faster Rendering

If you use tables, try avoiding the whole page being one big table. The browser won't show anything until it's read the whole thing that way. For a faster loading webpage, either try multiple tables (not nested) or having stuff above the main table to make your content in the first table show up faster. That way your visitors will have something to read while the rest of your page loads. It may not really make you page faster, but it will feel like it to your visitors.

Split Up Long Pages

This method will make the content show up faster and won't scare readers away with a huge scroll bar on the right. Use pagination or something to split your pages in readeble lengths. Don't make every article like this one :)

Remove Excess "Whitespace"

Yes white space is still space and needs space. Space means time, time means angry visitors and that's the chain as I see it. You can remove white spaces, tabs, line returns and tabs.

It may not be such a good looking code but this is not our goal. We don't build pages to have nice code. We need good code. By removing line returns you will end up with 9% - 11% reduction in your file size and that's a lot. The browser does not care how good looking is your code as long as it can read it correctly. Here's an example:










something
here
for demo




will become:

something
here
for demo




The disadvantage is human. The code becomes harder to edit and follow.

Keep Your Code Clean

Many wysiwyg editors add useless code to your pages like empty tags ( ) and other elements. Remove those for a faster page that also validates cleaner.

Don't Go Overboard On Images

CSS can do many effects that could easily replace many images used on websites. Don't use so many images unless you have to and, again, don't use images where you could use text to obtain the same result.

Height And Width Tags

If you have the height and width tags already defined, at the time of loading, the browser will know the sizes already and will know where everything will be, how much space to allow, how to render the page etc. It's the same rule for tables as well. Try to specify a width and height tag...it will help.

Faster Images? Reduce Their File Size

There are many tools out there that will optimize your images and make them smaller and web ready, they will also keep the transparency and animations in gif's. You will notice an increase in speed. Look at the bottom of this articles for more resources.

Properly Save Your Images

Photoshop and fireworks have a nice feature that says: "save for web". Why do you think it's there? Use this feature when you save a picture for use in your documents. As above, don't use a rich color palette as it will increase the size of your picture. Experiment the websnap feature that will try to cut down similar colors from the palette.

Compression

To decrease the size of your files you could try compressing them. There are many solutions on the net that will compress javascript, css or php eliminating comments, white space, tabs and breaks...anything that is not needed usually. Try to keep in mind that you might end up with non functional results, the result will most likely be very hard to read and follow and that you should in all cases keep the original documents as backup.

Global Loadbalancing:

If you have already invested in some kind of simple loadbalancing technology and are still having performance problems, start investigating in global loadbalancing which allows you to deploy multiple servers around the world and use intelligent loadbalancing devices to route client traffic to closest web server. If your organization can?t afford to setup multiple websites around the world, investigate global caching services like Akamai

Webserver Log Analysis:

The logs that your webserver keep are an open book to teach where and when errors occur. I think the most important part in the logs are the 404 and 500 errors that represent a missing page. It means that a visitor or a web crawler requested that page and it's missing. This again does not have so much of an effect when it comes to speed but it's a good idea to try and repair the bottlenecks at least for the sake of user experience. Almost any web hosting provider offer a log analizer such as awstats.

GIF vs JPG vs PNG


GIF's usually load quicker while JPG's tend to be better for photos and PNG's (optimized) have lossless compression but be aware of the PNG transparency that is not supported in IE6 and below.