Archive for the 'Web Development' Category

Aug 13 2007

Introducing the YUI Compressor

Published by Julien Lecomte under Web Development

Is there a need for a new JavaScript minifier?

Yahoo's YUI Compressor

According to Yahoo!’s Exceptional Performance Team, 40% to 60% of Yahoo!’s users have an empty cache experience and about 20% of all page views are done with an empty cache (see this article for more information on browser cache usage) This fact outlines the importance of keeping web pages as lightweight as possible. Improving the engineering design of a page or a web application usually yields the biggest savings. After that come many different techniques such as minification of the code, HTTP compression, etc. In terms of code minification, the most widely used tools to minify JavaScript code are Douglas Crockford’s JSMin and the Dojo compressor. Both tools however have pitfalls. JSMin, for example, does not yield optimal savings (due to its simple algorithm, it must leave many line feed characters in the code in order not to introduce any new bugs) The Dojo compressor, on the other hand, does a better job at compacting code (it obfuscates local variables) but is unsafe and potentially introduces bugs if you are unaware of its limitations.


What is the YUI Compressor?

The YUI Compressor is a new JavaScript minifier. Its level of compaction is higher than the Dojo compressor, and it is as safe as JSMin. Tests on the YUI library have shown savings of about 18% compared to JSMin and 10% compared to the Dojo compressor (these respectively become 10% and 5% after HTTP compression)

How does it work?

The YUI Compressor is written in Java (requires Java >= 1.4) and relies on Rhino to tokenize the source JavaScript file. It starts by analyzing the source JavaScript file to understand how it is structured. It then prints out the token stream, replacing all local symbols by a 1 (or 2, or 3) letter symbol wherever such a substitution is appropriate (in the face of evil features such as eval or with, the YUI Compressor takes a defensive approach by not obfuscating any of the scopes containing the evil statement). The YUI Compressor is open-source, so don’t hesitate to look at the code to understand exactly how it works.

Where can I get it?

An archive containing both source and binary is available for download on this site.

How do I run it?

java -jar yuicompressor-1.0.jar
    [-h, --help] [--warn] [--nomunge]
    [--charset character-set] [-o outfile] infile

The following command line for example:

java -jar yuicompressor-1.0.jar myfile.js

will minify the file myfile.js and output the file myfile-min.js. For more information on how to use the YUI Compressor, please refer to the documentation included in the archive.

Limitations

Unlike JSMin, the YUI Compressor is slow and cannot be used for on-the-fly code minification (see minify for a PHP implementation of JSMin by Ryan Grove, another Yahoo! engineer, that does on-the-fly JavaScript minification among other things)

Has Yahoo!’s official position on obfuscation changed?

Douglas Crockford wrote an interesting article last year on minification vs. obfuscation. While that article still holds true, the YUI Compressor actually represents a 3rd way, in which code compaction does not carry the risk of introducing new bugs. The YUI Compressor is currently considered as a replacement for JSMin to compact the entire YUI library.

Feedback appreciated

The YUI Compressor is still a fairly new tool, so your feedback is well appreciated. Don’t hesitate to drop me a line if you find a bug, or think an important feature is missing. I will make updates available on this site, so watch for posts related to the YUI Compressor on this blog. This software belongs to the community, so it’s up to the community to make it better!

Additional notes

  • Do not hesitate to use the --warn option. The YUI Compressor will warn you if it finds anything that seems abnormal with your code, or that might reduce the level of compression.
  • Keep as little of your code as possible in the global scope. This has 2 benefits:
    1. You’ll get a better level of compression since the YUI Compressor does not obfuscate global symbols (which would make it unsafe)
    2. You won’t pollute the global object (see this article)

69 responses so far

Aug 07 2007

YUI-based Image Magnifier Widget

Published by Julien Lecomte under Web Development

I wrote a prototype YUI-based image magnifier widget that makes use of VML on Internet Explorer and the Canvas tag on all the other A-grade browsers. Attached is a screenshot.

To instantiate the widget, include the following source files in your web page (requires YUI >= 2.3)


<!-- CSS -->
<link rel="stylesheet" type="text/css" href="image-magnifier.css">

<!-- Dependencies -->
<script src="yahoo-dom-event.js"></script>
<script src="dragdrop-min.js"></script>

<!-- Image cropper source file -->
<script src="image-magnifier-min.js"></script>

Then, place an image on your page:

<img src="myImage.jpg" id="myImageId">

Finally, instantiate the widget:

<script>
    new YAHOO.widget.ImageMagnifier("myImageId", "magnified.jpg");
</script>

Although this prototype is not extremely polished, it should work fairly well right out of the box. Here is a live demo of the image magnifier widget (drag the lens around). You can also download an archive containing all the necessary source code.

2 responses so far

Jul 28 2007

Introducing iSearch, A Search Page Optimized For The iPhone

Published by Julien Lecomte under Web Development

I hacked a search page optimized for the iPhone. It uses the Yahoo! Search API and bits of Joe Hewitt’s iUI library. The address is:

http://www.julienlecomte.net/isearch/

Developing a web application for the iPhone is actually easier than traditional web development because of the fact that you are designing for a specific browser (Safari) running on a specific device with a known resolution (320 x 480)

I hope you’ll find this page useful. Comments and constructive criticism are welcome as always!


No responses yet

Jul 26 2007

Exposing Extension Functionality to Web-Page Javascript

Published by Julien Lecomte under Web Development

In this article, I describe how to implement a scriptable XPCOM Component. This type of component exposes some extra functionality to untrusted web-page JavaScript running inside a Gecko-based browser such as Firefox. The implementation itself will be done in JavaScript.


