looking for a full-immersion/face-to-face HTML5, JavaScript, and Mobile Web Development training in the heart of London? Book your spot
Showing posts with label solution. Show all posts
Showing posts with label solution. Show all posts

Wednesday, September 05, 2012

A Meaningful Client Side Alternative To node require()

TL;DR

Here you have the solution to all your problems ... no? So take a break, and read through :)

Current Status

Using a generic "module loader" for JavaScript files is becoming a common technique, and full of wins, not only on the node.js server side. There are different client side alternatives, not entirely based over the module concept, and apparently only one concrete proposal, called AMD, able to work in both server and client following a build/parsing procedure.
However, as somebody pointed out already ...

AMD is Not the Answer

This post does not even tell everything bad about AMD problems, and I am getting there, but it's surely a good starting point.
Tobie article is another resource that inspired somehow what I am going to propose here, so before discriminating this or that technique, I hope you'll find time to understand the whole problem ... found it? Let's go on then :)

The Beauty Of node.js require Function

I don't think I should even spend many words here ...

// module: compress

// in the global scope, it's just a module
// so no pollution to the global/window object
// no need to put everything in yet another closure
var fs = require("fs");

// just as example
this.compress = function (file, fn) {
fs
.createReadStream(file)
.pipe(
// check this out!
require("zlib").createGzip()
)
.pipe(
fs.createWriteStream(file + ".gz")
).on("close", function () {
var content = fs.readFileSync(file + ".gz");
fs.unlinkSync(file + ".gz");
fn(content);
})
;
};

So basically, with a synchronous require(module) call we can decide whenever we want where that module should be included in our logic. This means we don't need to think in advance to all needed dependencies for our current module, as well as this doesn't require to split in many nested functions our asynchronous logic.
Look at above example ... in node world the require("fs") is performed basically in every single module ... the FileSystem is that important, hell yeah!
We dont' care much about requiring it at the very beginning of above stupid module 'cause surely that operation will cost nothing! Each module is cached indeed so there's actually zero impact if we use a require hundreds of time inline ... really, it's that fast, but the very first one might cost a bit.
This is why require("zlib") is loaded only once, and only when it's needed ... so that memory, disk, cpu, and everything else, can live in peace before the very first call of that exported method while after that, that call will cost again nothing.

Is a mandatory nested function call through AMD logic as fast as above example? I tell you, NO, but this is not the real problem, is it?

AMD Does Not Truly Scale

... as simple as that. If you need a build process behind something that could fail in any case, I would say you are doing it wrong. I am talking about current era, where internet connection could be there or not ... I am talking about mobile and I give you a very basic example.
I have created my freaking cool website or webapp that loads asynchronously everything and I am on the road with my supa-dupa smart phone.
When "suddenly, le wild spot without internet coverage appears"!
Now I press that lovely button in the lovely application that loads asynchronously the lovely next part of my action and guess what happens ... are you there? Nothing!
That instant without my mobile network will screw up my flow, will break my action, will let me wait "forever" and in most common cases, it will block me to use properly the app.
Of course, if that action required server side interaction, that action won't work in any case ... but how come I don't even see a notification? How come pieces of my application are not showing up telling me that there is actually a problem, rather than letting me wait without any notification, 'couse probably even notification logic was created as AMD module?

And what if connection is simply bad? The whole application or website is responding decently but that part, oh gosh how much I was planning to use that app part, is taking ages to load! How would you feel in front of such program?

AMD Resolves Lazy/Circular Load Synchronously

That's correct ... gotcha! Have you ever read what you should do in order to resolve modules that load asynchronously other modules inside themselves?

//Inside b.js:
define(["require", "a"],
function(require, a) {
//"a" in this case will be null if a also asked for b,
//a circular dependency.
return function(title) {
// me: Excuse me ... WUT?
return require("a").doSomething();
}
}
);

So here the thing, if "by accident" you have a circular dependency you should use require() as node.js does ... oh well ...

On Circular Dependencies / Cycles

