Monthly Archives: January 2010

Browser Testing for Mobile Web Applications

Posted by Mike Brittain on January 31, 2010
Misc / Comments Off on Browser Testing for Mobile Web Applications

Developers working on mobile web apps need to be able to test their apps or sites in all of the major mobile platforms.  Unfortunately, there are not a lot of good resources online for how to go about this.  You could pay for a service from a mobile testing company, like DeviceAnywhere, who provides access to a wide selection of real devices (using a virtual client).  Or you could go the free route by installing a variety of SDKs and mobile phone simulators.

Base Setup

I’m developing on a Mac.  Many of these emulators are Windows-specific.  Additionally, this could end up being a lot of work to setup, so putting all of these tools onto a Windows virtual machine will let me move the VM to another machine in the future and save me from reinstalling from scratch.  On my Mac I’m running Parallels Desktop with a copy of Windows XP.

The only exception is the iPhone SDK which includes a simulator for the iPhone.  The iPhone SDK is only available for installation on the Mac OS and I’ll be leaving it out of the instructions below.  I also haven’t installed or tested the 3.2 (beta) yet which includes an iPad simulator.

Java

Big surprise that Java is used for some of these SDKs and simulators, so we might as well get started by installing the JDK and runtime if you don’t already have it installed.  You should be able to download a copy of the JDK from here:

http://java.sun.com/javase/

I grabbed “JDK 6 Update 18”.

Android

Download the Android SDK from Google’s Android Developer site and run the enclosed SDK Setup program.

Unzip the .zip package you download and put in a location you want to keep the files (perhaps within Program Files) and then run the SDK Setup program.

In the “Installed Packages” section of the setup program, click “Update All…” to download the platforms and APIs that will be run by the SDK.

To create an emulator for a specific version of the Android OS, select the “Virtual Devices” option, then click the “New…” button.  In the dialog box that opens, enter a name for your emulator and select a target OS (e.g. “Android 2.0.1”).  Then click the “Create AVD” button.  Select your new emulator from the list and click the “Start” button.  When the emulator starts you’ll find an icon for “browser” on the main screen.

Symbian

In the past, I have setup Symbian emulators and SDKs to do local testing.  When I returned to their site to download new software I was pleased to find that they now provide a service for accessing virtual devices over the Internet using a Java application.  Visit http://apu.ndhub.net/ to register and access a wide selection of devices.

Easy!

BlackBerry

BlackBerry simulators for various models and OS versions can be downloaded from their developer site.  Each simulator is downloaded as its own installer package.  So download all of the  emulators you want to test (Storm, Bold, Pearl, etc.) and run their installers.

http://na.blackberry.com/eng/developers/resources/simulators.jsp

This seems simple enough, but if you start up one of these simulators and open the web browser you’ll quickly find that you’re missing a critical piece: network access.  To access the web from these emulators you need to also download the MDS Services Simulator package.  Find a link for this download from the resources page:

http://na.blackberry.com/eng/developers/resources/

Also note that BlackBerry makes available some documentation specific to web application development for the BlackBerry platform.  You can find these resources at the address below (registration required):

http://na.blackberry.com/eng/developers/browserdev/

Palm webOS SDK

The Palm SDK includes a web browser within its phone simulator which is useful for testing the browser that runs on the Palm Pre and Palm Pixi.

Go to Palm’s developer site and look for a button or link to download the SDK.

The emulator runs within Sun’s VirtualBox software.  There is a link from the Palm download site for downloading VirtualBox.  Follow the instructions and install VirtualBox first.

Next, download and install the webOS SDK.

Once you’ve completed the installation, you can start up Palm emulator from your Start Menu: Programs > Palm > SDK > Palm Emulator.

When you run VirtualBox, it may prompt you to download an updated version.  The Palm Emulator (as of January 30, 2010) will not run on the latest version of Virtual Box.  Stick to the version that you download from the Palm Developer web site (3.0.10).

Wrap up

This should get your started with a testing environment for a few of the top mobile browsers on the market today.

If you’ve got other tips to share about testing mobile browsers, share them in the comments below.

