Archive for the ‘Development’ Category

Why WolframAlpha Should Hire An SEO

Sunday, May 17th, 2009

Although my first look at WolframAlpha was rather disappointing I didn’t really intend to show everything that’s not working as I had expected. However I stumbled upon problem after problem.

Now I didn’t intend to write this article at all but just searching for what Google has already indexed of WolframAlpha and following some links made it clear that they obviously didn’t think about SEO at all prior to launching their site.

The problem is: they are doing many things that  might actually harm their Google rankings that are just beginning to show up. We don’t yet know who will be using WolframAlpha in two months, if it will grow to become something that most of the people will use  just like Google or if it is going to fail like WikiaSearch.

Remember: they received over 1000 links to their site within two days and this is likely to grow so it makes sense to optimize the site now to prevent damage.

So from a logical point of view if I had been responsible for the WolframAlpha website I would not have done any of the following that WolframAlpha has implemented:

  • You Should Prevent No-Result Pages From Being Indexed
    “no result” pages return an 200 HTTP status code, not a 404 - Google will likely index these pages. The page doesn’t contain any META robots tag containing “noindex,follow” either.
    Because the differences between different “no result” pages depending on the query are only marginal this might be seen as duplicate content which you should never have on your own site.
  • Don’t Use Redirects For Loadbalacing
    Using the search field on the homepage now redirects via a 302 redirect to a hostname like “www18.wolframalpha.com” leading to even more duplicate content if Google indexes the same page with two different hostnames, e.g. www18 and www76. Normally you would be using a loadbalancer and not use HTTP redirects to distribute the load. They should at least be using the canonical tag to tell Google the original URL, but they aren’t, regretfully.
  • Use A Robots.txt File
    WolframAlpha is currently not using a robots.txt file so they are not telling search engines what should not be indexed.
  • Optimize The Clickthrough Rate In The SERPS
    The result pages do not contain a META description field which I would recommend for a higher click-through rate in the organic search results.
  • Use Text To Display Text, Not Images
    The title tag could also be optimized but I still don’t understand why even simple text is rendered as an image.

What do you think?

tweetthis-15

Website Performance Checklist (PDF)

Thursday, May 14th, 2009

In this blog I have previously posted an article series on how to achieve maximum website performance. Now if you wish to follow the steps described in the articles I thought it’s quite helpful to have a checklist ready that you can print out and tick each box for every single optimization step that you have checked and optimized.

I have refrained from using any colors so it’s purely black and white for your day-to-day use.

So I created this checklist and offer it here as a free PDF download. Just click on the following button to access the website performance checklist. I always appreciate your comments, feedback and suggestions.

downloadnow-free

How To Achieve Maximum Website Performance (Part 5)

Tuesday, May 12th, 2009

Welcome to the fifth part of this article series on how to maximize the performance of your website. The focus of this article is mostly on compressing content on the way from the server to the user’s browser.


6. Compress That Code

All modern browsers support the compression of content transferred via HTTP and indicate this by sending the appropriate Accept-Encoding header just like this:

Accept-Encoding: gzip,deflate

This header tells the server that the browser supports compression of content using either the GZIP algorithm or the deflate algorithm.

To optimize your site and speed up the load time you should add compression to the output your server is sending. If you are using Apache (which I have always assumed throughout this article series) it works as described as follows.

Just like you installed the ExpiresModule as described in part 4 you can install the DeflateModule (”mod_deflate”) in your Apache web server by adding this line to your httpd.conf file:

LoadModule deflate_module       modules/mod_deflate.so

Most of the time it does not make sense to compress images or packed files because they have already been compressed so I suggest you focus on the HTML code. You can achieve this by adding this block to either your httpd.conf file or to any VirtualHost you wish to use the compression for.

<IfModule deflate_module>
AddOutputFilterByType DEFLATE text/html
</IfModule>

Just by adding this configuration to the VirtualHost for this domain (saschakimmel.com) at the time of writing the data transferred for this blog’s homepage was reduced from almost 170 KB to only 27 KB - that’s a reduction of 84%!

I highly recommend using this Apache module as it reduces the traffic enormously.

If you just wish to use output compression in your PHP scripts you can simply use this code:

<?php
ob_start("ob_gzhandler");
?>
<html>
<body>
<p>This should be a compressed page.</p>
</html>
<body>

This will tell the PHP interpreter to use output buffering, i.e. to buffer all of the output of the script until it has finished when it will call the ob_gzhandler from PHP. This handler detects if the browser supports compression at all and will only send the code as compressed data if it does.