This topic is one of the biggest paradox about programming ... we try to decouple everything, specially when it comes to write modules, so that not a single part of the app should be aware of the surrounding environment ... isn't it? Then someone said that circular dependencies are bad ... but how come?
Here an example, a truly stupid one:
Hi, I am a human, the human module, and I am completely sufficient, but I need to go in a place that would take too much by my own ... so I need the module car.

Hi, I am a car, the module car, and I am fabulous by my own, but I need the module human to be able to go somewhere.

A partner, better than a car, could also explain the fact we actually think in circular references all the time ... am I wrong?
The AMD take in this case is that "we should change the require logic when this happens and we should be aware in advance in order to solve this" ... yeah, nice, so now in AMD we have two ways to require and return what we export ... and once again, in my humble opinion, this does not scale ... at all!

Double Effort, Double Code!

With AMD we don't only need to change our AMD code/style/logic when things are not known in advance, as showed before ... we also need to write code for modules that is not compatible with node.js, resulting in such piece of redundant code that I believe nobody truly want to write more than once in a programmer life.
Take an excellent library as lodash is, and check what it has to do in order to be compatible with AMD too ...

// expose Lo-Dash
// some AMD build optimizers, like r.js, check for specific condition patterns like the following:
if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
// Expose Lo-Dash to the global object even when an AMD loader is present in
// case Lo-Dash was injected by a third-party script and not intended to be
// loaded as a module. The global assignment can be reverted in the Lo-Dash
// module via its `noConflict()` method.
window._ = lodash;

// define as an anonymous module so, through path mapping, it can be
// referenced as the "underscore" module
define(function() {
return lodash;
});
}
// check for `exports` after `define` in case a build optimizer adds an `exports` object
else if (freeExports) {
// in Node.js or RingoJS v0.8.0+
if (typeof module == 'object' && module && module.exports == freeExports) {
(module.exports = lodash)._ = lodash;
}
// in Narwhal or RingoJS v0.7.0-
else {
freeExports._ = lodash;
}
}
else {
// in a browser or Rhino
window._ = lodash;
}

Now ... ask yourself, is this what you want to write for every single module you gonna create that might work in both server and client side?

Combined AMD Modules

Here another possibility, super cool ... we can combine all modules together into a single file: YEAH! But if this what you do for your project, don't you wonder what is the point then to use all those "asynchronous ready" callbacks if these will be executed in a synchronous way in production? Was that different syntax truly needed? And what about JS engines parsing time? Is processing the whole project at once in a single file a good thing for both Desktop and Mobile?
Why are you developing asynchronously with all those nested callbacks if you provide a synchronous build? Is the code size affected? Does all this make any sense?

AMD, The Good Part... Maybe

OK, there must be some part of this logic that conquered many developers out there .. and I must admit AMD "solved with nonchalance" the fact JavaScript, in the client side, has always had problems with the global scope pollution.
The fact AMD forces us to write the module inside a function that receives already arguments with other needed modules, is a win ... but wait a second, wasn't that boring before that nobody until now wrote a single bloody closure to avoid global scope pollution?
I think AMD is a side effect, with all possible noble and good purpose, of a general misunderstanding of how is JS code sharing across libraries.
Let's remember we never even thought about modules until we started clashing with all possible each other polluting namespaces, global variables, Object.prototype, and any sort of crap, thinking we are the only script ever running in a web page ... isn't it?
So kudos for AMD, at least there is a function, but where the hack is the "use strict" directive suggested for every single bloody AMD module in any example you can find in the documentation? where is the global pollution problem solver, if developers are not educated or warned about the problem itself?

node.js require ain't gold neither

When network, roundtrips and latency come into the game, the node.js require() solution does not fit, scale, work, neither.
If you understand how Loading from node_modules Folders logic works, and you have an extra look into All Together diagram, you will realize that all those checks, performed through an HTTP connection, won't ever make sense on the client side.
Are we stuck then? Or there's some tiny little brick in the middle that is not used, common, public, or discussed yet?

A node require() Like, For Client Side

