Monday, September 25, 2006

A forensic analysis of the IE6 BackgroundImageCache command identifier

The document.execCommand("BackgroundImageCache", false, true) command seems to do at least what it's name suggests: cache the background images.

Let's see the visible effects of this command.

Step 1: "Is it modified YET?"

IE would "normally" check with your web server for newer versions of the css background images prior to applyng a css rule, no matter what is the value of the cache option. Make it "Every visit to the page.", "Automatically" or "Never", it does not matter, IE wants to know anyway.

Check this with Fiddler. Open the following page in IE: http://www.positioniseverything.net/css-dropdowns.html

See the hordes of requests for a tinny image, all getting the "304 Not Modified" response header. In it's greed to make all these requests, IE actually gets to abort some of them just to make room for others :))

Here's how to fix this insanity: run this bookmarklet inside the IE Addres Bar:

javascript:void(document.execCommand("BackgroundImageCache",false,true))

Look mom, there's no more traffic! Your poor ol' web server can rest now!

Now, let's move on for some more atrocities.

Step 2: "Where's my memory?"

Check the IE Memory Usage: open the above page in a clean instance of IE.

Play with the menu for a while, then check the Internet Explorer Memory Usage in task manager. Continue to move the mouse over the menu while keeping an eye on the "Mem Usage".

On my computer, IE memory heavily bounces between 21MB and 27MB and the menu is slow.

Now apply the patch on the page by running the following bookmarklet inside the IE address bar:

javascript:void(document.execCommand("BackgroundImageCache",false,true))

Guess what! The "Mem Usage" won't shake like this guy anymore and the menu will move much smother. Pages using extensive css background images run a lot smoother with the fix applied.

Step 3: "Move your platans, you lazy, good for nothing hard disk!"

So, it seems IE cache the bg images in memory, with no access to hard disk.

If you take a look at IE using the File Monitor from SysInternals you'll get the picture.

Close all IE instances, open IE, start File Monitor, filter events by process name iexplore, go to the above URL and start moving the mouse over the menus. You'll get something like 360 disk access for just going with the mouse over one menu item. Now apply the patch using the bookmarklet and continue moving the mouse over the menus. You'll see what I mean.

I can't tell at this moment if this fix would cause memory leaks. I don't know yet what's the catch, if there is any.

But it does a pretty good job for me.

14 comments:

Anonymous said...

On behalf of web developers everywhere: Thank you! :)

I wonder if there may be some other benefits to this, and if there is a risk of it causing wackiness elsewhere (maybe caching is "off" by default for a reason in IE 6? Who knows..)

Anonymous said...

This indeed greatly improved the speed of the CSS menus on my site, so I can only thank you a lot for this tip :) Gotta apply this to all my sites that use the IE:hover JavaScript...

Brad said...

Why is this command not listed on MSDN?
http://msdn.microsoft.com/workshop/author/dhtml/reference/commandids.asp

Dan POPA said...

I guess BackgroundImageCache was implemented as a dirty hack, a quick fix for a dirty problem.

Check the original article on Microsoft KB where I found this command identifier:
http://support.microsoft.com/?scid=kb;en-us;823727&spid=2073&sid=global

I am investigating now possible implications of the command.
I suspect that after the fix is applyed and IE starts keeping all the background images in memory instead of disk, the used memory would increase.
I would like to find the maximum memory cache size, what is the browser doing after it runs out of memory, does it release the memory cache after I reverse the fix by executing the command with the oposite argument:
execCommand("BackgroundImageCache", false, false)

Anonymous said...

OMG, thank you! I was going crazy with Deans IE7-position-fixed and background images, flickering like crazy. Now the flickering is gone!

Unknown said...

Nice hack, dude. :-) Thanks for sharing it.

Hugo said...
This comment has been removed by the author.
Hugo said...

This solution is GREAT, altough I wonder how Microsoft let such a crippling problem get through. And why it wasn't fixed in one of the NUMEROUS IE5/6 fixes.

I have one warning though. This fix will BREAK event handling in Opera 9. Whenever I use it, mouse events are stacked but never fired. It is only when the page is closed or reloaded that Opera fires ALL the events at once. I have no idea why a browser command targeting IE6's image cache would end up affecting Opera's event handlers... but it does.

So the best way to avoid this problem is to try to detect Opera & never apply the fix in that case.

Anonymous said...

These comments have been invaluable to me as is this whole site. I thank you for your comment.

Anonymous said...

@ HD: Why not use conditional statements (see quirksmode) to apply this to IE6 only?

Saves applying it to all unaffected browsers now and in the future.

Cheers for the article!

Alfred Albert said...
This comment has been removed by a blog administrator.
Anonymous said...

This indeed greatly improved the speed of the CSS menus on my site, so I can only thank you a lot for this tip :) Gotta apply this to all my sites that use the IE:hover JavaScript.

Anonymous said...
This comment has been removed by a blog administrator.
Unknown said...

I guess Back ground Image Cache was implemented as a dirty hack, a quick fix for a dirty problem.