Tuesday, September 22nd, 2009
Category: Google, Mobile, Tip
Bikin Chiu of the Gmail Mobile team picks up the HTML5 series with a piece on reducing startup latency.
It starts off by talking about lazily loading code via the old favorites of adding a <script> to the DOM, or XHR+eval, but then it gets beyond the typical and discusses the nuance of mobile + offline caching. The hack that is used, is another oldie.... which is to hide the script and eval it later:
For an HTML 5 application that takes advantage of the application cache to reduce startup latency and to serve the application offline, there are a few caveats one should be aware of. Mobile networks have decent bandwidth, but poor round trip latency, so listing each module as a separate resource in the manifest incurs quite a bit of extra startup latency when the application cache is empty. Also, if one of the module resources fails to be downloaded by the application cache (e.g. disconnected from network), additional error handling code needs to be written to handle such a case. Finally, applications today have no control when the application cache decides to download the resources in the manifest (such a feature is not defined in the current specification of the draft standard). Typically, resources are downloaded once the main page is loaded, but that's not an ideal time since that's when the application requests user data.
To work-around these caveats, we found a trick that allows you to bundle all of your modules into a single resource without having to parse any of the JavaScript. Of course, with this strategy, there is greater latency with the initial download of the single resource (since it has all your JavaScript modules), but once the resource is stored in the browser's application cache, this issue becomes much less of a factor.
To combine all modules into a single resource, we wrote each module into a separate script tag and hid the code inside a comment block (/* */). When the resource first loads, none of the code is parsed since it is commented out. To load a module, find the DOM element for the corresponding script tag, strip out the comment block, and eval() the code. If the web app supports XHTML, this trick is even more elegant as the modules can be hidden inside a CDATA tag instead of a script tag. An added bonus is the ability to lazy load your modules synchronously since there's no longer a need to fetch the modules asynchronously over the network.
On an iPhone 2.2 device, 200k of JavaScript held within a block comment adds 240ms during page load, whereas 200k of JavaScript that is parsed during page load added 2600 ms. That's more than a 10x reduction in startup latency by eliminating 200k of unneeded JavaScript during page load! Take a look at the code sample below to see how this is done.
HTML:
-
-
-
// Make sure you strip out (or replace) comment blocks in your JavaScript first.
-
/*
-
JavaScript of lazy module
-
*/
-
</script>
-
-
-
function lazyLoad() {
-
var lazyElement = document.getElementById('lazy');
-
var lazyElementBody = lazyElement.innerHTML;
-
var jsCode = stripOutCommentBlock(lazyElementBody);
-
eval(jsCode);
-
}
-
</script>
-
In the future, we hope that the HTML5 standard will allow more control over when the application cache should download resources in the manifest, since using comments to pass along code is not elegant but worked nicely for us.
Wednesday, September 2nd, 2009
Category: Tip, Utility
FireCrystal is a Firefox extension that helps designers and programmers alike figure out how interactive behaviors on the web work. FireCrystal allows users to record and rewind their interactions with web pages while showing the relevant code.
Wednesday, July 29th, 2009
Category: CSS, Tip
Jonathan Snook has posted a nice nugget on text rotation with CSS that takes a nice bit of markup like this:
HTML:
-
-
<div class="example-date">
-
<span class="day">31
</span>
-
<span class="month">July
</span>
-
<span class="year">2009
</span>
-
</div>
-
and converts it to:

all via the CSS:
CSS:
-
-
-webkit-transform: rotate(-90deg);
-
-moz-transform: rotate(-90deg);
-
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
-
Yup, even IE.
Thursday, July 2nd, 2009
Category: Tip, Utility
Paul Baukaus linked to jsescape, a little form that shows escaping and unescaping across a number of encodings.