Eventually, here where I was heading since the beginning: my require_client proposal ... gosh it took long!
Rewind ... How about having the best from all techniques described "here and there" in order to:
  • avoid big files parsing, everything is parsed once and on demand
  • provide an easy to use builder for production ready single file code
  • use one single syntax/model/style to define modules for both node or client side
  • solve cycles exactly as node does
  • forget 10 lines of checks to export a bloody module
  • organize namespaces in folders
  • obtain excellent performance
  • make a single file distributable
... and finally, compare results against all other techniques?
Here, the AMD loader, versus the inline and DOM script injection loader, versus the dev version of my proposal, and finally the production/compiled version of my proposal ... how about that? You can use any console, profiler, dev tool/thing you want, to compare results, it's about a 150Kb total amount of scripts with most of them loaded ASAP, and one loaded on "load" event.
You can measure jquery, underscore, backbonejs, and the ironically added as last script head.js script there within their loading/parsing/ready time.

Reading Results

If you think nowadays the DOMContentLoaded event is all you need to startup faster your web page/app, you are probably wrong. DOMContentLoaded event means almost nothing for real UX, because a user that has a DOM ready but can't use, because modules and logic are not loaded yet, or see, because CSS and images have not been resolved yet, the page/app, is simply a "user waiting" rather than interacting and nothing else.
Accordingly, if you consider the code flow and the time everything is ready to be used, the compiled require() method is the best option you have: it's freaking fast!

"use strict" included

The best part I could think about, is the "use strict"; directive by default automatically prepended to any module that is going to be parsed.
This is a huge advantage for client side code because while we are able to create as many var as we want in the module scope, the engine parser and compiler will instantly raise an error the line and column we forgot a variable declaration. All other safer things are in place and working but .. you know, maybe you don't want this?
That's why the require_client compiler makes the strict configuration property easy to spot, configure, and change ... as long as you know why you are doing that, everything is fine.

How Does It Work

The compiler includes a 360 bytes once minzipped function that when is not optimized simply works through XHR.
This function could be the very only global function you need, since every module is evaluated sandboxed and with all node.js module behaviors.
You can export a function itself, you can export a module, you can require inside a module, you can do 90% of what you could do in a node.js environment.
You don't need to take care of global variables definition, those won't affect other modules.
What you should do, is to remember that this is the client so the path you choose in the development version, is the root, as any node_modules folder would be.
If you clone the repository, you can test via copy and paste the resulting build/require.js in whatever browser console traps such require_client ~/folder_you_put_staff/require_client/js or require_client ~/folder_you_put_staff/require_client/cycles.
require("a") in the first case and require("main") in the second.
In order to obtain a similar portable function you should create a folder with all scripts and point to that folder via require_client so that a script with all inclusions will be created.

A Basic Example

So here what's the require_client script is able to produce.
Let's imagine this is our project folder structure:

project/
css/
js/
require.dev.js
index.html

The index.html file can simply have a single script in its header that includes require.dev.js and the bootstrap module through require("main");, as example.
So, let's imagine we have module a, b, and main inside the js folder, OK?
require_client project/js project/require.js
This call will produce the require.js file such as:

/*! (C) Andrea Giammarchi */
var require=function(c,d,e){function l(n,m){return m?n:g[n]}function b(o){var m=a[o]={},n={id:o,parent:c,filename:l(o,h),web:h};n[k]=m;d("global","module",k,(e.strict?"'use strict';":"")+l(o)).call(m,c,n,m);j.call(m=n[k],i)||(m[i]=h);return m}function f(m){return j.call(a,m)?a[m]:a[m]=b(m)}var k="exports",i="loaded",h=!0,a={},j=a.hasOwnProperty,g={
"a": "console.log(\"a starting\");exports.done=false;var b=require(\"b\");console.log(\"in a, b.done = \"+b.done);exports.done=true;console.log(\"a done\");",
"main": "console.log(\"main starting\");var a=require(\"a\");var b=require(\"b\");console.log(\"in main, a.done=\"+a.done+\", b.done=\"+b.done);",
"b": "console.log(\"b starting\");exports.done=false;var a=require(\"a\");console.log(\"in b, a.done = \"+a.done);exports.done=true;console.log(\"b done\");"
};f.config=e;f.main=c;return f}(this,Function,{
strict:true
});
Now the index.html could simply include reuiqre.js rather than the dev version ;)
Above program is the same showed in node.js API documentation about cycles. If you copy and paste this code in any console and you write after require("main"); you'll see the expected result.
As summary, require_client is able to minify and place inline all your scripts, creating modules names based on files and folders hierarchy.
All modules will be evaluated with a global object, already available, as well as module, exports, and the latter used as the module context.
The simple object based cache system will ensure these modules are evaluated once and never again.

