A picture of a coder

Speed Up Your Site – Web Site Optimization

The load time of websites is one of the most important factors affecting its usability; most Internet users will just skip a site altogether if it fails to load within a couple of seconds. Slow-loading websites are one of the main reasons that visitors may leave a site. As a result, it is important to ensure that your website is fast and regularly make improvements as content changes. The content should make up the majority of your pages. But as the majority of your pages, it is what you should focus on optimizing first. Content includes both text and images.

Below you will find the summary of the “Speed Up Your Site” series. Those are simple yet effective ways to make sure that your website is running 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. Tricks that are designed to make your pages load faster under the same server, with the same investment in most cases.

Optimize the HTML

The HTML is what makes your page display in the browser, but you need to make sure that it is optimized as well.

Layout your pages with CSS, not tables

CSS downloads faster than tables because:

  1. Browsers read through tables twice before displaying their contents, once to work out their structure and once to determine their content.
  2. Tables appear on the screen all in one go – no part of the table will appear until the entire table is downloaded and rendered.
  3. Tables encourage the use of spacer images to aid with positioning.
  4. CSS generally requires less code than cumbersome tables.
  5. All code to do with the layout can be placed in an external CSS document, which will be called up just once and then cached (stored) on the user’s computer; table layout, stored in each HTML document, must be loaded up each time a new page downloads.
  6. With CSS you can control the order items download on to the screen – make the content appear before slow-loading images and your site users will definitely appreciate it.

Don’t use images to display text

There’s no need to use images to display text as so much can be accomplished through CSS. Have a look at this code:

a:link.button, a:visited.button, a:active.button  {
color:#fff;
background:#747170;
font-size:1.2em;
font-weight:bold;
text-decoration:none;
padding:0.2em;
border:4px solid;
border-color:#000000
}

a:hover.button {
color:#fff;
background:#382D2C;
font-size:1.2em;
font-weight:bold;
text-decoration:none;
padding:0.2em;
border:4px solid;
border-color:#000000
}

This will give you a really simple button that appears to be pushed down when you mouseover it.

Use contextual selectors

This is inefficient:

<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>

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

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

<div class="paragraph-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>

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

This second CSS example basically says that every paragraph within 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.

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:

margin: 5em 1em 3em (top, right and left, bottom)

…instead of

margin-top: 5em;
margin-right: 1em;
margin-bottom: 3em;
margin-left: 1em

Use: margin: 5% 1% (top and bottom, right and left)

…instead of

margin-top: 5%;
margin-right: 1%;
margin-bottom: 5%;
margin-left: 1%

Use : margin: 0 (top, bottom, right and left)

…instead of

margin-top: 0;
margin-right: 0;
margin-bottom: 0;
margin-left: 0

These rules can be applied to margin, border and padding.

Minimize white space, line returns and comment tags

Whitespace is the spaces between your coding, removing the unneeded tabs and spaces can help a lot! Doing this will take a lot of extra bytes off the total size of your page and will speed up load time quite a bit. (Careful using automatic squishers, I find they often squish too much and makes it rather hard to edit later.)

Every single letter or space in your HTML code takes up one byte. It doesn’t sound like much but it all adds up. We’ve found that by working through your page source and eliminating unnecessary white space and comments, you can shave off up to, or even over (if your HTML is really inefficient) 10% of its file size.

Put CSS and JavaScript into external documents

To place CSS in an external document use:

<link type="text/css" rel="stylesheet" href="filename.css" />

To place JavaScript in an external document use:

<script language="JavaScript" src="filename.js" type="text/javascript"></script>

Any external file is called up just once and then cached (stored) on the user’s computer. Instead of repeating JavaScript or CSS over and over again in HTML files, just write it out once in an external document.

That way the browser already has it in it’s cache and won’t have to read it each time another page loads. This one saves a ton of load time, specially for larger scripts!

Use / at the end of directory links

Don’t do this:

<a href="http://www.URL.com/directoryname">

Do this instead:

<a href="http://www.URL.com/directoryname/">

Why? If there’s no slash at the end of the URL the server doesn’t know if the link is pointing to a file or to a directory. By including the slash the server instantly knows that the URL is pointing to a directory and doesn’t need to spend any time trying to work it out.

Link to Pages and Images with Relative Paths

