a weblog by Ed Eliot

Pressure is nothing more than the shadow of great opportunity. - Michael Johnson

This weblog is the online home of Ed Eliot, an experienced developer, architect and technical manager based in London, UK.

Entries for April 2008

You are currently viewing posts from the archive. Click here to return to the latest posts.

  • Mobile Browser Concurrency Test

    9 years, 1 month ago

    Cloud Four, specialists in mobile development, have set up a research project aimed at finding out more about the capabilities of mobile devices to determine the performance implications of building web sites for the wide variety of devices available. Inspired by desktop browser research, such as that carried out by Yahoo!'s Exceptional Performance Team, they're particularly interested in finding out the following information:

    • What is the number of concurrent http connections that the mobile browser supports both per domain and overall?
    • Does the mobile browser support gzip or other methods for reducing the size of pages?
    • Does the mobile browser support caching if you set the Expires header far into the future?

    They plan to publish the information under a creative commons license to allow mobile web developers to benefit from their findings.

    You can help them by running their test suite from your mobile phone's web browser.

  • Problems building MySQLdb on Mac OS X 10.4 (Power PC)

    9 years, 2 months ago

    Over the last couple of days I've been trying to build and install MySQLdb on my PowerPC based Mac Mini with very little success. I got the following message followed by a ton of type errors:

    Compiling with an SDK that doesn't seem to exist: 
    Please check your Xcode installation

    I tried reinstalling Xcode Tools to see if it would solve the problem but with no success. Anyway after searching around it turns out that the installer doesn't add a required SDK package which you can find in Xcode Tools->Packages on the install disk. It's called MacOSX10.4.Universal.pkg.

    I (and others) have not had similar problems on Intel based Macs running Tiger or Leopard so I'm guessing it's specific to the PPC install.

    With that out of the way - on with Django.

  • Automatic versioning of CSS, JavaScript and Images

    9 years, 2 months ago

    See comments for important information about HTTP caching issues with URLs containing query string parameters.

    When including CSS and JavaScript resources in your pages you should version file paths and update these version numbers every time the files change. This is necessary as a visitor's browsers may, depending on settings, continue to cache files even after a change. This can result in a mismatch between your HTML and these external resources which may cause rendering or functionality problems. One will likely encounter similar caching issues with images.

    So if we work on the basis that we should version these resources and that changing version numbers forces the browser to reload those resources then we can actually gain large performance improvements by explicitly instructing the browser to cache them for an extended period of time (say 10 years) thereby limiting the number of times the browser goes back to check for fresh copies.

    This can be achieved fairly easily within the virtual host settings of your Apache conf file. Simply add the following directives within the relevant virtual hosts section substituting /assets/ with the file path corresponding to the location where your CSS, JavaScript and images are stored.

    1. <Location /assets/>
    2. ExpiresActive On
    3. ExpiresDefault "access plus 10 years"
    4. </Location>

    If you have the mod_deflate module installed then you can gain an additional performance benefit by gzipping CSS and JavaScript resources to reduce the amount transmitted down the wire.

    1. <Location /assets/>
    2. ExpiresActive On
    3. ExpiresDefault "access plus 10 years"
    4. SetOutputFilter DEFLATE
    5. </Location>

    These directives can also be added to an appropriately placed .htaccess file but as Stuart explains there are performance implications with this method so it should only be chosen if you don't have access to your Apache conf files (perhaps because you're using shared hosting).

    Applying both these settings covers off a couple of recommendations made by Yahoo!'s YSlow performance testing tool so not only will you end up with a faster site but you'll also improve your YSlow rating by a grade or two.

    Of course manually versioning files is a pain, it's repetitive and as Stuart is always reminding me manually repetitive tasks should be eliminated wherever possible. In the past I wrote a script which automatically merges CSS or JavaScript files and versions the combined output. Here's some simpler code which versions individual files based their last modified date - every time the file is updated it's version number updates accordingly.

    1. <?php
    2. class Version {
    3. private static $aLookup = array();
    4. public static function Get($sFilename) {
    5. if (!array_key_exists($sFilename, self::$aLookup)) {
    6. $sRealPath = realpath($_SERVER['DOCUMENT_ROOT'] . "/$sFilename");
    7. if (file_exists($sRealPath) && ($iTimestamp = filemtime($sRealPath))) {
    8. self::$aLookup[$sFilename] = $iTimestamp;
    9. $sFilename .= "?v=$iTimestamp";
    10. }
    11. } else {
    12. $sFilename .= '?v='.self::$aLookup[$sFilename];
    13. }
    14. return $sFilename;
    15. }
    16. public static function GetLink($sFilename) {
    17. return '<link rel="stylesheet" type="text/css" href="'.self::Get($sFilename).'">';
    18. }
    19. public static function GetScript($sFilename) {
    20. return '<script type="text/javascript" src="'.self::Get($sFilename).'"></script>';
    21. }
    22. public static function GetImage($sFilename, $iWidth, $iHeight, $sAlt = '') {
    23. return sprintf('<img src="%s" width="%d" height="%d" alt="%s">', self::Get($sFilename), $iWidth, $iHeight, $sAlt);
    24. }
    25. }
    26. ?>

    Download plain text version (Updated version to fix HTTP caching issues)

    Using it is pretty simple - wrap the required function around the file path you'd normally have supplied to link, script or img tags.

    1. <link rel="stylesheet" type="text/css" href="<?php echo Version::Get('/css/dark.css'); ?>">

    In fact it's even easier than that - I've also provided some wrapper functions which make outputting link, script and img tags a little bit easier. The example above could be written more simply as follows:

    1. <?php echo Version::GetLink('/css/dark.css'); ?>