What's YAGNI

Few things, that could change, are not in on purpose. As example, the module.parent is always the global object, since in fact, it's in the global scope, through Function compilation, that the module will be parsed the very first time. Not sure we need a complicated mechanism to chain calls and also this mechanism is error prone.
If you have 2 scripts requiring the same module, first come, first serve. The second one should not affect runtime the already parsed module changing suddenly the module.parent property ... you know what I mean?
The path resolution is a no-go, rather than trying to fix all possible messes with paths and OS, put your files in a single JS folder and consider that one your virtual node_modules one for clients.
If you have folder links inside the JS folder it's OK, but if you have recursive links you are screwed. Please keep it simple while I think how to avoid such problem within the require_client logic, thanks.

What Is Not There Yet

If your project is more than a megabyte minzipped, you might want to be able to split in different chunks the code so that the second, last, injected, require, won't disturb the first one. This is not in place yet since this free time project was born for a small/medium web app I am working on that will be out pretty soon ... an app that surely does not need such amount of code as many other web app should NOT ... but you know, I've been talking about scaling so much that a note about the fact this solution won't scale so nicely with massive projects is a must say.

UpdateJust landed a version that does not cause conflicts with require itself. The first defined require will be the one used everywhere so it's now possible to name a project and include it in the main page so ... parallel projects are now available ;)

If you would like to reuse node modules that work in the client side too, you needto copy them inside the path folder.
The configuration object is the one you can find at the end of the require.js file ... there are two defaults there, but you can always change them via require.config.path = "different"; as well as you can drop the require.config.strict = false; directive so that modules will be evaluated without "use strict"; directive.
Anything else? Dunno ... you might come up with some hint, question, suggestion. And thanks for reading :), I know it was a long one!

Last Thoughts

If AMD and RequireJS comes with a compiler able to make everything already available somehow, think how much pointless become the optimization once you can have already available all dependencies without needing to write JS code in a different way, regardless it's for node.js or the client web normal code.
There are NOT really many excuse to keep polluting the global scope with variables, we have so may alternatives today that keep doing it would result as evil as any worst technique you can embrace in JS world.

Tuesday, November 17, 2009

195 Chars To Help Lazy Loading

Update
removed named function expression

Update
I wrote events letters in the wrong place, please use the latest script

We have talked many times about performances, and not only here.
One common technique to speed up a generic online page is the lazy loading.
For lazy loading I mean:
  • runtime dependencies resolution via script injection, preferably including all dependencies we need in a shot rather than script after script
  • Google comments style, where code is evaluated when required but the size is still there
  • namespaced strings, an example I have explained via code in Ajaxian
  • whatever else, because sometimes we need this or that library only in certain conditions


What Is The Problem

If we would like to widely adopt this lazy load pattern, we should be aware about a "little detail": Firefox < 3.6 does not support document.readyState, an historically valid Internet Explorer feature adopted in HTML5 and present in basically every other browsers.
We can find the readyState description and the related bug in Mozilla domain.
Reading suggestions, I found quite pointless the long diatribe about:

Should it be "loading" or "interactive" before it will switch to "complete" ?

IMHO, who cares, as long as we can rely in the final statement: complete

Affected Libraries

I have no idea but for sure jQuery! The event.js file shows at line 857 this check for the bindReady event:

// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState === "complete" ) {
return jQuery.ready();
}

The code goes on with common DOMContentLoaded checks and emulations.
The problem is that with such library where basically everything starts with an ready event:

$(function(){
// the ready event we are theoretically
// sure will be fired even if the
// code has been loaded after
});

