Tuesday, April 20, 2010

Getting Started with OOP & PHP5

Since the introduction of PHP 5 in 2004, PHP has had an object model worthy of that description and became a truly modern language for use on the web. Earlier PHP scripts would have been of the kind where, to quote from Alice's Adventures, you would `"Begin at the beginning, and go on till you come to the end: then stop."
Nowadays that very procedural approach is less common in PHP, so this article takes a look at some of the basic object oriented features available in the language and shows some examples of using them with code examples.

Using OOP (Object Orientated Programming) enables us to architect our systems much more clearly, and to make them more manageable and more maintainable. This technique also allows us to separate form from function to create clean, navigable codebases with plenty of opportunities to reuse code, apply design patterns and bring in concepts from other brances of computer science.

Objects vs Classes

While the terms "object" and "class" are often used almost interchangeably in the world of software, there is a definite conceptual difference between the two. A class is the blueprint or recipe; it describes what the object should be, have and do. So a class might look like this:
class Elephpant {
    public $colour;

    public function dance() {
        echo "elephpant dances!\n";
        return true;
    }
}
elephpant.php
An object, on the other hand, is an actual instantiation of the class – its an actual thing, with values and behaviours. In the example below, $ele is the object:
include('elephpant.php');

$ele = new Elephpant();
We can inspect $ele to make sure that it is, in fact, an object of the class Elephpant, using the print_r command. Adding this to our code sample as shown, we see the output below:
include('elephpant.php');

$ele = new Elephpant();
print_r($ele);

Elephpant Object
(
    [colour] =>
)
This output shows an object, of type Elephpant, and with a single empty property named "colour". For more information about the objects exact properties and their values, you can also use var_dump, which gives a more detailed output showing in detail the datatypes of each property. This is particularly useful for spotting empty strings, nulls and false.

Using Objects, Their Properties and Methods

Our class, Elephpant, has a property and a method (OO-speak for "function") already defined inside it, so how can we interact with these? Let's start by setting the colour property; we use the object operator which is a hyphen followed by a greater than sign.
include('elephpant.php');

$ele = new Elephpant();

// set the colour property
$ele->colour = "blue";

// now use that property
echo "The elephpant is " . $ele->colour;
The output of this script reads "The elephpant is blue". The property will remain set on the object until the object is destroyed, or the property overwritten or unset. Objects are a great way of keeping things together that belong together, for example information about an elephpant!
Similarly we can call the method using the same operator – the brackets after the call let PHP know its a method rather than a property, and if we had parameters to pass in they'd go between the brackets. Something like this:
include('elephpant.php');

$ele = new Elephpant();

// call the dance method
$ele->dance();
Look back at the class declaration for Elephpant and you'll see the dance method actually echoes from within it. Indeed when we run the code example here, we see "elephpant dances!" as our output. It is a very trivial example but I hope it does show how to call methods against our objects. An alternative approach (and probably a better one within an actual application) would be to create the string and use it as the return value for the function. Then the calling code can take the string and echo it, or do whatever else it needs to, in a more flexible way.

Inheritance

Now we know how to create and interact with objects, let's step things up a bit and look at how we can create objects which are similar in some ways and different in others, using inheritance. If you are accustomed to OOP from any other programming languages then this will seem very familiar to you, so here is a quick look at how this can be done in PHP. We already have our Elephpant class declared, so let's add a Penguin class as well. They will both inherit from the parent class Animal, which looks like this:
class Animal{

    public $type = "animal";

    public function dance() {
        echo $this->type . " dances!\n";
        return true;
    }
}
animal.php
The animal has a "type" property, and a dance() method. It uses the type property in the dance() method to create the output, using $this to refer to the current object. In PHP, $this is a special keyword which refers to the current object from within its own class.
Now we can create a Penguin class that inherits from this general Animal class, by using the extends keyword to denote its parent:
class Penguin extends Animal {
    public $type = "penguin";
}
penguin.php
The penguin class would inherit the type property set to "animal" if we didn't override it by setting the property again in this class. However even without declaring a dance() method, the penguin can dance!
include('animal.php');
include('penguin.php');

$tux = new Penguin();

// make tux dance
$tux->dance();
The above example gives the output "penguin dances!" – using the dance() method from the Animal class, which is available because the Penguin class extends it, and the type property set separately in the Penguin class itself.

Access Modifiers

Take a look at the previous example. The type is set in the class, but we could easily set it from our main code if we wanted to. Imagine if we put $tux->type = "giraffe" before we asked him to dance! Sometimes this is the desired behaviour, and sometimes it isn't. To allow us to control whether properties can be changed outside a class, PHP gives us access modifiers. An example of these are the "public" keywords you see in the classes shown above. To prevent the type property being edited from outside the class, we can declare the Penguin type to be private, so the class now looks like this:
class Penguin extends Animal {
    private $type = "penguin";
}
private_penguin.php
The following code listing shows us trying to set the now-private type property, and is followed by the resulting output.
include('animal.php');
include('private_penguin.php');