Absolute paths, including the host name, add additional characters that aren’t required for links to images and pages on the same web server. An example of an absolute call up is: <a href=”http://www.URL.com/filename.htm”>. Much better would be <a href=”filename.htm”>. But what if some files are in different folders to other ones? Use these shorthand properties:

  • <a href=”/”> – Calls up http://www.URL.com
  • <a href=”/filename.html”> – Calls up http://www.URL.com/filename.html
  • <a href=”/directory/filename.html”> – Calls up http://www.URL.com/directory/filename.html
  • <a href=”./”> – Calls up index.html within that directory
  • <a href=”../”> – Calls up index.html one directory above
  • <a href=”../filename.html”> – Calls up filename.html one directory above
  • <a href=”../../”> – Calls up index.html two directories above.

Remove unnecessary META tags and META content

Most META tags are pretty much unnecessary and don’t achieve very much. The most important tags for search engine optimization are the keywords and description tags, although due to mass abuse they’ve lost a lot of importance in recent times. When using these META tags try to keep the content for each under 200 characters – anything more increases the size of your pages. Lengthy META tags are not good for search engines anyway because they dilute your keywords.

Speed Up Your CSS

CSS is another place where your pages can be slowed down. Large CSS files with styles that are never used are a waste of bandwidth.

When developing large sites, stylesheets can get fairly messy and hard to keep track of. If you don’t stay organized, you can end up making them larger than they really need to be and doing more work than you should have to. Here’s just a few ways to can help avoid that.

Reusing Semantic Class Name

While in most cases semantic class names really don’t help achieve much, there are a few in which they can be quite helpful. One of these is when describing element states, such as .selected.

Oftentimes, people only use classes when there are multiple elements on a page that are to share the same styles–this isn’t the only way to use them, however. Say we have a tabbed horizontal navigation on the top of our page:

<ul id="tabs">
<li><a href="#">tab 1</a></li>
<li><a href="#">tab 2</a></li>
<li><a href="#" class="selected">current tab 3</a></li>
<li><a href="#">tab 4</a></li>
</ul>

We’re going to want to give the .selected link some extra styles. But now say we also have a form somewhere on the page and are using JavaScript to add some styles when a radio button has been selected. When the button is selected, our code would look something like this:

<form action="#" method="post" />
<input type="radio" name="button" value="value" />
<input type="radio" class="selected" name="button" value="value2" />
<input type="radio" name="button" value="value3" />
<input type="radio" name="button" value="value4" />
</form>;

Using selectors, we can give each of these different styles:

li .selected {
/* styles go here */
}

form .selected {
/* styles go here */
}

This makes our CSS easy to read and our classes easy to keep track of. When you have tons of elements with different styles, keeping track of all the IDs and classes can become difficult–this shortens that list and lets us use easy-to-remember names.

Name your <body>

When working with multiple pages, most of the time you’ll be re-using many of your styles but will need slight variations. Having the same code repeated several times in your stylesheet with minor variations wastes space, is hard to keep track of, and just isn’t necessary. For an example, let’s take our previous example and say that our navigation has these styles:

ul#tabs li {
float: left;
padding: 5px;
color: #000;
background: #fff;
font: 1em tahoma;
}

Now what if on all our subpages we want the same thing, but with less padding? We could create a new list, copy/paste all these styles, then modify the padding. But that’d be pointless. Instead, we add a class to the body on our subpages (say, subpage) and just add this into our stylesheet:

.subpage ul#tabs li {
padding: 2px;
}

And that’s it.

Keeping IE Happy

One of the biggest time consumers in CSS development is, of course, IE debugging. With IE7 now on the loose, this can get even more complicated. However, using one IE-only stylesheet that can target both IE 6 and 7 as well as each individually, this can be made much simpler.

To do this, first we set up our conditional comment with included stylesheet:

<!--[if IE]>
<link rel="stylesheet" href="ie.css" type="text/css" media="screen" />
< ![endif]-->

Within this stylesheet, we can then add any styling fixes that are needed for all versions of IE (just make sure that your styles will take priority over the ones in your main stylesheet–I usually add “html body” at the beginning of each selector). For fixes that don’t need to be done on IE7, we simply use the * html hack. For IE7-only fixes, add html > body before the selectors.

By doing this, we can target specific version of IE within one stylesheet and still keep it separate from our main stylesheet.

Don’t Use CSS Expressions

Internet Explorer versions 5 through 7 supported using JavaScript to modify the CSS programatically but these expressions are evaluated thousands of times as the page loads, is rendered, even as the scrollbar moves – all of which slows the page down

Don’t Use CSS Filters

Internet Explorer provides a filter AlphaImageLoader to fix a problem with semi-transparent PNGs in versions lower than 7, but this filter blocks rendering and freezes the browser while the image is downloaded.

Speed Up Your JavaScript

Javascript is becoming increasingly popular on websites, from loading dynamic data via AJAX to adding special effects to your page. Unfortunately, these features come at a price: you must often rely on heavy Javascript libraries that can add dozens or even hundreds of kilobytes to your page. Users hate waiting, so here are a few techniques you can use to trim down your sites.