every Firefox < 3.6 user will miss that code, plug-in, extension, whatever.
I have already informed jQuery dev ML about this problem but obviously they already know. John Resig told me that there is no guarantee the ready event will be fired if the page has been loaded.
Fair enough, I can perfectly understand John point which is: all jQuery supported browsers may not support document.readyState.
AFAIK, even if this is a good reason to avoid some obtrusive code, we all would expect consistency from a framework so if something worked even in IE I can't even think about Firefox problems.

The Solution


This missed FF feature could affect different libraries, not only jQuery.
We, as developers, could help every library author adding 195 uncompressed bytes, even less once deflated, as first stand alone piece of code ever in our page:

// WebReflection Solution
(function(h,a,c,k){if(h[a]==null&&h[c]){h[a]="loading";h[c](k,c=function(){h[a]="complete";h.removeEventListener(k,c,!1)},!1)}})(document,"readyState","addEventListener","DOMContentLoaded");

// NOTE: IE will never consider false s[o]==null

Since Firefox is usually updated automatically, all we need to do once we are sure people are surfing with version 3.6 or greater is simply remove above little line of code.

Explained Solution


// verify that document.readyState is undefined
// verify that document.addEventListener is there
// these two conditions are basically telling us
// we are using Firefox < 3.6
if(document.readyState == null && document.addEventListener){
// on DOMContentLoaded event, supported since ages
document.addEventListener("DOMContentLoaded", function DOMContentLoaded(){
// remove the listener itself
document.removeEventListener("DOMContentLoaded", DOMContentLoaded, false);
// assign readyState as complete
document.readyState = "complete";
}, false);
// set readyState = loading or interactive
// it does not really matter for this purpose
document.readyState = "loading";
}


Conclusion

Being this a browser problem and not directly libraries related, it does not probably make sense to put this fix just for few months until next FF release. At the same time we can guarantee for Firefox users, and only if the library does not sniff the browser via this read only property, that lazy loaded stuff a la $(rockNroll) will work into our favorite browser too or we could simply rely and with our code into a readyState "complete" check to decide what to do (this is the real reason I have investigated more this problem, but this is another story coming soon).

Monday, October 12, 2009

Named function expressions demystified III

Update For those interested about Internet Explorer scope resolution, I summarized everything in 5 slides.


This is hopefully the end of the Named function expressions demystified trilogy, where here you can find episode I, and episode II.
Juriy knows I am hard to convince, but apparently he is not better than me at all ...

Inglorious Correction

Sure, it's better than nothing, but after I have spent dunno how many tweets plus 2 posts, all I have obtained is a small correction in the whole article (and you have to scroll a bit before):

Generally, we can emulate function statements behavior from the previous example with this standards-compliant (and unfortunately, more verbose) code:

var foo;
if (true) {
foo = function foo(){ return 1; };
}
else {
foo = function foo() { return 2; };
};

// call the function, easy?
foo();


Above snippet is the best solution in the entire article but probably to avoid my name in article credits, and it does not matter since I have already said it's not about the copyright, and surely to avoid personal ego conflicts, the suggested one is a surrogate of above snippet, quite embarrassing from a developer point of view, isn't it?

var f; // create an alias, WHY!!!!!!!!!
if (true) {
f = function foo(){ return 1; };
}
else {
f = function foo() { return 2; };
};

// create a reference in order to remove a reference, WHY!!!!!!!!!!!
var foo = null;

// call the function via another alias, WHY!!!!!!!!!!!
f();

Above snippet is just a surrogate because the first one simply create an alias which will refer the proper function. Let's be simply developers avoiding obtuseness, OK?

Re Solution Pros

  1. it's standard, no excuses at all!
  2. variables on top, no way we can forget to nullify the function and we don't need to create a reference which aim is to remove a reference, cause the reference is already assigned, no memory problems at all (possibly less, since there is nothing referenced to a null value)
  3. semantic, we can easily refer to the function, since the whole point is to solve the missed arguments.callee plus IE inconsistency ...
  4. standard again, because it perfectly emulates ECMAScript 3rd Edition behavior even in Internet Explorer
  5. the day we will need to nullify the function will be the day we meant it, and not a surpassed convention


Why My Re Solution Is More Standard

