GC pauses are not the only issue. Image loading often introduces longer pauses than GC, and input latency is a huge problem too. I've written a benchmark that exposes these responsiveness issues: http://google.github.io/latency-benchmark
Yeah jpeg decoding is a big one, but I think it's less to do with raw performance and more to do with the fact that there aren't any hooks to help you control the user experience around it (i.e. there is no way to determine if you're done decoding unless you write the decoder yourself and draw to canvas, which increases your latency by a lot).
IIRC I think dropped frames from jpeg decoding is less of an issue in today's webkit, but I'm not sure. I seem to remember there being workarounds like adding a no-op CSS animation or iframe to coax the browser to do it off of the UI thread.
That's a nice demo you have there, btw, I'll have to check it out more.
Thanks! JPEG decoding isn't the only problem with image loading. Image resizing, texture upload, and relayout/painting related to image loading all contribute to jank. Also, as you pointed out, the fact that it's impossible to schedule any of those things at appropriate times because you have no control over or visibility about when they happen.
Are there relayout issues I'm not aware of with images when you're using absolute positioning?
I did some experiments a while ago with running jpgjs in a webworker and was able to get zero-jank images by splitting the copy to canvas across multiple requestAnimationFrames. However it adds a significant amount of latency and I'm not sure it's worth the trade off.
I am wondering, though, if one built a pipelined progressive jpeg downloaded/decoder/renderer with this technique if it would yield positive results.
I don't think so, I just mentioned layout since it's something that can be triggered by image loading.
I don't think progressive JPEG is worth the rendering overhead in general, but doing JPEG decoding in a JS worker is not as crazy as it sounds if you're serious about reducing jank.