$tux = new Penguin();

// change the type
$tux->type = "linux penguin";
// make tux dance
$tux->dance();

Fatal error: Access level to Penguin::$type must be public (as in class Animal) in /home/lorna/.../OOP/private_penguin.php on line 5
The resulting message feeds back to the user that the type property can't be modified, and even includes the detail that the property was public in the parent class. Access modifiers are pretty powerful, we should look at them in more detail.
Access modifiers can be applied to properties and to methods and to properties. The options are public, private and protected. In PHP4, these weren't available and everything is public. As a result, and to maintain backwards compatibility, if an access modifier isn't specified then the property or method defaults to being public. This isn't recommended practice however, and it is best to be explicit about which is intended.
Public: The public access modifier means that properties and methods can be accessed from anywhere, within the scope of the object itself, and also from outside code operating on an object.
Private: The method or property is only available from within the scope of this specific class. Before using this option, read on to find out about the "protected" access modifier.
Protected: The method or property is available from within this class, and from within any classes with extend or implement this class. This is ideal where you don't want external code to change the class, but you do want to be able to extend the class later and take advantage of this property or method. Protected is more flexible than private and almost always the better choice.
Using these access modifiers we can control where our class methods and properties can be accessed from. We looked at an example of properties and this works in the same way for method calls – they cannot be accessed from outside of the class definition unless they are declared to be public. It can be very useful indeed to declare methods as protected, where they are internal helper methods used by other class methods but not intended to be accessed directly. In PHP4 there was no support for this and so the internal methods were sometimes named with an underscore to hint that this was their intended use – it is still possible to see this naming convention in use today, although it is not needed.

Monday, April 5, 2010

HTML5 – New Old Semantics

We are sure that you’ll agree that HTML is one of the best web inventions of all times. The hyper text markup language is actually the cornerstone of modern web that appears to be a unique and self-sufficient phenomenon.

When HTML5 was being developed its developers have faced the few important issues that were to be solved with the help of HTML5. And one of these problems was creating a really explicit and extensible semantics. Now the tricky part is that the old versions of HTML were also being designed with the versatility in mind – with loads of various tags that were considered absolutely essential but have eventually proved themselves to be totally useless. The approach in the HTML5 has been changed according to the needs of today’s Internet.

HTML5 New Tags

The task that had to be accomplished by the developers was to create the richer and meaningful semantics for HTML5 version – plus the fact that new solution was supposed to be flexible, strongly efficient and of course to correspond to all modern web standards. Now here comes the list of the new tags that will available in HTML5.

  • <article> tag defines an article
  • <aside> tag defines content aside from the page content
  • <audio> tag defines sound content
  • <canvas> tag defines graphics
  • <command> tag defines a command button
  • <datalist> tag defines a dropdown list
  • <details> tag defines details of an element
  • <dialog> tag defines a dialog (conversation)
  • <embed> tag defines external interactive content or plugin
  • <figure> tag defines a group of media content, and their caption
  • <footer> tag defines a footer for a section or page
  • <header> tag defines a header for a section or page
  • <hgroup> tag defines information about a section in a document
  • <keygen> tag defines a generated key in a form
  • <mark> tag defines marked text
  • <meter> tag defines measurement within a predefined range
  • <nav> tag defines navigation links
  • <output> tag defines some types of output
  • <progress> tag defines progress of a task of any kind
  • <rp> tag is used in ruby annotations to define what to show browsers that do not support the ruby element.
  • <rt> tag defines explanation to ruby annotations.
  • <ruby> tag defines ruby annotations.
  • <section> tag defines a section
  • <source> tag defines media resources
  • <time> tag defines a date/time
  • <video> tag defines a video

Saturday, April 3, 2010

Using OOP in PHP: Practical Example


Object Oriented design is particularly useful where you have data objects that relate to one another – so it is very common for example to have OOP used to deal with data. PHP 5 has the PDO (PHP Data Object) classes which are a great way to talk to a backend database, either mysql or any other kind of database, and using the object oriented interface offered by this extension ties in well with the usage I have shown here.
A common mistake for those coming to OO for the first time is to declare methods inside a class but then instantiate a single copy of that and pass in data such as the ID of the data to each method. Here’s an example of a user class that does this:
class User {
    /**
     * getDisplayName
     *
     * @param int $user_id the user_id of the user in the database table
     * @access public
     * @return string Display name of this user
     */
    public function getDisplayName($user_id) {
        $sql = 'select display_name from users where user_id = '.$user_id;
        $results = mysql_query($sql);
        $row = mysql_fetch_array($results);
        return $row['display_name'];
    }