Andrea Giammarchi had his own post on encodings in a different way.... as he talked about
en-code which you can check out in action here on the page that lets you do simple encodings, especially for source code, in short order.
Friday, April 24th, 2009
Category: CSS, Tip
Paul Irish tries not to use CSS browser hacks anymore and instead "uses IE's conditional comments to apply classes to the body tag, but he put up a concise list of browser specific hacks he has used:
CSS:
-
-
/***** Selector Hacks ******/
-
-
/* IE 6 and below */
-
* html #uno { color: red }
-
-
/* IE 7 and below */
-
*:first-child+html #dos { color: red }
-
-
/* IE 7 and modern browsers */
-
html>body #tres { color: red }
-
-
/* Modern browsers (not IE 7) */
-
html>/**/body #cuatro { color: red }
-
-
/* Opera 9.27 and below */
-
html:first-child #cinco { color: red }
-
-
/* Safari */
-
html[xmlns*=""] body:last-child #seis { color: red }
-
-
/*safari 3+, chrome 1+, opera9+, ff 3.5+ */
-
body:nth-of-type(1) #siete { color: red }
-
-
/* safari 3+, chrome 1+, opera9+, ff 3.5+ */
-
body:first-of-type #ocho { color: red }
-
-
/* saf3, chrome1+ */
-
@media screen and (-webkit-min-device-pixel-ratio:0) {
-
#diez { background: #FFDECE; border: 2px solid #ff0000 }
-
}
-
-
/***** Attribute Hacks ******/
-
-
/* ie6 and below */
-
#once { _color:blue }
-
-
/* ie7 and below */
-
#doce { *color: blue } /* or #color:blue */
-
-
/* 'Modern Browsers' includes IE8, whether you agree or not.. :) */
-
He has included a test page and you can view the different browsers via browsershots.
Finally, he links to another concise list... of JavaScript sniffs.
Thursday, April 23rd, 2009
Category: JavaScript, Tip
Myk is one of the nicest chaps that I have had the pleasure to sit closely to in Mozilla building "S".
He has a nice little tip on the many syntaxes that you can use to iterate over arrays in various JavaScript implementations and standards. Some folks had some interesting points on the various approaches:
for each in:
JAVASCRIPT:
-
-
for each (var item in [1, 2, 3]) alert(item);
-
The MDC docs for "for each" say not to iterate arrays that way, too, so I never use it on them. The usual (would need to guard with hasOwnProperty() issue).
JavaScript 1.6 added the Array.forEach method:
JAVASCRIPT:
-
-
[1, 2, 3].forEach(function(item) { alert(item) });
-
JavaScript 1.7 added array comprehensions for array initialization:
JAVASCRIPT:
-
-
var squares = [item * item for each (item in [1, 2, 3])];
-
I just realized I can (ab)use comprehensions to iterate arrays with Perl-like syntax by throwing away the result:
JAVASCRIPT:
-
-
[alert(item) for each (item in [1, 2, 3])];
-
I can iterate object properties the same way:
JAVASCRIPT:
-
-
var obj = { foo: 1, bar: 2, baz: 3 };
-
[alert(name + "=" + obj[name]) for (name in obj)];
-
Edward Lee points out how to use Iterators:
JAVASCRIPT:
-
-
[alert(key + "=" + val) for ([key, val] in Iterator({a:1,b:2,c:3}))]
-
Friday, April 3rd, 2009
Category: JavaScript, Tip
Kangax has a really nice article on testing for event support in browsers in which he delves into the quirks and work-arounds needed to get 'er done, coming up with a nice generic solution:
JAVASCRIPT:
-
-
var isEventSupported = (function(){
-
var TAGNAMES = {
-
'select':'input','change':'input',
-
'submit':'form','reset':'form',
-
'error':'img','load':'img','abort':'img'
-
}
-
function isEventSupported(eventName) {
-
var el = document.createElement(TAGNAMES[eventName] || 'div');
-
eventName = 'on' + eventName;
-
var isSupported = (eventName in el);
-
if (!isSupported) {
-
el.setAttribute(eventName, 'return;');
-
isSupported = typeof el[eventName] == 'function';
-
}
-
el = null;
-
return isSupported;
-
}
-
return isEventSupported;
-
})();
-
Along with this, he put up a simple test case that you can point at.
Friday, March 6th, 2009
Category: Tip, Utility
Stoyan Stefanov has created a fun little bookmarklet that calculates the content to markup ratio of a webpage:
When you care about performance, or SEO (or just doing a good job as web dev) an interesting data point is the ratio of page content vs. the markup used to present this content. Or... how much crap we put in HTML in order to present what the users want to see - the content.
So I played tonight with a bookmarklet to provide this piece of stats.
The bookmarklet code is served from here. The code is also on github.
And some fun results:
Here are some random results of running the bookmarklet on different sites.
http://www.cnn.com:
Total size: 92004 bytes
Content size: 11475 bytes
Content-to-markup ratio: 0.12
Fair ratio * : 0.16
http://www.sitepoint.com
Total size: 65989 bytes
Content size: 16199 bytes
Content-to-markup ratio: 0.25
Fair ratio * : 0.60
Article on http://en.wikipedia.org:
Total size: 21648 bytes
Content size: 3315 bytes
Content-to-markup ratio: 0.15
Fair ratio * : 0.35
http://www.phpied.com
Total size: 31899 bytes
Content size: 7933 bytes
Content-to-markup ratio: 0.25
Fair ratio * : 0.48
http://www.google.com SERP
Total size: 29963 bytes
Content size: 3351 bytes
Content-to-markup ratio: 0.11
Fair ratio * : 0.14
Monday, February 23rd, 2009
Category: Prototype, Tip
Kangax shows a nice use of Prototype as he writes a tip to let you see your Prototype based events as they run in your application. A nice little view.
He also realized that the core piece of the bookmarklet is actually a nice view of the power of Prototype as a library:
JAVASCRIPT:
-
-
$H(Event.cache).inject(0, function(m, p) {
-
m += $H(p.value).values().flatten().size();
-
return m;
-
});
-
Category: Canvas, Examples, Tip