This is the expected behavior in all browsers, except Internet Exlorer and Opera, via Internet Explorer emulation:

var f; // let's use the suggested alias
// for demonstration purpose
if (true) {
f = function foo(){
// this is LOGICAL
// but in IE it will be false
// because foo will be the
// the other one, even if that
// else will never be executed!
alert(foo == arguments.callee)
};
}
else {
// IE will declare this function
// in any case since there is NO DIFFERENCE
// between expression and declaration
f = function foo() { return 2; };
};

f();

With my Re Solution the behavior is the expected one, alert(foo == arguments.callee) will be true in every browser ... do you still have doubts?

Re Solution Cons

  1. unfortunately, more verbose
This must be a joke ... more verbose? First of all we are dealing with developers that don't care at all about verbosity. Kangax as everybody else in credits always preferred verbosity since minifier and compressor could take care about this verbosity recreating, and I love the irony of this part, exactly the suggested case.

Re Solution Pros II

  1. being the function name declared on the top of the function, as I have said a well known good practice, every IDE will automatically suggest that name as soon as we'll startt to type it: does verbosity matter?
  2. As we all know gzip and deflate compresses repeated words more efficiently, as result the Re Solution is even smaller if we don't munge it, does verbosity matter?


Re Solution Is More Logical And Smaller

Here the simple test everybody can do. Two pages, same code, except the first one is Re Solution, 99 bytes, while the second one is Juriy suggestion, 111 bytes.

<?php ob_start('ob_gzhandler'); ?>
var foo;
if (true) {
foo = function foo(){ return 1; };
}
else {
foo = function foo() { return 2; };
};


<?php ob_start('ob_gzhandler'); ?>
var f;
if (true) {
f = function foo(){ return 1; };
}
else {
f = function foo() { return 2; };
};
var foo = null;

Do we have a single valid reason to use the Juriy suggestion over mine? I would honestly feel an idiot preferring the second one, since few bytes and more logic (foo is the function foo) against spread variables declarations (top and the middle with F = null) via aliases rather than function names inside the function itself where a debugger will show the name but we have to remember the alias, plus the possibility we forget to nullify the reference consuming more memory ... I mean, this is not the first of April, isn't it?

And That's Not All Folks

We are developers, not monkey, I always dislike generic affirmations a la eval is evil, the most used function since Ajax epoch, obviously included in json2.js itself, since is natural and logical to use it when necessary. Juriy corrected his article to underline how unprofessional am I suggesting a last option for IE behavior ... well, probably he has never thought about ternary assignment, isn't it?
// Never do this!, that's what I can read at some point, but we should think carefully before these statements.
Here there is an example where the function will be a named one but there are no differences in this case for IE, indeed the last option is the IE one.

// somewhere in a closure ...
// (otherwise add will be public in IE,
// but I hope we went further than this
// at this point and after 3 posts
// plus an entire article ...)
var event = {
add:document.addEventListener?
function add(){
alert([add, document.addEventListener]);
}:
function add(){
alert([add, document.attachEvent]);
}
,
del:document.removeEventListener?
function del(){
alert([del, document.removeEventListener]);
}:
function del(){
alert([del, document.detachEvent]);
}
};

In one shot we have created a unique add reference, a named function, plus the right one for the event object. Now guess what's up if we invert the order putting the IE version at the end ... add will be the last option ... the one with addEventListener, got the point?

As Summary

I am pretty much sure I'll be criticized again and only for the last part of this post where obviously things work but somebody will argue about future IE9 sci-fi behavior or stuff like that ... well, that day my library will be deprecated in any case and, if needed, it's easy to implement over my Re Solution

var event = {
add:(function(add){document.addEventListener?
(add = function add(){
alert([add, document.addEventListener]);
}):
(add = function add(){
alert([add, document.attachEvent]);
}); return add
})()
};

Now let's see if the most interesting analysis about functions expressions and declaration will keep ending up with the wrong suggestion, rather than mine ... kinda curios, still hopeful though.

Monday, September 21, 2009

CSS Position Fixed Solution

Who does not know CSS 2.1? ... silence (maybe) ...
Good, so who does not know the CSS 2.1 position property? ... silence (still maybe though) ...