    /**
     * getFriends
     *
     * @param int $user_id the user_id of the user in the database table
     * @access public
     * @return array An array of friend_ids
     */
    public function getFriends($user_id) {
        $sql = 'select friend_id from user_friends where user_id = '.$user_id;
        $results = mysql_query($sql);
        $friends = array();
        while($row = mysql_fetch_array($results)) {
            $friends[] = $row['friend_id'];
        }
        return $friends;
    }
}
user.php
And some code that uses it:
include('user.php');
mysql_connect('localhost','root','');
mysql_select_db('test');

$user = new User();
echo "User known as: " . $user->getDisplayName(1) . "\n";

$friends = $user->getFriends(1);
echo "Friends with: " . implode(', ',$friends) . "\n";
If you want to run this code yourself, then you can set up the database tables using this script:
CREATE TABLE `user_friends` (
  `user_friend_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `friend_id` int(11) NOT NULL,
  PRIMARY KEY (`user_friend_id`)
)
INSERT INTO `user_friends` VALUES (1,1,3),(2,1,5);

CREATE TABLE `users` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(20) DEFAULT NULL,
  `last_name` varchar(50) DEFAULT NULL,
  `display_name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
)
INSERT INTO `users` VALUES (1,'Lorna','Mitchell','lornajane');
user.sql
This is more like a function library than an actual object, and although it works perfectly well and does have its applications, it can be better to aim to take advantage of more object oriented features. To do this, a new object should be created for each item the system handles, and if it has an ID and perhaps some other properties, these should be set as part of the object. Then rather than creating a single user object and doing getFriends(42) on it, you’d have a user with ID 42 which did $user->getFriends().
Here’s a follow up example with a class and how to use it, this will give better performance and enable you to clearly see which data goes with which object where there are multiple items on a page:
class User {
    /**
     * getUserById
     *
     * @param int $user_id the id of the user row in the table
     * @access public
     * @return true if the user was found
     */
    public function getUserById($user_id) {
        $sql = 'select first_name, last_name, display_name from users where user_id = ' . $user_id;
        $results = mysql_query($sql);
        $row = mysql_fetch_array($results);
        $this->user_id = $user_id;
        $this->first_name = $row['first_name'];
        $this->last_name = $row['last_name'];
        $this->display_name = $row['display_name'];

        // in real life, there would be escaping and error handling and we'd only return true if we got data
        return true;
    }

    /**
     * getDisplayName
     *
     * @access public
     * @return string Display name of this user
     */
    public function getDisplayName() {
        return $this->display_name;
    }

    /**
     * getFriends
     *
     * @access public
     * @return array An array of friend_ids
     */
    public function getFriends() {
        $sql = 'select friend_id from user_friends where user_id = '.$this->user_id;
        $results = mysql_query($sql);
        $friends = array();
        while($row = mysql_fetch_array($results)) {
            $friends[] = $row['friend_id'];
        }
        return $friends;
    }
}
user2.php
include('user2.php');
mysql_connect('localhost','root','');
mysql_select_db('test');

$user = new User();
// populate the object
$user->getUserById(1);
echo "User known as: " . $user->getDisplayName() . "\n";

$friends = $user->getFriends();
echo "Friends with: " . implode(', ',$friends) . "\n";

In Summary

This has been a very introductory look at some of the object oriented features available in PHP, to get you started out with the basics of working with OO code and also writing your own. If this has helped you take your first OOP steps, then let us know by leaving a comment and let us know what you built! In the next post there will be some more in-depth content including using constructors, access modifiers and working with the static keyword in PHP – taking your skills to the next level.

Saturday, March 27, 2010

The Java serialization algorithm revealed

What is serialization?

Serialization is the process of saving an object's state to a sequence of bytes; deserialization is the process of rebuilding those bytes into a live object. The Java Serialization API provides a standard mechanism for developers to handle object serialization. In this tip, you will see how to serialize an object, and why serialization is sometimes necessary. You'll learn about the serialization algorithm used in Java, and see an example that illustrates the serialized format of an object. By the time you're done, you should have a solid knowledge of how the serialization algorithm works and what entities are serialized as part of the object at a low level.

Why is serialization required?

In today's world, a typical enterprise application will have multiple components and will be distributed across various systems and networks. In Java, everything is represented as objects; if two Java components want to communicate with each other, there needs be a mechanism to exchange data. One way to achieve this is to define your own protocol and transfer an object. This means that the receiving end must know the protocol used by the sender to re-create the object, which would make it very difficult to talk to third-party components. Hence, there needs to be a generic and efficient protocol to transfer the object between components. Serialization is defined for this purpose, and Java components use this protocol to transfer objects.
Figure 1 shows a high-level view of client/server communication, where an object is transferred from the client to the server through serialization.

How to serialize an object

In order to serialize an object, you need to ensure that the class of the object implements the java.io.Serializable interface, as shown in Listing 1.

Listing 1. Implementing Serializable