JavaScript and Ajax can make pages slower, especially if you have them load right away. Most scripts are not used until the entire page is loaded, and if they load first that makes the page appear slower.

Compress Your Javascript

First, you can try to make the javascript file smaller itself. There are lots of utilities to “crunch” your files by removing whitespace and comments.

  • Run JSLint (online (http://www.jslint.com/) or downloadable version) to analyze your code and make sure it is well-formatted.
  • Use Rhino to compress your javascript. There are some online packers (http://dean.edwards.name/packer/), but Rhino actually analyzes your source code so it has a low chance of changing it as it compresses, and it is scrip table.

This compresses myfile.js and spits it out into myfile.js.packed. Rhino will remove spaces, comments and shorten variable names where appropriate. The “2>&1″ part means “redirect standard error to the same location as the output”, so you’ll see any error messages inside the packed file itself (cool, eh? Learn more here.).

Optimize Javascript Placement

Place your javascript at the end of your HTML file if possible. Notice how Google analytics and other stat tracking software wants to be right before the closing </body> tag.

This allows the majority of page content (like images, tables, text) to be loaded and rendered first. The user sees content loading, so the page looks responsive. At this point, the heavy javascripts can begin loading near the end.

I used to have all my javascript crammed into the <head> section, but this was unnecessary. Only core files that are absolutely needed in the beginning of the page load should be there. The rest, like cool menu effects, transitions, etc. can be loaded later. You want the page to appear responsive (i.e., something is loading) up front.

Load Javascript On-Demand

An AJAX pattern (http://ajaxpatterns.org/On-Demand_Javascript) is to load javascript dynamically, or when the user runs a feature that requires your script. You can load an arbitrary javascript file from any domain using the following import function (http://www.activewidgets.com/javascript.forum.6114.43/dynamic-load-javascript-from-javascript.html):

function $import(src){
var scriptElem = document.createElement('script');
scriptElem.setAttribute('src',src);
scriptElem.setAttribute('type','text/javascript');
document.getElementsByTagName('head')[0].appendChild(scriptElem);
}

// import with a random query parameter to avoid caching
function $importNoCache(src){
var ms = new Date().getTime().toString();
var seed = "?" + ms;
$import(src + seed);
}

The function $import(‘http://example.com/myfile.js’) will add an element to the head of your document, just like including the file directly. The $importNoCache version adds a timestamp to the request to force your browser to get a new copy.

To test whether a file has fully loaded, you can do something like.

if (myfunction){
// loaded
}
else{ // not loaded yet
$import('http://www.example.com/myfile.js');
}

There is an AJAX version as well (http://ajaxpatterns.org/On-Demand_Javascript#XMLHttpRequest-Based_On-Demand_Javascript) but I prefer this one because it is simpler and works for files in any domain.

Delay Your Javascript

Rather than loading your javascript on-demand (which can cause a noticeable gap), load your script in the background, after a delay. Use something like

var delay = 5;
setTimeout("loadExtraFiles();", delay * 1000);

This will call loadExtraFiles() after 5 seconds, which should load the files you need (using $import). You can even have a function at the end of these imported files that does whatever initialization is needed (or calls an existing function to do the initialization).

The benefit of this is that you still get a fast initial page load, and users don’t have a pause when they want to use advanced features.

In the case of InstaCalc (http://instacalc.com/), there are heavy charting libraries that aren’t used that often. I’m currently testing a method to delay chart loading by a few seconds while the core functionality remains available from the beginning.

You may need to refactor your code to deal with delayed loading of components. Some ideas:

  • Use SetTimeout to poll the loading status periodically (check for the existence of functions/variables defined in the included script).
  • Call a function at the end of your included script to tell the main program it has been loaded.

Cache Your Files

Another approach is to explicitly set the browser’s cache expiration. In order to do this, you’ll need access to PHP or Apache’s .htaccess so you can send back certain cache headers.

Rename myfile.js to myfile.js.php and add the following lines to the top:

<?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);
?>

In this case, the cache will expire in (60 * 60 * 24 * 3) seconds or 3 days. Be careful with using this for your own files, especially if they are under development. I’d suggest caching library files that you won’t change often.

If you accidentally cache something for too long, you can use the $importNoCache trick to add a datestamp like “myfile.js?123456″ to your request (which is ignored). Because the filename is different, the browser will request a new version.

Setting the browser cache doesn’t speed up the initial download, but can help if your site references the same files on multiple pages, or for repeat visitors.

Cookies Affect Speed

Cookies are a powerful tool for web designers and developers, but they can also cause your pages to slow down. These tips can help you speed up your cookies.

  • Keep cookies small – the larger the cookies are, the more data that must be passed .
  • Eliminate unnecessary cookies – the fewer cookies you set the less that have to be downloaded with your page.
  • Set your cookies at the appropriate domain level – so that only the domains and sub-domains that need cookies, and the rest don’t.
  • Serve static content from a cookieless domain – static content like images can’t use cookies anyway, so serving cookies along with them just adds more requests that aren’t used.

Speed up the loading of HTML files with images

Don’t Go Overboard On Images

While images can greatly enhance the look of a site they can really slow it down if there are too many. Try to decide if all your images are really needed (quite a few nice effects can be done with css, so sometimes images are unneeded.)

Height And Width Tags

Here’s a good old HTML trick that will help most WWW browsers display HTML pages with images faster. Simply add the WIDTH and HEIGHT tags to your IMG tags. For example, if your original image (IMG) tags looks like:

<IMG SRC="MyLogo.gif">

and the width and height of MyLogo.gif is 32 by 50, change the above tag to:

<IMG SRC="MyLogo.gif" WIDTH=32 HEIGHT=50>

So why would adding WIDTH and HEIGHT tags improve the speed? Well, if you don’t specify the size of the image, the browser would have to spend time to actually load the image to find out the size of it and only then can calculate how to layout rest of the elements on the page. As you can see, if you have many images on your page, taking time to load each image before calculating the final layout of the page would take longer.

GIF vs JPG vs PNG

Personally on new sites I design I tend to go for optimized pngs. They have lossless compression (jpgs are lossy) and can be used without worry (gifs have the potential to have copyright issues) and load fast when optimized. Jpgs however are usually better for photos and sometimes highly detailed images. The best idea is really to try the image you want in different formats and compare file size to quality.

Here’s a bit of fast info… If you don’t need sharp resolution, choose PNGs or GIFs over JPEGs, as PNGs and GIFs generally load quicker. JPGs are generally best for photos, PNGs or GIFs for anything else.

Speed up your site with Caching and cache-control

Caching with .htaccess and Apache will take your website and your web skills to the next level. This is some technical and advanced methods condensed to simple htaccess code examples for you. But you must take the time to understand caching with cache-control and other headers and HTTP options before you implement on a production server. Read more about the Caching The Web from here (http://www.david-guerrero.com/papers/squid/squid.htm)

To apply Cache-Control headers, you’ll need to use the mod_headers module, which allows you to specify arbitrary HTTP headers for a resource. See http://www.apache.org/docs/mod/mod_headers.html

Here’s an example .htaccess file that demonstrates the use of some headers.

htaccess files allow web publishers to use commands normally only found in configuration files. They affect the content of the directory they’re in and their subdirectories. Talk to your server administrator to find out if they’re enabled.

### activate mod_expires
ExpiresActive On
### Expire .gif's 1 month from when they're accessed
ExpiresByType image/gif A2592000
### Expire everything else 1 day from when it's last modified
### (this uses the Alternative syntax)
ExpiresDefault "modification plus 1 day"
### Apply a Cache-Control header to index.html
<Files index.html>
Header append Cache-Control "public, must-revalidate"
</Files>

Server-Side Scripting

PHP

PHP (http://www.php.net/) is a server-side scripting language that, when built into the server, can be used to embed scripts inside a page’s HTML, much like SSI, but with a far larger number of options. PHP can be used as a CGI script on any Web server (Unix or Windows), or as an Apache module.

By default, objects processed by PHP are not assigned validators, and are therefore uncacheable. However, developers can set HTTP headers by using the Header() function.

For example, this will create a Cache-Control header, as well as an Expires header three days in the future:

<?php
Header("Cache-Control: must-revalidate");

$offset = 60 * 60 * 24 * 3;
$ExpireString = "Expires: " . gmdate("D, d M Y H:i:s", time() + $offset) . " GMT";
Header($ExpireString);
?>

Remember that the Header() function MUST come before any other output.

As you can see, you’ll have to create the HTTP date for an Expires header by hand; PHP doesn’t provide a function to do it for you. Of course, it’s easy to set a Cache-Control: max-age header, which is just as good for most situations.

For more information, see http://www.php.net/manual/en/function.header.php

Speed up your site with Memcached

Memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.” In plain English, this means memcached is an application that you can use to take advantage of spare free memory on any number of machines to cache pretty much anything you want (with a few exceptions) and retrieve it very quickly.

For more information, see http://en.wikipedia.org/wiki/Memcached

I hope you found these tips helpful. Be sure to drop a comment if you have any more ideas.