It's a cross-browser issue, some of which is inherent to the spec (and some which is solved by yet-unimplemented spec behaviors): if the image is presented from the cache, the
load event might fire, or might not fire (I guess the "might" is for when the browser presents a cached version and then replaces it with a new response?). The only thing you can do is check the
complete property of the element when the page loads, treat the image as if it's ready if it's
true, and then just debounce or re-evaluate the image if the
load event fires and the image was already completed.
What this model is missing is something like a
done event that fires if and when the browser decides that the
load event will not fire for the image (specifically, if it got a response like a 304 when requesting the image).
There appears to be some discussion about extending
<img> with Progress events, akin to XHR, but the spec for the
<img> element doesn't really seem to match the behavior I'm observing (particularly the tendency for the image to be
complete but still fire