Before we start

First of all, you will need to download a recent version of the Mozilla source code. The Mozilla source code can be obtained either by downloading a source archive, or by using a CVS (source control) client. For our project, downloading a source archive is recommended, but if you wish to go down the CVS road, you should read this MDC article first. In my case, I simply downloaded a tarball of the Firefox 2.0.0.5 source code. Untar it using

tar xjfv <source-file.tar.bz2>

XPCOM uses its own variant of the CORBA OMG Interface Definition Language (IDL) called XPIDL. You will need a special compiler to process your XPIDL files. You can build the compiler yourself (the source for the compiler is under mozilla/xpcom/typelib/xpidl). If you’re on Windows (XP or Vista), you can simply download a statically linked Windows binary here.

Define the component interface

Let’s define the interface of our component. I will not delve into details about the actual XPIDL syntax. You can find more information on this here. This interface resides in a file named nsSimple.idl. The GUID was generated using Microsoft’s GUIDGen.exe.

#include "nsISupports.idl"

[scriptable, uuid(B2A56E5E-CF18-4a8e-8EE9-CE228098516A)]
interface nsISimple : nsISupports {

    // Version string. Readonly!
    readonly attribute string version;

    // Dummy test function.
    string doSomething( in string value );
};

Compile the interface file

This file must be compiled using the XPIDL compiler using the following command line. This should generate a file name nsISimple.xpt.

xpidl -m typelib -w -v -I <path-to-mozilla-source>/mozilla/xpcom/base -o nsISimple nsISimple.idl

Interface implementation

Once you have successfuly created an interface file that publicly defines the component’s methods and attributes, the next step is to implement those methods and attributes in a separate source file named nsSimple.js. The nsSimple object implements the nsISimple interface of course, but also the nsISupports interface (because nsISimple inherits from it) and the nsIClassInfo interface (this is needed because we are writing a scriptable component).

Component registration and instantiation

The second half of the file nsSimple.js contains the code necessary for the component instantiation and automatic registration. This code is fairly generic and does not change much from one component to another.

Install the component and test it

Copy the two files nsISimple.xpt and nsSimple.js to

<path-to-your-firefox-install>/components/

and restart Firefox. Create a simple HTML file as follows:

<html>
  <head>
    <title>XPCOM test page</title>
  </head>
  <body>
    <script>

if (window.simpleObj) {
    alert(simpleObj.version);
    alert(simpleObj.doSomething("foo"));
}
    </script>
  </body>
</html>

and open it up in Firefox. You should see a couple of alerts.

Downloads

I put together a complete archive that contains all the necessary files.

4 responses so far

Jul 24 2007

YUI-based Image Cropper Widget

Published by Julien Lecomte under Web Development

I wrote a YUI-based image cropper widget that allows you to easily select which region of an image you’d like to crop. This widget works on all A-grade browsers in both standards mode and quirks mode. Attached is a screenshot.

To instantiate the widget, include the following source files in your web page (requires YUI >= 2.3)


<!-- CSS -->
<link rel="stylesheet" type="text/css" href="image-cropper.css">

<!-- Dependencies -->
<script src="yahoo-dom-event.js"></script>
<script src="dragdrop-min.js"></script>

<!-- Image cropper source file -->
<script src="image-cropper-min.js"></script>

Then, place an image on your page:

<img src="myImage.jpg" id="myImageId">

Finally, instantiate the widget:

<script>
    var cropper = new YAHOO.widget.ImageCropper("myImageId");
</script>

You can then retrieve the geometry of the crop region by calling:

var region = cropper.getCropRegion();

This should work right out of the box. You can also pass an optional configuration object to the constructor to set the initial geometry of the crop region as well as a constraint on the ratio width / height. For more information, please refer to the documentation inline in the source code.

Here is a live demo of the image cropper widget. You can also download an archive containing all the necessary source code.

30 responses so far

Jul 23 2007

IE6, CSS Sprites and Alpha Transparency

Published by Julien Lecomte under Web Development

Image slicing using CSS, also known as CSS sprites, is quickly becoming a very popular technique in web development as it can dramatically improve the performance of a site by reducing the number of HTTP requests (see this article for more information). Alpha transparency is also quickly becoming a favorite feature among web designers: nice transparent gradients, no more jagged edges, etc. What’s not to like?

The good news is that almost all browsers in the A-grade category support alpha transparency via the use of PNG. The bad news is that IE6 does not support alpha transparency natively. It requires the use of a filter involving the AlphaImageLoader activeX, which does not support background repeat or positioning, the heart of the traditional CSS sprites technique.

The traditional CSS sprites technique relies on the ability to control the background properties of an appropriately sized HTML element, masking out all but the needed part of the larger background image. I recently heard of another technique that instead relies on clipping. Here is the recipe:

  • Create a block element (a DIV for example)
  • Set its size to the same size as the large image used for the sprite.
  • Set its background image.
  • Clip it to show only a small portion of the sprite.
  • Finally, position it appropriately.

The following example masks all but a 50 x 50 px portion of the master image:

#myDiv {
   width:400px; height:300px;
   background:url(sprite.png);
   clip:rect(100px,250px,150px,100px);
   position:absolute;
}

Unlike the traditional CSS sprites technique, this new technique can be used with the AlphaImageLoader filter to create alpha transparent sprites on IE6. Simply replace the line:

background:url(sprite.png);

with:

filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(
    src="sprite.png", sizingMethod="scale");

This technique does not offer any support for background repeat. However, if you only use patterns that can be stretched either horizontally or vertically, you can still use this technique. I put together a complete demo to illustrate this.

7 responses so far

« Prev