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.
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:
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.
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.
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.
<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.
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.
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
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.
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.
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.
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.).
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.
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.
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:
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 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.
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.)
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.
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.
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>
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
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.