Always Get Better

Never stop looking for ways to improve

January 30th, 2012

All web site owners should feel a burning need to speed. Studies have shown that viewers waiting more than 2 or 3 seconds for content to load online are likely to leave without allowing the page to fully load. This is particularly bad if you’re trying to run a web site that relies on visitors to generate some kind of income – content is king but speed keeps the king’s coffers flowing.

If your website isn’t the fastest it can be, you can take some comfort in the fact that the majority of the “top” web sites also suffer from page load times pushing up into the 10 second range (have you BEEN to Amazon lately?). But do take the time to download YSlow today and use its suggestions to start making radical improvements.

I’ve been very interested in web server performance because it is the first leg of the web page’s journey to the end user. The speed of execution at the server level is capable of making or breaking the user’s experience by controlling the amount of ‘lag time’ between the web page request and visible activity in the web browser. We want our server to send page data as immediately as possible so the browser can begin rendering it and downloading supporting files.

Not long ago, I described my web stack and explained why I moved away from the “safe” Apache server solution in favour of nginx. Since nginx doesn’t have a PHP module I had to use PHP’s FastCGI (PHP FPM) server with nginx as a reverse proxy. Additionally, I used memcached to store sessions rather than writing to disk.

Here are the configuration steps I took to realize this stack:

1. Memcached Sessions
Using memcached for sessions gives me slightly better performance on my Rackspace VM because in-memory reading&writing is hugely faster than reading&writing to a virtualized disk. I went into a lot more detail about this last April when I wrote about how to use memcached as a session handler in PHP.

2. PHP FPM
The newest Ubuntu distributions have a package php5-fpm that installs PHP5 FastCGI and an init.d script for it. Once installed, you can tweak your php.ini settings to suit, depending on your system’s configuration. (Maybe we can get into this another time.)

3. Nginx
Once PHP FPM was installed, I created a site entry that would pass PHP requests forward to the FastCGI server, while serving other files directly. Since the majority of my static content (css, javascript, images) have already been moved to a content delivery network, nginx has very little actual work to do.


server {
listen 80;
server_name sitename.com www.sitename.com;
access_log /var/log/nginx/sitename-access.log;
error_log /var/log/nginx/sitename-error.log;
# serve static files
location / {
root /www/sitename.com/html;
index index.php index.html index.htm;

# this serves static files that exists without
# running other rewrite tests
if (-f $request_filename) {
expires 30d;
break;
}

# this sends all-non-existing file or directory requests to index.php
if (!-e $request_filename) {
rewrite ^(.+)$ /index.php?q=$1 last;
}
}

location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /www/sitename.com/html$fastcgi_script_name;
include fastcgi_params;
}
}

The fastcgi_param setting controls which script is executed, based upon the root path of the site being accessed. All of the requests parameters are passed through to PHP, and once the configuration is started up I didn’t miss Apache one little bit.

Improvements
My next step will be to put a varnish server in front of nginx. Since the majority of my site traffic comes from search engine results where a user has not yet been registered to the site or needs refreshed content, Varnish can step in and serve a fully cached version of my pages from memory far faster than FastCGI can render the WordPress code. I’ll experiment with this setup in the coming months and post my results.

January 25th, 2012

Now that WebOS is being made open source, HP has released a new version of the Enyo JavaScript framework. Whereas the first version of the framework only supported Webkit-based environments (like the HP Touchpad, or Safari or Chrome), the newer version has expanded support for Firefox and IE9 as well. Developers who created apps with the old framework will have to wait a little while longer before all of the widgets and controls from Enyo 1.0 are ported over.

What does this mean for app developers? Now that Enyo is open-source, it means applications built on the platform will run on Android and iOS. But it’s not a disruptive technology – both Android and iOS have supported HTML5 applications for quite awhile; HP will be competing against mature frameworks like jQuery Mobile.

As a WebOS enthusiast I am definitely going to put some time into continuing my explorations of Enyo, but it’s getting harder and harder to justify the investment. My Pre is getting pretty old at this point, and hardware manufacturers have yet to express interest in making new devices to take advantage of WebOS. If I end up switching to Android with my next hardware purchase, it’s going to shift my priorities away from Enyo and its brethren.

January 14th, 2012
Mimbo - A Friendly Robot
Creative Commons License photo credit: langfordw

If you don’t want a search engine to read some or all of the files on your site, you can create a robots.txt file. (Looking through the blog archive, I realize I’ve never gone through the construction and contents of that important file, so this is a promise to one day return and fix that!)