import java.io.Serializable; class TestSerial implements Serializable { public byte version = 100; public byte count = 0; }
In Listing 1, the only thing you had to do differently from creating a normal class is implement the java.io.Serializable interface. The Serializable interface is a marker interface; it declares no methods at all. It tells the serialization mechanism that the class can be serialized.
Now that you have made the class eligible for serialization, the next step is to actually serialize the object. That is done by calling the writeObject() method of the java.io.ObjectOutputStream class, as shown in Listing 2.

Listing 2. Calling writeObject()

public static void main(String args[]) throws IOException { FileOutputStream fos = new FileOutputStream("temp.out"); ObjectOutputStream oos = new ObjectOutputStream(fos); TestSerial ts = new TestSerial(); oos.writeObject(ts); oos.flush(); oos.close(); }
Listing 2 stores the state of the TestSerial object in a file called temp.out. oos.writeObject(ts); actually kicks off the serialization algorithm, which in turn writes the object to temp.out.
To re-create the object from the persistent file, you would employ the code in Listing 3.

Listing 3. Recreating a serialized object

public static void main(String args[]) throws IOException { FileInputStream fis = new FileInputStream("temp.out"); ObjectInputStream oin = new ObjectInputStream(fis); TestSerial ts = (TestSerial) oin.readObject(); System.out.println("version="+ts.version); }
In Listing 3, the object's restoration occurs with the oin.readObject() method call. This method call reads in the raw bytes that we previously persisted and creates a live object that is an exact replica of the original object graph. Because readObject() can read any serializable object, a cast to the correct type is required.
Executing this code will print version=100 on the standard output.

The serialized format of an object

What does the serialized version of the object look like? Remember, the sample code in the previous section saved the serialized version of the TestSerial object into the file temp.out. Listing 4 shows the contents of temp.out, displayed in hexadecimal. (You need a hexadecimal editor to see the output in hexadecimal format.)

Listing 4. Hexadecimal form of TestSerial

AC ED 00 05 73 72 00 0A 53 65 72 69 61 6C 54 65 73 74 A0 0C 34 00 FE B1 DD F9 02 00 02 42 00 05 63 6F 75 6E 74 42 00 07 76 65 72 73 69 6F 6E 78 70 00 64
If you look again at the actual TestSerial object, you'll see that it has only two byte members, as shown in Listing 5.

Listing 5. TestSerial's byte members

public byte version = 100; public byte count = 0;
The size of a byte variable is one byte, and hence the total size of the object (without the header) is two bytes. But if you look at the size of the serialized object in Listing 4, you'll see 51 bytes. Surprise! Where did the extra bytes come from, and what is their significance? They are introduced by the serialization algorithm, and are required in order to to re-create the object. In the next section, you'll explore this algorithm in detail.

Java's serialization algorithm

By now, you should have a pretty good knowledge of how to serialize an object. But how does the process work under the hood? In general the serialization algorithm does the following:
  • It writes out the metadata of the class associated with an instance.
  • It recursively writes out the description of the superclass until it finds java.lang.object.
  • Once it finishes writing the metadata information, it then starts with the actual data associated with the instance. But this time, it starts from the topmost superclass.
  • It recursively writes the data associated with the instance, starting from the least superclass to the most-derived class.
I've written a different example object for this section that will cover all possible cases. The new sample object to be serialized is shown in Listing 6.

Listing 6. Sample serialized object

class parent implements Serializable { int parentVersion = 10; } class contain implements Serializable{ int containVersion = 11; } public class SerialTest extends parent implements Serializable { int version = 66; contain con = new contain(); public int getVersion() { return version; } public static void main(String args[]) throws IOException { FileOutputStream fos = new FileOutputStream("temp.out"); ObjectOutputStream oos = new ObjectOutputStream(fos); SerialTest st = new SerialTest(); oos.writeObject(st); oos.flush(); oos.close(); } }
This example is a straightforward one. It serializes an object of type SerialTest, which is derived from parent and has a container object, contain. The serialized format of this object is shown in Listing 7.

Listing 7. Serialized form of sample object

AC ED 00 05 73 72 00 0A 53 65 72 69 61 6C 54 65 73 74 05 52 81 5A AC 66 02 F6 02 00 02 49 00 07 76 65 72 73 69 6F 6E 4C 00 03 63 6F 6E 74 00 09 4C 63 6F 6E 74 61 69 6E 3B 78 72 00 06 70 61 72 65 6E 74 0E DB D2 BD 85 EE 63 7A 02 00 01 49 00 0D 70 61 72 65 6E 74 56 65 72 73 69 6F 6E 78 70 00 00 00 0A 00 00 00 42 73 72 00 07 63 6F 6E 74 61 69 6E FC BB E6 0E FB CB 60 C7 02 00 01 49 00 0E 63 6F 6E 74 61 69 6E 56 65 72 73 69 6F 6E 78 70 00 00 00 0B

