Well here’s a subject I love. Near the king of all factors that is represented by the content, a website must be pure in navigation and structure, pleasant, functional and, most of all, fast.
By following this article, you will realize that a fast website will increase the user experience very much and this brings you returning visitors and, why not, happy visitors. You will also learn how to optimize your website for speed with almost no cost at all.
There are almost 50 tricks to read, understand, analyze and implement into your website. Skills that are designed to make your pages load faster under the same server, with the same investment in most cases.
Without further talking about the massive importance of a fast website I invite you to read carefully every method of optimizing that is presented below this line. I’m sure many of you missed some of them.
Reduce the number of colors in your graphics
- Reduce the number of colors in your graphics 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? Cache expiration. This can be quickly done using PHP to send some headers. For example, let’s take a js file called scripts.js. 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:
<?php header("Content-type: text/javascript; charset: UTF-8"); header("Cache-Control: must-revalidate"); $offset = 60 * 60 * 24 * 3; $ExpStr = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT"; header($ExpStr); ?>
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 specific website. You can use a script to combine various .js or .css files into one and reduce the HTTP requests.
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 created 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 perfect solution is to use style sheets instead of images. Having all your stylesheets into one file solves many many problems. Your 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:
<div class="background-image"></div>
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:
<image src="something.gif" class="background-image" alt="description" />
where something.gif can be a 1px x 1px transparent image.
Use contextual selectors
This is inefficient:
<p class="text">This is a sentence</p> <p class="text">This is another sentence</p> <p class="text">This is yet another sentence</p> <p class="text">This is one more sentence</p>
.text { color: #03c; font-size: 2em }
Instead of assigning a value to each paragraph, we can nest them within a <div> tag and assign a value to this tag:
<div class="text"> <p>This is a sentence</p> <p>This is another sentence</p> <p>This is yet another sentence</p> <p>This is one more sentence</p> </div>
.text p { color: #03c; font-size:2em }
This second CSS example says that every paragraph within class=” text” should be attached a color 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 quickly knock off 20% of the file size. You may have noticed the color values are shorter than average. #03c is a shortened version of #0033cc – you can assign this abbreviated value to any color 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 URLs
- An absolute URL like <a href=”http://www.roscripts.com/snippets”> is much bigger than <a href=”snippets”> 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 anymore. Anyways, if you’re going to use it, my advice is to keep it under 200 characters to reduce the overall size and also save some 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: <a href=”http://www.yourdomain.com/directory”>
Do this: <a href=”http://www.yourdomain.com/directory/”>
Try to have fewer 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 to display the full page by downloading all the images, stylesheets, javascript files, flash, etc. Reducing these 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 photos 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. Model 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 the beginning of your source
Even if this technique doesn’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 to finish downloading the rest of the material. Let’s take for example a simple page with the menu at the 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 groups at the left and the text content at the right and in the source, we can place the text content before the left types as it will have the same result when it comes to source code but, you achieve something essential: 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 the 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 is perfect for caching static images like the ones used for navigation or buttons where can be set a significant amount of time as expiry to make the website much more responsive to its visitors.
This trick is vital 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 information to the browser by an 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 material 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 want to change the name of the file as well. For example, a file that is named myfile.js and is cached via expires header for an extended period should be renamed somewhat when we change the content 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 its 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 bandwidth 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 websites gzip their HTML documents. It’s also worthwhile to gzip your scripts and stylesheets, but many sites miss this opportunity. Squeezing any text response including XML and JSON is worthwhile. 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 more significant 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 straightforward PHP code to your web pages.
<?php if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) { ob_start("ob_gzhandler"); } else { ob_start(); } ?>
Gzip can be the real deal when you have your page mostly on text/HTML, it won’t have such a significant effect on image-based websites, and it might fail on some plugins and PDF files since they’re already compressed.
Anyways, 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 particular 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 four so we end up with 4 downloads. What if….we put 4 pictures on server1, another 4 on server2, another 4 on server3 and the rest on server4? We might notice a huge speed improvement by almost four times since the browser will open four 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 fewer bytes.
Put CSS at the Top
When a new visitor reaches our website is very important to show him that we have a progressive site that loads fast. Putting CSS at the top helps the browser to render the page progressively and not wait for the whole page to load 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 transmission 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 perfect idea to try this small trick when you have a lot of javascript for transitions and various effects etc.
Avoid CSS Expressions
CSS expressions allow you to set the properties dynamically 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 straightforward 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 enormous 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 address bar 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 the operating system’s DNS cache can cache it 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 two 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 don’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 actions 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. to reduce the size of the data 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, confusing your data 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 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 sometimes 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 information, 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 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 just adding the following line to your Apache configuration file:
FileETag none
Use CSS For Faster Pages
I sense a massive struggle in today’s design to avoid using tables which can be a mistake. It’s ok to use them for rendering tabular 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 its 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 Need
Yes…I know…it’s obvious. So evident that everyone is leaving behind. A good website is not one that is full of cool javascript effects, bright 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 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 useful to render tabular 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 is one big table. The browser won’t show anything until it’s read the entire 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 make your page more quickly, 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 readable 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 a beautiful 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:
<TABLE> <TR> <TD>something</TD> </TR> <TR> <TD>here</TD> </TR> <TD>for demo</TD> </TR> </TABLE>
will become:
<TABLE><TR><TD>something</TD></TR><TR><TD>here</TD></TR><TD>for demo</TD></TR></TABLE>
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 (<font> </font>) 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 photos 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 gifs. You will notice an increase in speed. Look at the bottom of these 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 vibrant color palette as it will increase the size of your image. Experiment the web snap 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, whitespace, tabs, and breaks…anything that is not needed usually. Try to keep in mind that you might end up with nonfunctional results, the result will most likely be robust to read and follow and that you should in all cases keep the original documents as a backup.
Global Load balancing:
If you have already invested in some simple load balancing technology and are still having performance problems, start investigating in global load balancing which allows you to deploy multiple servers around the world and use intelligent load balancing devices to route client traffic to the closest web server. If your organization can?t afford to set up multiple websites around the world, investigate global caching services like Akamai
Web server Log Analysis:
The logs that your web server keep are an open book to teach where and when errors occur. I think the most crucial part in the records 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 offers a log analyzer 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.
Some good resources:
- http://www.htmlcenter.com/tutorials/tutorials.cfm/158/php/
- http://developer.yahoo.com/performance/rules.html
- http://www.pcbit.com/gifopt/
- http://html-optimizer.en.softonic.com/
- http://downloads.theregister.co.uk/Windows/Internet/InternetAccelerators/spaceagent2.html
- http://betterexplained.com/articles/how-to-optimize-your-site-with-gzip-compression/
- http://httpd.apache.org/docs/1.3/mod/mod_expires.html
- http://www.crockford.com/javascript/jsmin.html
- http://www.askapache.com/htaccess/speed-up-sites-with-htaccess-caching.html
- http://tools.dynamicdrive.com/imageoptimizer/
- http://www.jpegwizard.com/
- http://www.cssdev.com/csstweak/
Table of Contents