7. Using YSlow

If you have read each of the articles in this series you pretty much know every possible performance optimization for a website so now let’s have a look at the analysis of the YSlow addon for Firefox. If you have not already installed this addon you should install it now.

After installing it and restarting your Firefox browser type the URL of the page you wish to optimize into the address bar and hit the enter key. If the page has finished loading you need to open the YSlow tool by clicking on the icon in the browser’s status bar.

yslow

If you click on the button labeled “Run Test” it takes some seconds during which YSlow reloads and analyzes the page. This will show you a list of recommendations like the one below.

yslowresult

If you have read all parts of this series you should by now already have optimized most of the things you can optimize on your website. Please note that YSlow only shows you what you can optimize, not what you already have optimized. It won’t show me that the main page is already delivered with compression it only shows me which files are not yet compressed on this blog so keep this in mind when reading the recommendations.

8. Outsourcing Your Data To A CDN

If you get lots of traffic (and I am talking about really lots of traffic here) to static files like images, videos and downloads you should think about hosting your files on a content delivery network.

You just upload the data to their network and modify the links on your website pointing to these files. You have to pay a fee depending on the amount of data served to your users through these networks. If you already know that your server is not likely to be able to handle all of that traffic you might have a closer look at these services.

The most prominent ones are Amazon Simple Storage Service (S3) and MOSSO.

9. Adding Cache Headers For The WordPress Sociable Plugin

As I just had a look at the YSlow recommendations for my blog I found out that I could add expiration headers for these graphics so I just added this info here because I think it may be quite helpful for you.

Just add this code to your VirtualHost which belongs to your WordPress blog:

<LocationMatch /wp-content/plugins/sociable/images/*>
        ExpiresActive On
        ExpiresDefault "access plus 7 days"
</LocationMatch>

Please note that you need to have the ExpiresModule installed on your server for this to work as described in part 4 of this series.

This concludes this article series. Download your free Website Performance Checklist now.

tweetthis-15

How To Achieve Maximum Website Performance (Part 4)

Monday, May 11th, 2009

Welcome to the fourth part of the article series on how to maximize the performance of your website. This time I will show you how you can minimize the number of HTTP requests to your server by setting appropriate cache headers so that the browser does not request the file time and again while a visitor is browsing your site.

5. Caching And Expiration

Most of the people think that if a browser has downloaded a file like an image or CSS file from the server it has stored it in the cache directory on the local harddisk and will retrieve it from there without sending a new request to the server every time it is embedded in an HTML page.

However this is simply not true. Modern browsers just like Firefox or Internet Explorer 7 will most of the time send an “If-Modified-Since” request to the server to find out if the file has been updated on the server. This is good because your browser can use the file from the cache if it has not changed on the server without downloading the file again.

Well, this still is an HTTP request that is sent to your server. Just think about how often you change images, CSS and JavaScript files on your server. Every 2 minutes?

Most of the time your answer to that question will simply be “No.” although this makes sense for some specific files like images from a webcam that may be updated every few seconds.

Cache Headers

This is the HTTP response header sent to your browser when you access this blog:

Live HTTP Headers Addon For Firefox showing headers

Live HTTP Headers Addon For Firefox showing headers (German version)

Let’s examine the different headers in detail:

Expires: Wed, 11 Jan 1984 05:00:00 GMT

This tells your browser that the file has already expired so that the browser should retrieve from the server again next time it is requested.

Cache-Control: no-cache, must-revalidate, max-age=0
Pragma: no-cache

These headers tell the browser that it must not cache the file and always has to revalidate if the file on the server has been updated.

Last-Modified: Sun, 10 May 2009 18:06:04 GMT

When looking at the headers of static files like images you will often see a header like this which is the file modification time.

Time To Optimize

So now let’s optimize the header settings for some of our files. This optimization assumes that you are using the Apache web server. If you do not have root level access to your web server you cannot use this optimization as described here, regretfully. There are other ways which I am planning to write about in a later post.

First of all you need access to your webserver configuration. You need to add the Expires module (”mod_expires”) to your Apache configuration file httpd.conf like this where all the other lines beginning with LoadModule are located at the beginning of the file:

LoadModule expires_module       modules/mod_expires.so

This will load the Expires module into your Apache web server. Now you need to add the following lines to your VirtualHost configuration - the VirtualHost given is only an example - just add the <IfModule>…</OfModule> block  to your existing VirtualHost block for the domain you wish to speed up.

<VirtualHost 127.0.0.1:80>
ServerName      example.com
DocumentRoot    /srv/www/example.com/htdocs
CustomLog       /logs/example.com.access_log combined
<IfModule expires_module>
	<Location /flvplayer.swf>
	      ExpiresActive On
	      ExpiresDefault "access plus 1 day"
	</Location>
	<Location /img>
       	ExpiresActive On
	      ExpiresDefault "access plus 2 hours"
	</Location>
</IfModule>
</VirtualHost>

This example code assumes that you want all of the files in the /img directory to be cached on the client side for two hours and the file /flvplayer.swf to be cached for one day. You can add as many <Location> blocks as you wish. There are several options available you can look up on the Apache website.

By using this method Apache will add the appropriate HTTP headers automatically.

Setting Manual Headers In Your PHP Files

You can also set expiration and caching headers automatically in your PHP files. By default as PHP is a language where the code is interpreted at runtime PHP sends an Expires header with a date long gone. Here is some example code:

$cacheTime = 60*60; // 1 hour

header("Expires: " . gmdate("D, d M Y H:i:s", gmmktime() + $cacheTime)." GMT");
header("Pragma: public"); // HTTP/1.0

header("Cache-Control: public, max-age=".(int)$cacheTime.""); // HTTP/1.1

WARNING!

Never set the last two headers if the page you are using it on contains user-specific data. This means: if you offer a login on your homepage don’t add the last two lines as this may result in proxies between your server and the visitor’s PC storing this data so that another person who is using the same proxy might see confidential data belonging to the other user - “public” says it all in the code above. In all other cases you can normally safely  use the code as shown above. Just modify the cache time to suit your needs.

How To Find The Perfect Cache Time Value

You should resist the temptation to set the expiration for all of your files to one day or anything more than a few hours. Just imagine you have an image on your website which shows a product with the price next to it. If you change the price when the user returns to your website several hours later (which may depend on your business) he will not be able to see the updated price because the original file has not yet expired in his browser’s cache.

I suggest using several different values depending on how often specific content changes. Your company logo for example is unlikely to change every day (unless you are Google, of course) so you may set a high value here. Just remember that you can (OK, should be able to) change the value on your server at any time so if you are planning to update some images you may as well lower the value a few days or hours before the change is scheduled to happen.

There is no rule of thumb so you just have to think about the different types of files and how often you update these files.

This concludes this article. I appreciate your comments below - feel free to retweet!

Read the next part.

tweetthis-15

How To Achieve Maximum Website Performance (Part 3)

Sunday, May 10th, 2009

Welcome to part 3 of this article series on how to maximize the performance of you website. This time I am going to show you how to minimize the number of HTTP requests on your page. Most people don’t even realize how many HTTP requests are required until every single element on the page has been loaded. I was shocked when I saw that the Sociable plugin for Wordpress has not been optimized for the number of requests but more on that later.

4. Less Requests = Better

If you have not done yet you need to empty your browser cache once again. Open the page you wish to optimize and open Firebug by clicking on the Firebug icon in your browser’s status bar.

Firebug

Firebug

If you have not used Firebug before on that domain you need to activate it (check all boxes) and reload the page. After the page has finished loading open the network tab in Firebug at the top.

This will show you all of the HTTP requests that were required on your page.

Using CSS Sprites To Reduce Image Requests

Now have a look at all of the image requests on your page. If you move your mouse pointer over the “GET …” text on the left hand side of the list Firebug will show you a thumbnail version of the image so that you can find out quickly which image has been loaded.

On my blog (this page) there is a large number of images loaded which can (and should) be optimized.

Some of the HTTP Image requests on my blog

Some of the HTTP Image requests on my blog

There is a good technique to merge several images into one file yet still be able to display separate images even in separate image tags in HTML. These are called CSS Sprites because Cascading Style Sheets are used to implement this. In fact a new image is created that contains all of the images and CSS is used later with background positions to show separate areas of the image where the source images are located in the merged image.

This is not as hard as it sounds because although you could create the merged image and CSS manually I prefer to use the Online CSS Sprite Generator.

The only thing you need to do is to package all of the images into a single ZIP file and upload it on the Sprite generator website. I recommend that you use the same output format as the original images - I will be using the PNG format. You may want to change some of the default options however I am using the default options most of the time.

After clicking on the “Create Sprite Image & CSS” button after a few seconds you will be shown some CSS code and a link to download your merged image.

In my case I received the following CSS code:

.sprite-1_de_btn { background-position: 0 -30px; } 
.sprite-delicious-large_blue { background-position: 0 -83px; } 
.sprite-digg-large_blue { background-position: 0 -165px; } 
.sprite-findmeonfacebook2 { background-position: 0 -247px; } 
.sprite-linkedin2 { background-position: 0 -310px; } 
.sprite-myspace1 { background-position: 0 -370px; } 
.sprite-stumbleupon_48x48 { background-position: 0 -460px; }

This is the code I have added (slightly modified from the original code on the website):

.sidebarsprite {background: url(/img/csg-4a07143404186.png) no-repeat top left; }

This is the merged image:

Merged Buttons as CSS Sprites

As I am not using a list for the images on the right hand side of this page (the sidebar) although this may make sense this is how I implemented it. You need to have a 1×1 pixel transparent GIF first. This will be used as your main image file in the image tag and it has to be transparent for the background image to be visible.

<img src="/img/spacer.gif" width="100" height="30" alt="" border="0" class="sidebarsprite sprite-linkedin2" />

When using an image tag (and not an <li> tag) you have to set both width and height of the image as shown in the image tag above otherwise your image will not be shown.

It does of course not make sense to merge all of the images on your page just to save HTTP requests but you should do this whenever there are images on your page that are used on many other pages on your site as well (just like the sidebar images I am using).

By using the CSS sprite technique just described I have saved 6 HTTP requests to the server. There is even more to optimize - try it for yourself on your own website.

External Scripts Under Scrutiny

Now it’s time to have a look at all the external scripts and maybe images used on your site. Use the method described above in Firebug to find more culprits. And look very closely at your own website - do you really need these 12 external JavaScripts to show your Twitter follower count, your social network friends and contacts and so on?

By using Firebug you can find out how much further requests are caused by some of the external scripts - just scroll down the list in the network tab.

Remove all of the external files that are not essential and that you can live without.

Merge CSS And JavaScript Files Automatically

If you have several CSS and/or JavaScript files on your page hosted on your own server you should merge them into a single file - for your visitors. I strongly suggest to keep modular code separated on the development site but you may wish to just copy all of your own JavaScript and CSS files each into a single .js and a single .css file while still keeping the original files for editing.

Also see the section Optimizing CSS and JS Code in part two of this article series.

Several techniques are shown on this page but I am planning to show you the one I am using in one of the next articles on my blog.

Outsourcing With Google

If you are using one of the popular JavaScript frameworks like prototype.js, jQuery, MooTools, DoJo, script.aculo.us etc. I suggest using Google to deliver these files straight from their servers. Google’s worldwide network of servers has a very high performance and speed so I suggest you check out the documentation on the AJAX Libraries API and start using it to deliver these files through Google’s servers.

This concludes the third part of this article series. Continue with the next part.

tweetthis-15

How To Achieve Maximum Website Performance (Part 2)

Sunday, May 10th, 2009

This is the second article in the article series on how to maximize your website performance. I assume that you have also read the previous article which defines the basics of performance optimization.

After optimizing the time to the first byte received the next step is to decrease the load time of your website.

3. Decreasing Load Time

The less bytes are to be transferred the better. But you may also want to check your webhost first because if the connection to your server is very slow that might be the root of the problem - not necessarily the number of bytes to be transferred.

Checking Your Server Performance

To check this you should upload a large file to your server - maybe 10 megabytes at the very least - the larger the better. You should also ensure that your own internet connection does not suffer from any problems while you are testing. All downloads and other programs (like email clients) should be shutdown prior to testing.

Please note that this test only shows the maximum speed of both your server and your own internet connection combined. If your server is connected to the network with 100 Mbps but your internet connection is just 1 Mbps you will only be able to measure 1 Mbps as the maximum speed so depending on your connections it may not make sense to measure the speed.

Now you need to have a stopwatch ready as you need to measure the time from starting the download to the download being finished. Let’s say the file you have uploaded has a size of 2 MB. You now have to divide the file size by the number of seconds it took to download. If it took 10 seconds to download the file the connection speed is something like 2MB/10 seconds = 0.2 Mbps = 200k/s.

You may also use DownTester (freeware) to measure the download speed automatically.

To measure the performance of your internet connection I recommend using SpeedTest.

If you have found out that the server speed is indeed very low compared with what you would expect check back with your webhost.

Image Optimization

Now it’s time to review the images on your page. Select “Images” > “View Image Information” in your Web Developer Toolbar after you have opened your website again in your Firefox browser.

webdeveloper

This will open a new tab which will list all of the images on your website including information on image dimensions, URL and file size. Have a careful look at the number of total image requests - the higher the more you can optimize.

webdeveloper-image-count

While scrolling down always have a look at the file size for each image. There is not a rule of thumb regarding the file size of an image because it depends on the file type of the image and the dimensions.

Image Types - What’s Right And What’s Wrong

I am still amazed when I see how many web developers still do not know which image file formats to use for different kinds of images. There are only three main types of images used on the web (yes, I won’t talk about SVG and other formats here) and supported by all major browsers:

  • GIF
    The GIF format should never ever be used to compress photos because it has been developed for images with a maximum of 256 colors and works best with images that contains a small number of colors and especially large chunks of pixels with the same color.
    This is the optimal format for screenshots of an application and for graphics with a small number of different colors.
    When compressing GIF images you can choose the maximum number of colors. Sometimes just 16 colors or even just two may be enough however in my opinion you should not invest hours to optimize images just to gain a total 10 KB out of it.
    Supports one color to be used as a transparent color. Supports animations as well.
  • JPEG
    The JPEG format (the “P” actually stands for “photographic”) has been developed for true-color images, mostly for photos. It should never be used for screenshots beause it uses far more storage capacity (and therefore load time) than required.
    No support for a transparent color, no support for animations.
  • PNG
    Nowadays PNG files - although originally developed to be used online - are seldom used for normal images on a website. From my experience it does not make sense to use PNG graphics most of the time except you want to use the so-called alpha transparency feature which in contrast to the GIF transparency offers a full 256 bits channel for transparency. This means that you cannot only pick one single color that is transparent but several grey scale values which are semi-transparent. This allows for seamless integration onto any background.
    Most of the time I am only using PNG images if I need alpha transparency.
    There are currently two formats implementing animations for PNG.

Sample Images - Learning By Seeing

Just have a look at the following images to see the differences in image types and compression. You should see very clearly when not to use JPEGs and prefer GIF images instead.

Photo (bad, saved as GIF, 32K)

Photo (bad, saved as GIF, 32K)

Photo (good, saved as JPEG, 21K)

Photo (good, saved as JPEG, 21K)


Screenshot (good, saved as GIF, 5K)

Screenshot (good, saved as GIF, 5K)

Screenshot (bad, saved as JPEG, 15K)

Screenshot (bad, saved as JPEG, 15K)


Screenshot (good, saved as GIF, 5K)

Screenshot (good, saved as GIF, 5K)

Screenshot (bad, saved as JPEG, 8K)

Screenshot (bad, saved as JPEG (90%), 8K)


Screenshot (good, saved as GIF (8 colors), 2K)

Screenshot (good, saved as GIF (8 colors), 2K)

Screenshot (bad, saved as JPEG (20%), 3K)

Screenshot (bad, saved as JPEG (20%), 3K, still larger than the GIF)


Screenshot (good, saves as PNG (truecolor), 4K)

Screenshot (good, saves as PNG (truecolor), 4K)



You should have seen that GIF offers good quality and still requires less bytes for certain images.

After you have optimized your images (Corel PhotoImpact offers a very cool image optimization assistant for JPEG, GIF and PNG) now it’s time to look at your CSS and JS code on the page.

Optimizing CSS and JS code

Are you using Cascading Style Sheets (CSS) and JavaScript on your page? For this optimization it does not matter whether the code is embedded on your website or has been outsourced to an external file. Just look at your CSS and JavaScript code and remove unnecessary comments first.

Now it’s time to compress your CSS and JavaScript files. There are free online services available to compress CSS and JS code. I recommend using CSSDrive to compress your CSS code and JavaScriptCompressor.com to compress your JavaScript code.

You should save the compressed code to another file than your original file otherwise you won’t be able to edit the code later on unless you are a bot of course.
Just remember that you have to repeat this process every time you modify your CSS or JS code. In a later article I will show how you can automate this process completely with PHP.

Cleaning Up The HTML Code

Now have a closer look at your HTML code. Are there large chunks of code in comments? Remove the comments that are no longer useful.

Embedded Code From External Domains

Is there any popular website that doesn’t offer embeddable content? Yes, embeddable content can be quite cool but it may also slow down the loading time of your page especially if the code snippet you have inserted into your page uses JavaScript because your browser will stop rendering the page right where the JavaScript code has been embedded until it has been executed successfully. If an external source is unavailable or very slow your page will get stuck while loading.

I even had to remove some ad server code some months ago from one of my pages because the ad server was so slow that even after one minute my page was still showing just half of the page rendered. This is not an impressive or professional view. It makes you look like an amateur.

To find out which sources are slow you only have to look at the status bar of your browser to see what is currently happening. “Waiting for ….” is an indication.

Sometimes I also experience slower load times on my page because of the Google Friend Connect Widget embedded on the sidebar to the right. You should check the code one-by-one and decide if you really need this specific widget, snippet or feature.

There are many sites that allow you to embed buttons on your own website to link to your Twitter, Facebook, LinkedIn, MySpace etc. profile and just give you a JavaScript snippet to put onto your site. You should think about using static images to upload onto your server and link to the pages manually.

This concludes the second part of the article series. The next part will focus on how to minimize the number of requests on your page. Some of the optimizations discussed in this article will be revisited to further improve the performance of your website. Click to read the next part now.

tweetthis-15

How To Achieve Maximum Website Performance (Part 1)

Saturday, May 9th, 2009

The idea for this article came to my mind when I was wondering why twitter.com is so slow sometimes. When looking at the source code of my profile homepage on Twitter I was really shocked because I still cannot understand why such a reputable company with so many users does not use all of the methods and processes available to increase the performance of their website.

But first things first. Before you’re going to analyze your website to find out what you can optimize to increase the performance of your website you need to install the following addons and Firefox of course.

I have also compiled a comprehensive list of Firefox addons for developers but you only need the addons listed above to follow the steps described in this article series.

1. Finding The (Maybe Not So Usual) Suspects

It is important that you empty your browser cache first.

Now just open the website in your Firefox you wish to speed up.

At the bottom of the browser in your status bar you will see information collected by the lori addon.

Screenshot of "Life Of Request" info

Screenshot of "Life Of Request" info

Time To First Byte

The first value shows you how long it took for the first byte to arrive. On this blog’s homepage it took just about 0.157 seconds. If you have dynamic data on your page and maybe even database queries on your site the value may actually be much higher.

This value is important to optimize your code on the server side. If you see something like more than 0.5 seconds or even a value greater than one second you know that you have to optimize your server-side code (more on that later).

Total Load Time

The second value shows how long it took until all of the elements on the page had been loaded - this includes embedded images and everything else - even external scripts and embedded video players. If this value is higher than about two to three seconds you know that you need to optimize the code on the client side.

Total Number Of Bytes

The third value shows the total number of bytes transferred which also includes images, scripts etc. Depending on your site and your target audience this value may be quite high but in most of the cases it should not exceed 200K (if your site is a blog it may be up to 500K in my opinion).

Number Of HTTP Requests

The fourth value shows you how many separate HTTP requests to a server were required. Your goal should be to minimize this number. At the time of writing there were 37 HTTP requests required on this page (and 5 requests on reload which is shown in the screenshot) which is quite a large value. Every HTTP request (especially if the request goes to different servers) results in a delay of your page being displayed.

There is no rule of thumb regarding this value - it depends on the nature and contents of your site but it should always be as low as possible.

2. Optimizing The Time To First Byte

If the time to first byte value is quite high you need to optimize your server-side code. As there is no general rule for all the different backends, applications and content management systems I can only give general recommendations here yet I will also show you how to decrease this value if you are using WordPress on your own server (not the hosted blogs at Wordpress.com).

Static Page

If the page you are trying to optimize is a completely static page (like a real HTML file) and the value is relatively high I would interpret this as your server being too slow or being under a high server load. You should check this with your webhost as a static page should be delivered by webservers in a very short amount of time.

Dynamic Page

If your page is a dynamic page developed in PHP, Perl, Ruby-On-Rails, JSP or any other web development language or system there may be much to optimize depending on the nature of your page.

Do you have many content on your website that is retrieved dynamically?

You may for example have the latest comments by users in your forum, on your blog or the latest images or postings on your page. If you are not caching these contents (or the page) on your server yet just ask yourself the following question:

What is the access-to-update ratio, i.e. how often is the specific page accessed by someone and how often do you change or update the contents?

If you have many people accessing your page yet you only update it hourly or even daily or weekly you should implement caching on your server. You may for example just update the contents on the page every X minutes from the database or you may use what I call intelligent caching where you only update cache files if the content has changed. This is actually what I am using on most of my own sites: when a new user joins the cache file containing the HTML code for the “new users” snippet is deleted. Whenever someone then accesses the page the PHP script on the server checks if the cache file is available and loads it in that case. If it is not available it is created just-in-time, cached and will be used as long as it exists.

Implementing a caching algorithm is however very dependent on the language your code is written in and depends on your framework or application so I cannot go into detail on that matter, regretfully, as there is not a one-fits-all solution.

WordPress

I am using WordPress on this blog as well (as you might already have guessed) so I can give you some advice on how to optimize your pages.

I have seen many plugins for WordPress that have not been developed with getting lots of traffic in mind. Some retrieve the data from an external source (like your Twitter feed) on every single page request which not only increases load time it also means that your blog may be unavailable if Twitter (or any other source a plugin may be using) is down. This also leads to a huge amount of traffic to the external sources. You should check if the plugins you are using are requesting dynamic content from external sources on every single reload of a page.

Remember: whenever you access such a blog page data is retrieved from the external source before the page is displayed to the user (because it is server based). If these pages would be cached on the server for a limited amount of time this problem would be solved (to the most part).

There is actually a great caching plugin available for WordPress. It is called WP Super Cache and can be downloaded or installed directly from within WordPress. It decreases the load time of your WordPress pages dramatically because with the default installation WordPress pulls all article data on every request from the database so the database is really your bottleneck if you are getting lots of traffic to your site. WP Super Cache not only caches the pages it is also very intelligent in that it regenerates cache files automatically if you update your posts.

More info on WP Super Cache is available on this page as well.

This concludes the first part of the series. Continue to read the second part of this series.

tweetthis-15

How To Create A Dynamic “Tweet This” Button With JavaScript

Wednesday, May 6th, 2009

Yesterday I posted some code on how to create dynamic Tweet This buttons with PHP, today I’m going to share a short code snippet you can really drag and drop into your editor to create a “Tweet This” button on your website.

You just need to copy and paste this code and adjust the src attribute of the image to point to your button:

<script type="text/javascript">
var twtTitle  = document.title;
var twtUrl    = location.href;
var maxLength = 140 - (twtUrl.length + 1);
if (twtTitle.length > maxLength) {
twtTitle = twtTitle.substr(0, (maxLength - 3))+'...';
}
var twtLink = 'http://twitter.com/home?status='+encodeURIComponent(twtTitle + ' ' + twtUrl);
document.write('<a href="'+twtLink+'" target="_blank"'+'><img src="tweetthis.gif"  border="0" alt="Tweet This!" /'+'><'+'/a>');
</script>

tweetthis-15

How To Create A Dynamic “Tweet This Button” With PHP

Tuesday, May 5th, 2009

Yesterday I have just released some of my graphics for Twitter that I have designed myself.

This time I will show you how can easily create links to your own pages on your website or different articles whenever you have both a page URL and a page title available.
This code automatically removes characters from the end of the title so that in addition to the URL itself and a space character between the maximum length of 140 characters will not be exceeded. If the title is too long it will be truncated and three dots will be appended to show that it has been shortened.

When clicking on the link the user is taken to the Twitter homepage with the message already preset so that he can tweet it immediately with just a single click.

function getTweetUrl($url, $title)
{
$maxTitleLength = 140 - (strlen($url)+1);
if (strlen($title) > $maxTitleLength) {
$title = substr($title, 0, ($maxTitleLength-3)).'...';
}
$output = "$title $url";
return 'http://twitter.com/home?status='.urlencode($output);
}
?>
Example usage:
<a href="<?php echo $url; ?>" target="_blank"><img src="tweetthis.gif" border="0" alt="Tweet This!" /></a>

tweetthis-15

What I learned From Implementing Ratings & Rankings On A Website

Saturday, May 2nd, 2009

Ratings seem to be a must-have feature in todays’ Web 2.0 world. More and more sites are using the ratings feature the most popular site (at least to me) being YouTube. If you are planning to implement a ratings feature on your website there are several steps to follow:

  1. Decide if the feature makes sense at all
    You should not try to create an artificial rating system where it simply does not fit. If you have nothing on your site that would make sense to rate simply do not implement it.
  2. Decide what you wish to have rated and what your primary goals are
    Do you have any content provided by users like images, postings or content you provide like your own articles, business listings or something similar? Just write down what types of content you have and what might be rated by your users and especially what you want to achive.
    Do you just want to improve the stickyness of your website visitors or is your main goal to identify quality content and/or users? Do you wish to get just more users or improve the loyalty of the existing users or both?
  3. Give users a reason to rate
    Always focus on the end user who will ask “What’s in it for me?” before using your ratings feature. Just imagine that the user has to invest some time and effort to write a rating. If you only allow registered users to add ratings on your website (which I think you should always do - just like YouTube oes) the incentive or personal gain should be even higher because signing up on your site and providing credentials and maybe even more data is a task most people do not want to take.
    You can use physical incentives like some small gifts - merchandise is good if it fits with your brand. However you can of course also use other incentives - even virtual ones like points for ratings, comments and so on that can be exchanged for downloadable products like free software or - if this fits with your brand - desktop wallpapers, ringtones or something similar.
  4. Which rating methods do you wish to use?
    There are two main distinctions: a simple one-click star rating and a textual rating. The one-click rating is the easiest one but it can also be used without thinking - just “click and continue” especially if the user gets something in return depending on the number of ratings.The textual rating not only requires much more user interaction, it also leads to much more work for you as well. If the user simply clicks on a star that’s all. He’s done. A textual rating requires much more effort and may also be used to abuse your ratings system. A textual comment may contain SPAM but it may also contain abusive language and negative comments from someone who wants to damage a competitor’s reputation.
    This is a very complex topic and I will therefore not cover it here because I could write a full article about that as well. Just keep this in mind as this might lead to negative publicity if you do not carefully screen the texts submitted by users.
  5. Toplists
    If a user gets no perceived personal gain from using your ratings feature the stickyness is not likely to improve. By implementing something like a toplist which shows the users that have rated something on your websites ordered by the number and/or quality of ratings they might use your ratings feature more often.
    In the best case - I will talk about that later in this article - everyone will benefit from the ratings feature.
    Many people like to tell others that they are the “top rated user” on a website or at least something like a “top 10″ user just because of the perceived personal gain - or even admiration - not because they are getting something physical in return.
    You should not underestimate this human trait. So I definetly think you should integrate something like a toplist on your website. Implementing this however may yield more useless ratings because there are many people out there that would just like to get a top position without much work so be prepared to handle ratings like “I can highly recommend this [whatever]” over and over again. If you are just using star-type ratings this may or may not be a problem depending on what the user can rate. You can actually rate the perceived quality of an image quite well within a few seconds but you obviously cannot rate a 1000-word article within 5 seconds. This is a very tricky situation.
  6. Don’t fake ratings
    You should never fake ratings or have other people write ratings for you that are getting paid to do it. Most users will be able to spot this easily just like I did on a German business directory.
  7. Don’t syndicate ratings
    Although syndicating ratings from other vendors might give the impression that you have lots of good content most users are likely to find out soon that you are not providing unique content especially if you have many competitors. From an SEO standpoint you should not do that as well because duplicate content is something you should always try to avoid.

What I learned

On one of my websites (a German website for models and those who wish to become models) I have implemented a ratings feature about two years ago. Although I have not implemented a textual ratings or comments feature yet a simple 5-star rating allows every registered user to rate a model profile. And that’s actually the complete visible ratings feature I implemented. I also implemented a list of profiles the user has not rated yet to encourage the users to rate other profiles.

However there is also a hidden ranking feature called “SilverIndex” which ranks the model profiles with the profile with the most “index points” coming first and all the others after that ordered according to their points value. This simple integer value is calculated once per day by these parameters (and several more I cannot write down here because of possible manipulation of the ranking):

  • Total number of photos in the profile
  • Types of photos (body, face, hands etc.) - photo types (hand photos for example) that are very scarce lead to a higher number of points
  • Age of the photos (you always want to have current photos)
  • Original size of the photos (small photos are not professional)
  • Last login date (post-and-leave is not encouraged)
  • Age of the profile (fresh profiles get more points for a few days to push new models)
  • Number of new users referred (need to have a visible profile as well)

To encourage users to rate other profiles the number of ratings of other profiles also counts against the points value so the more profiles have been rated the more points the user will get and thus get a higher position in the main model list. In fact the complete list of models is ordered by the SilverIndex so to get as many visits to a profile as possible from potential clients a user actually has to be and remain active on the site.

This leads to a situation that is good for everyone: many professional and current photos of the different types are good for potential clients and also show the motivation of the user for becoming a model (or getting to participate in a shooting). So if there is a way for you to rank whatever you are making available for rating by these kinds of features you should really do that.

If you allow your users to rate for example businesses obviously businesses that get many ratings tend to have many customers so you may want to give them a higher ranking on your site.

If you offer a verification process like some websites do you should also give more trust to a user (and thus more points) if the user account has been verified. You could even charge a small handling fee for verification if you are sending a letter to the postal address given by the user to verify it.

So if there is an incentive for your users to rate contents you provide you should clearly focus on that and make it especially clear for your users so they immediately know what to do next to achive a certain goal.

The ranking algorithm I have implemented automatically optimizes the model list because it both encourages ratings and it also encourages providing good content.

Recommened reading on how to rank your users: Yahoo Design Patterns

tweetthis-15