When you want the opposite – accessible pages and author credit, create a humans.txt file. Although not an “official” standard, it is a fun way to acknowledge the (sometimes many) hardworking individuals behind the creation of a web site.

An example is:

/* TEAM */
Leader: Mike Wilson
Site: http://www.alwaysgetbetter.com
Twitter: HawkWilson
Location: Ottawa, ON

/* THANKS */
Seth Godin: http://www.sethgodin.com
Steve Pavlina: http://www.stevepavlina.com
Phil Haack: http://haacked.com

/* SITE */
Last Update: Jan 14, 2012
Standards: HTML5, CSS3
Software: WordPress

In most cases, you would want to include at least a TEAM and SITE section. Clearly the exact fields are left to your imagination, but it’s a very simple way to acknowledge the people who helps (directly or in spirit) a site to get to fruition.

For more information about humans.txt, check out the initiative’s home page at http://humanstxt.org/.

November 7th, 2011

The Node.js team has released version 0.6. Although much of the core was re-written, the most noteworthy change has to be the support for native Windows installation. Whereas previously it was possible to run node.js on Windows using Cygwin, the native compilation means its performance will be comparable to Linux equivalents.

Other important improvements include upgrading of the V8 engine and multi-process load balancing. Much more information can be found on the node blog.

November 4th, 2011

Hopefully when you do web work, you’re not developing code on the same server your users are accessing. Most organizations have at least some kind of separation for their development and production code, but it’s possible to go far further. Separating environments allows you to achieve multiple threads of continuous integration for all kinds of cool.

These normally break down as follows:

Development
Working code copy. Changes made by developers are deployed here so integration and features can be tested. This environment is rapidly updated and contains the most recent version of the application.

Quality Assurance (QA)
Not all companies will have this. Environment for quality assurance; this provides a less frequently changed version of the application which testers can perform checks against. This allows reporting on a common revision so developers know whether particular issues found by testers has already been corrected in the development code.

Staging/Release Candidate
This is the release candidate, and this environment is normally a mirror of the production environment. The staging area contains the “next” version of the application and is used for final stress testing and client/manager approvals before going live.

Production
This is the currently released version of the application, accessible to the client/end users. This version preferably does not change except for during scheduled releases. There may be differences in the production environment but generally it should be the same as the staging environment.

Having separation between the different environments is not tricky, but managing your data environment can be. There are, of course, all kinds of ways to solve the problem.

May 9th, 2011

Suppose we are building a Facebook application and have a variable called fb.appId containing our Application’s ID. We want to use that to initialize an FBJS call, but obviously don’t want to hard-code it into our page’s template.

Using the template engine in Play! framework, we can make direct calls to the underlying Java framework as long as we use the full namespace path. Our Facebook Application Id is accessible like this:


${play.Play.configuration.get("fb.appId")}

If we’re making a lot of configuration calls, we can simplify our lives by aliasing the namespace path:


%{
cf = play.Play.configuration
}%
${cf.get("fb.appId")}

Conditional Statements
Let’s go a step further. Suppose we have Google Analytics and only want the JavaScript to run when our site has been deployed to production (I covered a similar technique earlier this year using Ruby on Rails).


#{if play.Play.configuration.get("application.mode") == 'PROD'}
GOOGLE ANALYTICS CODE - WILL ONLY DISPLAY IN PRODUCTION
#{/if}

April 19th, 2011
Tortoise
Creative Commons License photo credit: Eric Kilby

Why is my website loading so slowly?!?

There are a few common culprits behind website speed issues. When diagnosing problems, the best bet is to start at the worst performers and move up. Some suggestions, in order from slowest to fastest, are:

1. Internet Traffic
If your web page is downloading anything over the internet during each page request, stop right now. This is the most expensive operation you can perform. Example: Downloading a photo from Flickr and loading it into memory in order to determine its width and height dimensions.

2. Network Traffic
Local network traffic is generally very fast, but still involves transmitting information outside your computer. In some cases, such as web clusters with a shared session cache, the network performance cost is worth it for the overall application.

3. Database
Databases are fast, particularly when the data you need is already stored in a memory cache – which you generally can’t control. When paired with a key-value memory store like memcache, the majority of your database calls can come straight from memory.

4. Disk I/O
Even with the incredible access times found in today’s hard drives, reading and writing from the disk is an expensive operation (and why databases lose points, except for their memory caching abilities). Sometimes reading from disk is the better choice – YMMV.

5. Script Caching
Implement a tool like xcache (PHP). This will keep your code in binary bytecode format which is much faster to execute since it doesn’t have to be re-processed by the web server.