Tags: , , , , , , , , , , , ,

A Web Without Flash?

Posted by Mike Brittain on January 31, 2010
WWW / 1 Comment

Scoble has an interesting post asking Can Flash Be Saved? His central point is that developers will make use of whatever technologies that are widely available to their users which, of course, makes sense.  He draws an analogy between the growth of the iPhone OS, which does not include Flash, and Firefox, which does not include Microsoft-centric technologies like ActiveX.  Within the first years that Firefox began to steal share from Internet Explorer in the consumer market, developers changed the manner that they coded their sites by embracing Web Standards.

The interesting thing about that change was that Firefox’s growth was fairly slow outside of the developer community.  Many developers loved Firefox, but it took a few years for the general public to get hip to the browser.  I would have to say that the iPhone has far higher brand recognition and uptake.  You could attribute this to Apple’s strong marketing machine.

Mobile web browsing is still a small market compared to desktop browsers.  It’s a tiny, but growing market that can’t be ignored.  I believe that in just a few years mobile Internet services (including networked apps)  will be more important than the desktop Internet for communication, entertainment, and consuming information.  Devices like the iPhone and iPad are driving this forward.  Android is growing and finally seeing a wider number of devices offering Google’s mobile OS.  BlackBerry is a widely used platform, but it doesn’t contribute much to mobile web usage (yet).

If these (iPhone and Android) operating systems become the leading platforms in the mobile space, developers will build sites and apps based on the technologies available across them, namely HTML5 support that is part of the WebKit engine.  If Flash continues to be blockaded from the iPhone OS, developers will certainly look to other technologies to replace it.

Tags: , , , , ,

Batch Processing your JPEGs with jpegtran

Posted by Mike Brittain on January 27, 2010
WWW / 1 Comment

UPDATE: Please read my post about a new version of this image processing script.

Stoyan Stefanov wrote up a nice post last year about installing jpegtran on a Mac or Unix/Linux system so that you can run optimizations on your JPEG files.  His conclusion on jpegtran is that you can save about 10% on your JPEG file sizes for “about a minute of work, or less.”

Sounds great!  I looked it over and, indeed, jpegtran cuts some of the junk out of the JPEG files I tested.  The only holdup, however, is that at CafeMom we have a few thousand JPEG files in our site code, and that number grows every week.  The only reasonable solution was to automate this process.

The following Perl script should work right out of the box for you, assuming you already have jpegtran installed on your server or shared hosting account.

optimize_jpegs.pl

#!/usr/bin/perl

#
# Lossless optimization for all JPEG files in a directory
#
# This script uses techniques described in this article about the use
# of jpegtran: http://www.phpied.com/installing-jpegtran-mac-unix-linux/
#

use strict;
use File::Find;
use File::Copy;

# Read image dir from input
if (!$ARGV[0]) {
    print "Usage: $0 path_to_images\n";
    exit 1;
}
my @search_paths;
my $images_path = $ARGV[0];
if (!-e $images_path) {
    print "Invalid path specified.\n";
    exit 1;
} else {
    push @search_paths, $ARGV[0];
}

# Compress JPEGs
my $count_jpegs = 0;
my $count_modified = 0;
my $count_optimize = 0;
my $count_progressive = 0;
my $bytes_saved = 0;
my $bytes_orig = 0;

find(\&jpegCompress, @search_paths);

# Write summary
print "\n\n";
print "----------------------------\n";
print "  Sumary\n";
print "----------------------------\n";
print "\n";
print "  Inspected $count_jpegs JPEG files.\n";
print "  Modified $count_modified files.\n";
print "  Huffman table optimizations: $count_optimize\n";
print "  Progressive JPEG optimizations: $count_progressive\n";
print "  Total bytes saved: $bytes_saved (orig $bytes_orig, saved "
       . (int($bytes_saved/$bytes_orig*10000) / 100) . "%)\n";
print "\n";