Friday, March 12, 2010

GWT XML Indenter/Formatter

So while I was working on one of my outreach projects as a graduate student, I wanted to write a simple XML indenter to make my GWT generated xml more aesthetically appealing using stock GWT. The xml document is assumed to be as lean as possible (There are no empty #text nodes that are usually in xml because of the indentation.)

I should also mention that I’m posting this because I didn’t really see any stock simple GWT indenters after a quick google. The following is not meant to be a complete indenter, just something quick and simple to organize xml.
Here’s a basic indenter.

 public String formatXML(Node node,String tab_str)
 {
  String formatted="";
 
  if (node.getNodeType()==Node.ELEMENT_NODE)
  {
   String attributes="";
   for (int k=0;k < node.getAttributes().getLength();k++)
    attributes+=" "+node.getAttributes().item(k).getNodeName()+"=\""+node.getAttributes().item(k).getNodeValue()+"\"";
 
   formatted=tab_str+"<"+node.getNodeName()+attributes+">\n";
 
   for (int i=0;i< node.getChildNodes().getLength();i++)
   {
    formatted=formatted+formatXML(node.getChildNodes().item(i),tab_str+"    ");
   }
   formatted=formatted+tab_str+"+node.getNodeName()+">\n";
  }
  else
  {
   if (node.toString().trim().length()>0)
    formatted=tab_str+node.toString()+"\n";
  }
 
  return formatted;
 }

Thursday, February 25, 2010

Playing with JVM / Java Heap Size.

Java programs executes in JVM uses Heap of memory to manage the data. If your Java program requires a large amount of memory, it is possible that the virtual machine will begin to throw OutOfMemoryError instances when attempting to instantiate an object. The default heap size if 1 MB and can increase as much as 16 MB.

Setting/Increase JVM heap size

It is possible to increase heap size allocated by the Java Virtual Machine (JVM) by using command line options.
Following are few options available to change Heap Size.
  1. -Xms<size> set initial Java heap size
  2. -Xmx<size> set maximum Java heap size
  3. -Xss<size> set java thread stack size
For example, you can set minimum heap to 64 MB and maximum heap 256 MB for a Java program HelloWorld.
  1. java -Xms64m -Xmx256m HelloWorld

Getting / Reading default heap size

It is possible to read the default JVM heap size programmatically by using totalMemory() method of Runtime class. Use following code to read JVM heap size.
public class GetHeapSize {
  public static void main(String[]args){
    //Get the jvm heap size.
    long heapSize = Runtime.getRuntime().totalMemory();
    //Print the jvm heap size.
    System.out.println("Heap Size = " + heapSize);
  }
}

Tuesday, February 23, 2010

How to show each post’s date in WordPress

The templating system in WordPress is very flexible, and there's  rarely something you can't do or that doesn't work as you'd expect. A  notable exception however is the_date.  Its purpose is simple enough. It displays the current post's date of  creation. But on pages with more than one post (such as on many blog  home pages), something weird happens. If a number of posts on any given  page were created on the same date, the_date will only show  that date for the first of those posts.
In the early days of blogging, posts were usually listed by date,  much like a regular, paper diary. In the old default theme that comes  with WordPress a big date title is used to separate posts into days.  That's what the_date was created to do, and so it makes  sense it only displays the same date once. In most modern themes  however, people like the date to be among the meta data for each  article, so the_date falls short.

Friday, February 12, 2010

ChromeOS gets more mature with Flow

It's been a while since I blogged about Chrome OS. Things have been pretty quiet around the Google-supported operating system for netbooks and tablets. But Hexxeh, a 17th year old developer who's been supplying pre-built versions of the OS for a while now, released an new version yesterday, and it's a lot more polished than earlier builds. It boots in seconds and runs pretty smoothly for a pre-alpha OS. If you're curious about Chrome OS, this is the perfect opportunity to give it a try.
Not only is the 'Flow' build very easy to use, there are complete setup instructions as well. The OS is installed on a USB stick or an SD card (provided your target computer has a card reader it can boot from). It runs off of that drive, so nothing is left behind on the computer's hard drive. Simply take out the SD card and boot up to get back to Windows or whatever you were using before.

Monday, January 25, 2010

Best Practices for Speeding Up Your Web Site - Gzip Components

The time it takes to transfer an HTTP request and response across the network can be significantly reduced by decisions made by front-end engineers. It's true that the end-user's bandwidth speed, Internet service provider, proximity to peering exchange points, etc. are beyond the control of the development team. But there are other variables that affect response times. Compression reduces response times by reducing the size of the HTTP response.

Starting with HTTP/1.1, web clients indicate support for compression with the Accept-Encoding header in the HTTP request.


Accept-Encoding: gzip, deflate

If the web server sees this header in the request, it may compress the response using one of the methods listed by the client. The web server notifies the web client of this via the Content-Encoding header in the response.


Content-Encoding: gzip

Gzip is the most popular and effective compression method at this time. It was developed by the GNU project and standardized by RFC 1952. The only other compression format you're likely to see is deflate, but it's less effective and less popular.

Gzipping generally reduces the response size by about 70%. Approximately 90% of today's Internet traffic travels through browsers that claim to support gzip. If you use Apache, the module configuring gzip depends on your version: Apache 1.3 uses mod_gzip while Apache 2.x uses mod_deflate.

There are known issues with browsers and proxies that may cause a mismatch in what the browser expects and what it receives with regard to compressed content. Fortunately, these edge cases are dwindling as the use of older browsers drops off. The Apache modules help out by adding appropriate Vary response headers automatically.

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

Gzipping as many file types as possible is an easy way to reduce page weight and accelerate the user experience.

Sunday, January 10, 2010

Best Practices for Speeding Up Your Web Site - Minimize HTTP Requests

80% of the end-user response time is spent on the front-end. Most of this time is tied up in downloading all the components in the page: images, stylesheets, scripts, Flash, etc. Reducing the number of components in turn reduces the number of HTTP requests required to render the page. This is the key to faster pages.

One way to reduce the number of components in the page is to simplify the page's design. But is there a way to build pages with richer content while also achieving fast response times? Here are some techniques for reducing the number of HTTP requests, while still supporting rich page designs.

Combined files are a way to reduce the number of HTTP requests by combining all scripts into a single script, and similarly combining all CSS into a single stylesheet. Combining files is more challenging when the scripts and stylesheets vary from page to page, but making this part of your release process improves response times.

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

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

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. Inline images are not yet supported across all major browsers.

Reducing the number of HTTP requests in your page is the place to start. This is the most important guideline for improving performance for first time visitors. As described in Tenni Theurer's blog post Browser Cache Usage - Exposed!, 40-60% of daily visitors to your site come in with an empty cache. Making your page fast for these first time visitors is key to a better user experience.

Friday, December 25, 2009

Best Practices for Speeding Up Your Web Site - Put Scripts at the Bottom

The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.

In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.

An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.

Saturday, December 12, 2009

Best Practices for Speeding Up Your Web Site - Put Stylesheets at the Top

While researching performance at Yahoo!, we discovered that moving stylesheets to the document HEAD makes pages appear to be loading faster. This is because putting stylesheets in the HEAD allows the page to render progressively.

Front-end engineers that care about performance want a page to load progressively; that is, we want the browser to display whatever content it has as soon as possible. This is especially important for pages with a lot of content and for users on slower Internet connections. The importance of giving users visual feedback, such as progress indicators, has been well researched and documented. In our case the HTML page is the progress indicator! When the browser loads the page progressively the header, the navigation bar, the logo at the top, etc. all serve as visual feedback for the user who is waiting for the page. This improves the overall user experience.

The problem with putting stylesheets near the bottom of the document is that it prohibits progressive rendering in many browsers, including Internet Explorer. These browsers block rendering to avoid having to redraw elements of the page if their styles change. The user is stuck viewing a blank white page.

The HTML specification clearly states that stylesheets are to be included in the HEAD of the page: "Unlike A, [LINK] may only appear in the HEAD section of a document, although it may appear any number of times." Neither of the alternatives, the blank white screen or flash of unstyled content, are worth the risk. The optimal solution is to follow the HTML specification and load your stylesheets in the document HEAD.

Wednesday, November 25, 2009

Best Practices for Speeding Up Your Web Site - Avoid CSS Expressions

CSS expressions are a powerful (and dangerous) way to set CSS properties dynamically. They're supported in Internet Explorer, starting with version 5. As an example, the background color could be set to alternate every hour using CSS expressions.

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

As shown here, the expression method accepts a JavaScript expression. The CSS property is set to the result of evaluating the JavaScript expression. The expression method is ignored by other browsers, so it is useful for setting properties in Internet Explorer needed to create a consistent experience across browsers.

The problem with expressions is that they are evaluated more frequently than most people expect. Not only are they evaluated when the page is rendered and resized, but also when the page is scrolled and even when the user moves the mouse over the page. Adding a counter to the CSS expression allows us to keep track of when and how often a CSS expression is evaluated. Moving the mouse around the page can easily generate more than 10,000 evaluations.

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.

Monday, November 9, 2009

Best Practices for Speeding Up Your Web Site - Make JavaScript and CSS External

Many of these performance rules deal with how external components are managed. However, before these considerations arise you should ask a more basic question: Should JavaScript and CSS be contained in external files, or inlined in the page itself?

Using external files in the real world generally produces faster pages because the JavaScript and CSS files are cached by the browser. JavaScript and CSS that are inlined in HTML documents get downloaded every time the HTML document is requested. This reduces the number of HTTP requests that are needed, but increases the size of the HTML document. On the other hand, if the JavaScript and CSS are in external files cached by the browser, the size of the HTML document is reduced without increasing the number of HTTP requests.

The key factor, then, is the frequency with which external JavaScript and CSS components are cached relative to the number of HTML documents requested. This factor, although difficult to quantify, can be gauged using various metrics. If users on your site have multiple page views per session and many of your pages re-use the same scripts and stylesheets, there is a greater potential benefit from cached external files.

Many web sites fall in the middle of these metrics. For these sites, the best solution generally is to deploy the JavaScript and CSS as external files. The only exception where inlining is preferable is with home pages, such as Yahoo!'s front page and My Yahoo!. Home pages that have few (perhaps only one) page view per session may find that inlining JavaScript and CSS results in faster end-user response times.

For front pages that are typically the first of many page views, there are techniques that leverage the reduction of HTTP requests that inlining provides, as well as the caching benefits achieved through using external files. One such technique is to inline JavaScript and CSS in the front page, but dynamically download the external files after the page has finished loading. Subsequent pages would reference the external files that should already be in the browser's cache.

Friday, October 16, 2009

Best Practices for Speeding Up Your Web Site - Reduce DNS Lookups

The Domain Name System (DNS) maps hostnames to IP addresses, just as phonebooks map people's names to their phone numbers. When you type www.yahoo.com into your browser, a DNS resolver contacted by the browser returns that server's IP address. DNS has a cost. It typically takes 20-120 milliseconds for DNS to lookup the IP address for a given hostname. The browser can't download anything from this hostname until the DNS lookup is completed.

DNS lookups are cached for better performance. This caching can occur on a special caching server, maintained by the user's ISP or local area network, but there is also caching that occurs on the individual user's computer. The DNS information remains in the operating system's DNS cache (the "DNS Client service" on Microsoft Windows). Most browsers have their own caches, separate from the operating system's cache. As long as the browser keeps a DNS record in its own cache, it doesn't bother the operating system with a request for the record.

Internet Explorer caches DNS lookups for 30 minutes by default, as specified by the DnsCacheTimeout registry setting. Firefox caches DNS lookups for 1 minute, controlled by the network.dnsCacheExpiration configuration setting. (Fasterfox changes this to 1 hour.)

When the client's DNS cache is empty (for both the browser and the operating system), the number of DNS lookups is equal to the number of unique hostnames in the web page. This includes the hostnames used in the page's URL, images, script files, stylesheets, Flash objects, etc. Reducing the number of unique hostnames reduces the number of DNS lookups.

Reducing the number of unique hostnames has the potential to reduce the amount of parallel downloading that takes place in the page. Avoiding DNS lookups cuts response times, but reducing parallel downloads may increase response times. My guideline is to split these components across at least two but no more than four hostnames. This results in a good compromise between reducing DNS lookups and allowing a high degree of parallel downloads.

Thursday, October 1, 2009

Best Practices for Speeding Up Your Web Site - Minify JavaScript and CSS

Minification is the practice of removing unnecessary characters from code to reduce its size thereby improving load times. When code is minified all comments are removed, as well as unneeded white space characters (space, newline, and tab). In the case of JavaScript, this improves response time performance because the size of the downloaded file is reduced. Two popular tools for minifying JavaScript code are JSMin and YUI Compressor. The YUI compressor can also minify CSS.

Obfuscation is an alternative optimization that can be applied to source code. It's more complex than minification and thus more likely to generate bugs as a result of the obfuscation step itself. In a survey of ten top U.S. web sites, minification achieved a 21% size reduction versus 25% for obfuscation. Although obfuscation has a higher size reduction, minifying JavaScript is less risky.

In addition to minifying external scripts and styles, inlined <script> and <style> blocks can and should also be minified. Even if you gzip your scripts and styles, minifying them will still reduce the size by 5% or more. As the use and size of JavaScript and CSS increases, so will the savings gained by minifying your code.

Friday, September 25, 2009

Best Practices for Speeding Up Your Web Site - Avoid Redirects

Redirects are accomplished using the 301 and 302 status codes. Here's an example of the HTTP headers in a 301 response:

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

The browser automatically takes the user to the URL specified in the Location field. All the information necessary for a redirect is in the headers. The body of the response is typically empty. Despite their names, neither a 301 nor a 302 response is cached in practice unless additional headers, such as Expires or Cache-Control, indicate it should be. The meta refresh tag and JavaScript are other ways to direct users to a different URL, but if you must do a redirect, the preferred technique is to use the standard 3xx HTTP status codes, primarily to ensure the back button works correctly.

The main thing to remember is that redirects slow down the user experience. Inserting a redirect between the user and the HTML document delays everything in the page since nothing in the page can be rendered and no components can start being downloaded until the HTML document has arrived.

One of the most wasteful redirects happens frequently and web developers are generally not aware of it. It occurs when a trailing slash (/) is missing from a URL that should otherwise have one. For example, going to http://astrology.advancedmicrodevices.org/astrology results in a 301 response containing a redirect to http://astrology.advancedmicrodevices.org/astrology/ (notice the added trailing slash). This is fixed in Apache by using Alias or mod_rewrite, or the DirectorySlash directive if you're using Apache handlers.

Connecting an old web site to a new one is another common use for redirects. Others include connecting different parts of a website and directing the user based on certain conditions (type of browser, type of user account, etc.). Using a redirect to connect two web sites is simple and requires little additional coding. Although using redirects in these situations reduces the complexity for developers, it degrades the user experience. Alternatives for this use of redirects include using Alias and mod_rewrite if the two code paths are hosted on the same server. If a domain name change is the cause of using redirects, an alternative is to create a CNAME (a DNS record that creates an alias pointing from one domain name to another) in combination with Alias or mod_rewrite.

Friday, September 18, 2009

Best Practices for Speeding Up Your Web Site - Remove Duplicate Scripts

t hurts performance to include the same JavaScript file twice in one page. This isn't as unusual as you might think. A review of the ten top U.S. web sites shows that two of them contain a duplicated script. Two main factors increase the odds of a script being duplicated in a single web page: team size and number of scripts. When it does happen, duplicate scripts hurt performance by creating unnecessary HTTP requests and wasted JavaScript execution.

Unnecessary HTTP requests happen in Internet Explorer, but not in Firefox. In Internet Explorer, if an external script is included twice and is not cacheable, it generates two HTTP requests during page loading. Even if the script is cacheable, extra HTTP requests occur when the user reloads the page.

In addition to generating wasteful HTTP requests, time is wasted evaluating the script multiple times. This redundant JavaScript execution happens in both Firefox and Internet Explorer, regardless of whether the script is cacheable.

One way to avoid accidentally including the same script twice is to implement a script management module in your templating system. The typical way to include a script is to use the SCRIPT tag in your HTML page.


<script type="text/javascript" src="menu_1.0.17.js"></script>

An alternative in PHP would be to create a function called insertScript.


<?php insertScript("menu.js") ?>

In addition to preventing the same script from being inserted multiple times, this function could handle other issues with scripts, such as dependency checking and adding version numbers to script filenames to support far future Expires headers.

Tuesday, August 25, 2009

Best Practices for Speeding Up Your Web Site - Reduce the Number of DOM Elements

A complex page means more bytes to download and it also means slower DOM access in JavaScript. It makes a difference if you loop through 500 or 5000 DOM elements on the page when you want to add an event handler for example.

A high number of DOM elements can be a symptom that there's something that should be improved with the markup of the page without necessarily removing content. Are you using nested tables for layout purposes? Are you throwing in more <div>s only to fix layout issues? Maybe there's a better and more semantically correct way to do your markup.

A great help with layouts are the YUI CSS utilities: grids.css can help you with the overall layout, fonts.css and reset.css can help you strip away the browser's defaults formatting. This is a chance to start fresh and think about your markup, for example use <div>s only when it makes sense semantically, and not because it renders a new line.

The number of DOM elements is easy to test, just type in Firebug's console:
document.getElementsByTagName('*').length

And how many DOM elements are too many? Check other similar pages that have good markup. For example the Yahoo! Home Page is a pretty busy page and still under 700 elements (HTML tags).



A complex page means more bytes to download and it also means slower DOM access in JavaScript. It makes a difference if you loop through 500 or 5000 DOM elements on the page when you want to add an event handler for example.

A high number of DOM elements can be a symptom that there's something that should be improved with the markup of the page without necessarily removing content. Are you using nested tables for layout purposes? Are you throwing in more <div>s only to fix layout issues? Maybe there's a better and more semantically correct way to do your markup.

A great help with layouts are the YUI CSS utilities: grids.css can help you with the overall layout, fonts.css and reset.css can help you strip away the browser's defaults formatting. This is a chance to start fresh and think about your markup, for example use <div>s only when it makes sense semantically, and not because it renders a new line.

The number of DOM elements is easy to test, just type in Firebug's console:
document.getElementsByTagName('*').length

And how many DOM elements are too many? Check other similar pages that have good markup. For example the Yahoo! Home Page is a pretty busy page and still under 700 elements (HTML tags).

Saturday, August 1, 2009

Best Practices for Speeding Up Your Web Site - Minimize the Number of iframes

Iframes allow an HTML document to be inserted in the parent document. It's important to understand how iframes work so they can be used effectively.

<iframe> pros:

     
  • Helps with slow third-party content like badges and ads
  •  
  • Security sandbox
  •  
  • Download scripts in parallel

<iframe> cons:

     
  • Costly even if blank
  •  
  • Blocks page onload
  •  
  • Non-semantic