Excellent! Finally, who would like to use in a lightweight, cross-browser, unobtrusive way, without JavaScript dependencies, the property fixed? ... silence again, but this time I can spot a different expression in your face ...


Common Browsers With position:fixed Support

  • Chrome
  • Firefox
  • Internet Explorer 7 and 8 but NOT in quirks mode
  • Opera
  • Safari


Common Browsers WithOut position:fixed Support

  • Internet Explorer 6
  • Internet Explorer 7 and 8 in quirks mode
  • WebKit for Android
  • WebKit for iPhone


To Quirks Or Not To Quirks

For backward compatibility reasons IE let developers choose between two box models ... Our loved bloody 64 years* old browser Internet Explorer 6 has never supported such property while both Internet Explorer 7 and 8 do nt support it if we are in quirks mode, a modality tendentiously dead thanks to new simple HTML 5 doctype declaration: <!DOCTYPE html>.
To solve this issue I have created a dedicated file to include via conditional comments which includes a set of "never before that useful" expressions.

Why Expressions

CSS expressions are compatible, so far, only with Microsoft IE browser and they are totally alien for both other browsers and developers. The reason I am saying that is because they are completely unpredictable: it is not possible to easily understand or to predict when expressions will be executed, where, and how!
Technically speaking, being expressions dedicated for CSS hacks, their executions will be performed at least every time the element is somehow involved, and to make it involved, we need to touch some property in order to make expression useful (in this solution case the property offsetHeight of the current node).

The Direct Example

Here we have two pages: the standard or strict mode and the quirks one.
As you can test via your favorite browsers, there are always 5 elements in that page, a top div, a center one, a bottom one, and two divs one left and one right, above and over the center one.

How Does It Work

It is very simple, consider these CSS classes:

/** A WebReflection Solution */
.position-fixed-top {
position:fixed !important;
top: 0;
}
.position-fixed-center {
position:fixed !important;
top: 50%;
}
.position-fixed-bottom {
position:fixed !important;
bottom:0;
}

Hopefully choose name are semantic enough, so it's quite clear that these classes aim is only to position elements, and nothing else, in order to be able to add other classes for whatever other property, zIndex if necessary included.
Choose classes are about most common usage of fixed elements in a page, top, center, or bottom, and adjusting positions or margins it is really simple to put the element in whatever part of the page starting from the bottom, from the top, or the left.
To let the magic be in Internet Explorer 6 and others in quirks mode, these classes are completely replaced, as you can read in IE dedicated file.
Being the IE solution based on CSS expressions, there should not be anything better or quicker than that, render time and call speaking, same should be for memory leaks, timers, and whatever strategy we have adopted 'till now (but of course if there is something better please share!).

Android & iPhone - Not Worth It

These mobile devices implement a stunning browser as dedicated WebKit is, able to render faster than IE8, for example, my last Liquid FX, based on 1 image, and one div, that's it! (congrats IE8 for stretched images rendering time! 7, 6, and 5.5. are much better) ... uh, wait, it's not about IE ...
Android and iPhone have both a great CSS 2.1 support, and even some CSS 3. Unfortunately the position fixed does not work as expected. To fix it I have tried different scripts failing each time. The reason is quite simple: both Android and iPhone block timers or render during scroll, so the effect is that divs move with the scrolled page and only after, eventually, divs come back in the expected position. This is against position fixed idea, and having a truly small screen we should ask our self if it makes sense to cover precious pixels with something fixed there.
It does not matter, as soon as I'll be able to test an iPhone I will continue to optimize my script in order to make the position fixed property usable somehow with mobile devices as well ( center right or center left could be interesting, bottom or top bar quite intrusive for user and/or zooming features ).

How To Implement My Solution

It's simple, if we are in a quirks page, we should include the CSS hacked file after the normal one, and for every IE:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css" />
<![endif]-->

While for every standard or strict web page we can include the hack only for IE less than version 7:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css?444" />
<![endif]-->

I can spot a new expression in your face, isn't it?


* if we multiply per 7 dogs age, I think it is reasonable to say that in IT each year could be multiplied for 8