Jacob is back, and this time he has a cheat sheet with him. It is nice to see the Canvas API fitting on one sheet here, and I really like the images showing how things look like and work.
Thursday, January 29th, 2009
Category: Tip
That is the current winner in the shortest way to test for IE (including 8). The other notable was:
Huh :)
Gareth Heyes (the chap who did the v trick) has posted on this himself and comes up with One Line To Rule Them All:
JAVASCRIPT:
-
-
B=(function x(){})[-5]=='x'?'FF3':(function x(){})[-6]=='x'?'FF2':/a/[-1]=='a'?'FF':'\v'=='v'?'IE':/a/.__proto__=='//'?'Saf':/s/.test(/a/.toString)?'Chr':/^function \(/.test([].sort)?'Op':'Unknown'
-
Tuesday, January 27th, 2009
Category: Tip

This is a fun little hack by Manfred Staudinger.
Thanks to select="system-property('xsl:vendor')", he has a style sheet that allows you to show items depending on the browser:
To include a link or a style element for one of the above choices you use the dr:select attribute and specify one or more tokens as a comma separated list. For example dr:select="Firefox, Safari 3" will cause the link or style element to be included for any Firefox and for Safari 3. If you specify more than one token, each of which constitutes a positive selection, you may use any combination of tokens from the non-IE browsers plus the token "IE".
To select a specific IE only one token in the dr:select attribute is allowed, because it is directly used in constructing a Conditional Comment (CC). These are constructed on the fly only if the current browser is actually an IE. Any valid CC expression is allowed, so you can specify for example dr:select="lte IE 7" (positive selection) or dr:select="!IE 6" (negative selection). To clarify, a positive CC selection will allow only the IE's specified to read the CSS, and a negative CC will exclude them from seeing it. The best, you don't need anymore to include Microsoft proprietary CC's for selecting CSS in your HTML!
Link and style elements without a dr:select attribute are considered common stylesheets which every browser will see. They will remain unchanged, as any other HTML element. Only the dr:select attributes will be nullified.
You could do this when JavaScript isn't enabled for example.... although I am not sure how practical it actually is :)
Monday, January 19th, 2009
Category: Tip

"Ethan" has a really nicely packaged set of web resources that he uses.
From JavaScript core libraries, to widgets, to tools, to CSS frameworks, to CSS techniques, to browser compatibility, to typography, to extensions, and much much more. Nicely done.
Monday, January 12th, 2009
Category: JavaScript, Tip
Thomas Fuchs has run into those annoying times when a redraw is required to irk the browser into a correct layout, and his weapon of choice is:
JAVASCRIPT:
-
-
Element.addMethods({
-
redraw: function(element){
-
element = $(element);
-
var n = document.createTextNode(' ');
-
element.appendChild(n);
-
(function(){n.parentNode.removeChild(n)}).defer();
-
return element;
-
}
-
});
-
This is an update to the Script.aculo.us forceRerendering so it will probably be in Scripty 2? :)
Sebastian of Qooxdoo had a similar technique:
You may also use some kind of addClass/removeClass combo. That would result into the same effect but without creating unused DOM elements. We use this method in qooxdoo and it works well.
Do you run into these issues?
Friday, November 14th, 2008
Category: JavaScript, Library, Tip
Our own Michael Mahemoff is at it again, creating a simple little GUID generator called Guid0:
Guid0 is a GUID library for Javascript. Okay, it doesn't yet do official, bona fide, 128-bit, GUIDs yet, mainly for API design reasons. But this is a library you might find useful if you want to generate a unique ID in your Ajax app.
JAVASCRIPT:
-
-
// simple
-
guid = new Guid();
-
var newguid = guid.generate();
-
-
// options
-
guid = new Guid(
-
{
-
chars: Guid.constants.base85, // or you could say "abc" if you only wanted those chars to appear
-
epoch: "June 1, 2003",
-
counterSequenceLength: 2, // a counter field appended to the end
-
randomSequenceLength: 2 // a random field appended to the end
-
}
-
);
-
He is working on 128-bit support.
Wednesday, October 1st, 2008
Category: Tip, Utility
Dan Fabulich got bitten by the "trailing comma" issue one too many times, so he created a script to solve his problem:
“How many thousands of developer hours have been lost to random IE bugs like this?” I asked myself. I decided that there had to be a good way to detect this problem in an automated way, without firing up a copy of IE and running a full test suite.
It turns out that these and other syntax errors can be detected automatically from the Windows command line, using the Windows Scripting Host (WSH). On Windows XP and higher, the command-line tool “cscript.exe” can be used to run JavaScript (ahem, JScript) headlessly (outside of any browser).
Just create a file called “wsh-parser.js” like this:
JAVASCRIPT:
-
-
var fso = new ActiveXObject( "Scripting.FileSystemObject" );
-
-
function parse(fname) {
-
var file = fso.OpenTextFile( fname, 1 );
-
ret = file.ReadAll();
-
file.Close();
-
try {
-
eval("(function(){\n"+ret+"\n});");
-
} catch (e) {
-
WScript.Echo("Syntax error parsing " + fname);
-
WScript.Echo(" " + e.message);
-
}
-
}
-
-
function findJavaScript(folder) {
-
for (var fc = new Enumerator(folder.files); !fc.atEnd(); fc.moveNext()) {
-
var file=fc.item();
-
if (/.js$/.test(file.Name)) {
-
parse(file);
-
}
-
}
-
for (var fc = new Enumerator(folder.subfolders); !fc.atEnd(); fc.moveNext()) {
-
var subfolder = fc.item();
-
if (subfolder.Name == ".svn") continue; // ignore .svn folders
-
findJavaScript(subfolder);
-
}
-
}
-
-
var rootPath = "src/main/javascript";
-
var rootFolder = fso.GetFolder(rootPath);
-
-
findJavaScript(rootFolder);
-
Other tools will help you hunt this down too, and I am sure some of you have Perl/Ruby/Python one liners to do the same ;)
Next Page »