sub jpegCompress()
{
    if (m/\.jpg$/i) {
        $count_jpegs++;

        my $orig_size = -s $_;
        my $saved = 0;

        my $fullname = $File::Find::dir . '/' . $_;

        print "Inspecting $fullname\n";

        # Run Progressive JPEG and Huffman table optimizations, then inspect
		# which was best.
        `/usr/bin/jpegtran -copy none -optimize $_ > $_.opt`;
        my $opt_size = -s "$_.opt";

        `/usr/bin/jpegtran -copy none -progressive $_ > $_.prog`;
        my $prog_size = -s "$_.prog";

        if ($opt_size && $opt_size < $orig_size && $opt_size <= $prog_size) {
            move("$_.opt", "$_");
            $saved = $orig_size - $opt_size;
            $bytes_saved += $saved;
            $bytes_orig += $orig_size;
            $count_modified++;
            $count_optimize++;

            print " -- Huffman table optimization: "
				. "saved $saved bytes (orig $orig_size)\n";

        } elsif ($prog_size && $prog_size < $orig_size) {
            move("$_.prog", "$_");
            $saved = $orig_size - $prog_size;
            $bytes_saved += $saved;
            $bytes_orig += $orig_size;
            $count_modified++;
            $count_progressive++;

            print " -- Progressive JPEG optimization: "
				. "saved $saved bytes (orig $orig_size)\n";
        }

        # Cleanup temp files
        if (-e "$_.prog") {
             unlink("$_.prog");
        }
        if (-e "$_.opt") {
            unlink("$_.opt");
        }
    }
}

How to use this script

For starters, copy this script into a text file (such as optimize_jpegs.pl) and set it to be executable (chmod 755 optimize_jpegs.pl).

After the script is setup, pull the trigger…

$ ./optimize_jpegs.pl  /path/to/your/images/dir

That’s it.  The output should look something like this:

Inspecting ./phpXkWlcW.jpg
 -- Progressive JPEG optimization: saved 1089 bytes (orig 13464)
Inspecting ./phpCnBRri.jpg
 -- Progressive JPEG optimization: saved 1155 bytes (orig 34790)
Inspecting ./phpx6G3lD.jpg
 -- Progressive JPEG optimization: saved 742 bytes (orig 11493)

...

----------------------------
  Sumary
----------------------------

  Inspected 21 JPEG files.
  Modified 21 files.
  Huffman table optimizations: 0
  Progressive JPEG optimizations: 21
  Total bytes saved: 63918

Wrap up

Many thanks to Stoyan for his post on jpegtran, and all of the other performance ideas he has been sharing on his blog.  This script was easy to write, knowing the right techniques to be running on our images.

optimize_jpegs.pl took about a minute or so to run on our thousands of images and shaved a few megabytes from all of those files combined.  This will be a great savings for us.

Tags: , , , ,

Guess which version?

Posted by Mike Brittain on January 26, 2010
Microsoft / Comments Off on Guess which version?

Just what do you suppose I should make of this user-agent string?  It’s real.  I found it in my logs today.

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; GTB6.3; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)

Seriously.  We see “MSIE 7.0” in there, which you would initially think of as Internet Explorer 7.  But of course, since we also see “Trident/4.0”, we can deduce that this is Internet Explorer 8 running in Compatibility View.  So what the hell is “MSIE 6.0” still doing in here?

P.S. Thanks for including the version of .NET CLR… 6 different ways. That certainly is helpful.

Tags: , ,

Choosing a CDN

Posted by Mike Brittain on January 15, 2010
WWW / 1 Comment

I thought this was a good article covering 8 Things to Consider When Choosing a CDN.  It’s worth a read.

The only bit I would disagree with is that this reads a bit too video-centric for me.  It felt like the main argument for using a CDN is that you don’t have enough bandwidth at your own data center to handle all of the requests being made to your servers.

I use CDNs for delivering static objects like images, CSS, and JavaScript.  An additional consideration I have is how fast cached objects will reach different locations across the country or around the world.  I’m dependent (as most sites are) on one central data center where my pages are being generated.  Every page view needs to make that trip over the network from the browser to my data center.  However, if the 20-100 successive objects can be requested from a regional CDN node, the performance in the end-user’s browser will be much better than if every request made a full trip across the country.

Tags: , ,