NEW322584
Image loads start in the same task as the src assignment instead of a microtask later, so a src set twice in one task requests both
https://bugs.webkit.org/show_bug.cgi?id=322584
Summary Image loads start in the same task as the src assignment instead of a microta...
Karl Dubost
Reported 2026-08-26 03:06:31 PDT
Created attachment 481165 [details] testcase-microtask.html followup on Bug 6656 "Update the image data" is required to stop partway through and finish one microtask later. Step 8: "Queue a microtask to perform the rest of this algorithm, allowing the task that invoked this algorithm to continue." Step 9 then discards anything but the newest run: "If another instance of this algorithm for this img element was started after this instance (even if it aborted and is no longer running), then return." Note: "Only the last instance takes effect, to avoid multiple requests when, for example, the src, srcset, and crossorigin attributes are all set in succession." https://html.spec.whatwg.org/multipage/images.html#updating-the-image-data WebKit runs the whole algorithm synchronously from the attribute change, so the pause the spec asks for does not exist.
Attachments
testcase-microtask.html (3.67 KB, text/html)
2026-08-26 03:06 PDT, Karl Dubost
no flags
Karl Dubost
Comment 1 2026-08-26 03:08:28 PDT
Two consequences, both in the attached testcase. First, the current request is updated too early, which is directly observable: const img = new Image(); img.src = "image-a.png"; img.currentSrc // must still be "", WebKit returns the resolved URL Second, and this is the part that costs bandwidth, an assignment that is immediately replaced is fetched anyway: const img = new Image(); img.src = "image-b.png"; img.src = "image-c.png"; // same task Only image-c.png may be requested. WebKit requests both, and reads image-b.png to completion. Measured on the same machine, 2026-08-26: STP 251 Chrome 154 Firefox 156 currentSrc empty in the same task FAIL PASS PASS src set twice in one task, requests for the first 1 0 0 With a 3.00 MB image on the first URL, STP downloads all 3.00 MB of it. Chrome and Firefox never ask for it. The practical case is the lazy-loading pattern in comment 17 and comment 18 of bug 6656: a MutationObserver watches for images being inserted and swaps src for a small placeholder before anything is meant to load. That works when the fetch waits a microtask and does not work when it does not. Same three engines, cost of one image the page has already said it does not want: Firefox 156 nothing, the request is never made Chrome 154 32 kB, aborted after 40 ms STP 251 3.00 MB, downloaded in full There is already test coverage in the tree, and it is already failing. Under imported/w3c/web-platform-tests/html/semantics/embedded-content/the-img-element/update-the-image-data/ current-request-microtask-expected.txt 1 FAIL current-request-microtask-002-expected.txt 1 FAIL src-then-lazy-load-expected.txt 8 FAIL lazy-out-of-band-load-expected.txt 4 FAIL 14 subtests. The last two set src and then loading="lazy" in the same task, so nothing should load at all, and assert_unreached fires on the load event.
Radar WebKit Bug Importer
Comment 2 2026-09-02 03:07:13 PDT
Note You need to log in before you can comment on or make changes to this bug.