WebKit leaks data URIs

The Problem

At work we have a web application where data URIs containing JPEG image data are generated on the server, transferred to the client and there the images are displayed by using these URIs as image sources. This approach works and it even performs nicely and all. Sadly, when trying this approach in WebKit based browsers (hello iPad...), we hit a bad memory leak.

As it turns out, all you have to do to trigger this is setting the "source" property of an image. Every time you do this, the image gets updated as expected, but as it seems the memory occupied by the last image that was displayed is never freed. I hacked a small demonstration of this so you can try yourself. But please be aware that this might crash your browser.

When you hit the "start" button the script will try to update the image every 50ms with a fresh, randomly-generated data URI which should result in an animated white noise (like your TV when not tuned to a station). And when using a current WebKit based browser, you will see the browsers unbounded memory usage. I highly recommend hitting "stop" before your OS starts swapping.

This bug is already known on the chromium issue tracker, but currently unresolved.

Affected Browsers

Here are some browsers that I tested. If you dare to, post your test results to the comments section and I'll update this list.

  • Chrome 6 (Windows, 32 bit) : leaks
  • Chromium 5.0.375.70 (Linux, 64 bit) : leaks
  • Firefox 3.6.3 (Linux, 64 bit) : OK
  • Firefox 3.6.3 (Windows, 32 bit) : OK
  • Firefox 3.7a5 (Windows, 32 bit) : OK
  • IE 8 (Windows, 32 bit): leaks
  • IE 9 (Windows, 32 bit): OK
  • iPhone 3.1 : leaks (most probably; crash)
  • iPhone 4 : leaks (like 3.1)
  • Konqueror 4.3.5 : leaks
  • Opera 10.10 (Linux, 64 bit) : leaks
  • Opera 10.* (Windows, 32 bit) : leaks
  • Safari 5 (Windows, 32 bit) : leaks

To cut it short: Firefox works, all others fail in one or another way.

Workaround

Welcome to the world of canvas and manual pixel manipulation using JavaScript. Using canvas' capability to draw images is of no use here, as obviously you have to initialize the image-to-be-drawn using an... URI. *yuck*


About this entry