<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>322584</bug_id>
          
          <creation_ts>2026-08-26 03:06:31 -0700</creation_ts>
          <short_desc>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</short_desc>
          <delta_ts>2026-09-02 03:07:13 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>Page Loading</component>
          <version>Safari 26</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>NEW</bug_status>
          <resolution></resolution>
          
          <see_also>https://bugs.webkit.org/show_bug.cgi?id=6656</see_also>
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>HasReduction, InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Karl Dubost">karlcow</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>beidson</cc>
    
    <cc>webkit-bug-importer</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>2243815</commentid>
    <comment_count>0</comment_count>
      <attachid>481165</attachid>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2026-08-26 03:06:31 -0700</bug_when>
    <thetext>Created attachment 481165
testcase-microtask.html

followup on Bug 6656

&quot;Update the image data&quot; is required to stop partway through and finish one microtask later. Step 8:

&quot;Queue a microtask to perform the rest of this algorithm, allowing the task that invoked this algorithm to continue.&quot;
Step 9 then discards anything but the newest run:

&quot;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.&quot;
Note: &quot;Only the last instance takes effect, to avoid multiple requests when, for example, the src, srcset, and crossorigin attributes are all set in succession.&quot;
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.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2243817</commentid>
    <comment_count>1</comment_count>
    <who name="Karl Dubost">karlcow</who>
    <bug_when>2026-08-26 03:08:28 -0700</bug_when>
    <thetext>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 = &quot;image-a.png&quot;;
img.currentSrc            // must still be &quot;&quot;, 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 = &quot;image-b.png&quot;;
img.src = &quot;image-c.png&quot;;  // 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=&quot;lazy&quot; in the same task, so nothing should load at all, and assert_unreached fires on the load event.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>2246311</commentid>
    <comment_count>2</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2026-09-02 03:07:13 -0700</bug_when>
    <thetext>&lt;rdar://problem/186446580&gt;</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="0"
              isprivate="0"
          >
            <attachid>481165</attachid>
            <date>2026-08-26 03:06:31 -0700</date>
            <delta_ts>2026-08-26 03:06:31 -0700</delta_ts>
            <desc>testcase-microtask.html</desc>
            <filename>testcase-microtask.html</filename>
            <type>text/html</type>
            <size>3757</size>
            <attacher name="Karl Dubost">karlcow</attacher>
            
              <data encoding="base64">PCFET0NUWVBFIGh0bWw+CjxtZXRhIGNoYXJzZXQ9InV0Zi04Ij4KPHRpdGxlPkltYWdlIGxvYWRz
IHNob3VsZCBub3Qgc3RhcnQgdW50aWwgYSBtaWNyb3Rhc2sgYWZ0ZXIgdGhlIHNyYyBhc3NpZ25t
ZW50PC90aXRsZT4KPHN0eWxlPgogIGJvZHkgeyBmb250OiAxNHB4LzEuNSAtYXBwbGUtc3lzdGVt
LCBzeXN0ZW0tdWksIHNhbnMtc2VyaWY7IG1hcmdpbjogMnJlbTsgbWF4LXdpZHRoOiA2MHJlbTsg
fQogIHRhYmxlIHsgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsgbWFyZ2luOiAxcmVtIDA7IH0K
ICB0aCwgdGQgeyBib3JkZXI6IDFweCBzb2xpZCAjOTk5OyBwYWRkaW5nOiAuM3JlbSAuNnJlbTsg
dGV4dC1hbGlnbjogbGVmdDsgfQogIC5wYXNzIHsgY29sb3I6ICMwYTdjMmY7IGZvbnQtd2VpZ2h0
OiA2MDA7IH0KICAuZmFpbCB7IGNvbG9yOiAjYzAyNzFhOyBmb250LXdlaWdodDogNjAwOyB9CiAg
LnNraXAgeyBjb2xvcjogIzc3NzsgfQogIGNvZGUgeyBmb250LXNpemU6IDEycHg7IHdvcmQtYnJl
YWs6IGJyZWFrLWFsbDsgfQo8L3N0eWxlPgoKPGgxPkltYWdlIGxvYWRzIHNob3VsZCBub3Qgc3Rh
cnQgdW50aWwgYSBtaWNyb3Rhc2sgYWZ0ZXIgdGhlIHNyYyBhc3NpZ25tZW50PC9oMT4KCjxwPkhU
TUwgInVwZGF0ZSB0aGUgaW1hZ2UgZGF0YSIsIHN0ZXAgODogPGVtPiJRdWV1ZSBhIG1pY3JvdGFz
ayB0byBwZXJmb3JtIHRoZSByZXN0IG9mIHRoaXMKYWxnb3JpdGhtLCBhbGxvd2luZyB0aGUgdGFz
ayB0aGF0IGludm9rZWQgdGhpcyBhbGdvcml0aG0gdG8gY29udGludWUuIjwvZW0+IFN0ZXAgOSB0
aGVuIHJldHVybnMKZWFybHkgaWYgYSBsYXRlciBpbnN0YW5jZSBvZiB0aGUgYWxnb3JpdGhtIGhh
cyBzdGFydGVkLCB3aXRoIHRoZSBub3RlIDxlbT4iT25seSB0aGUgbGFzdCBpbnN0YW5jZQp0YWtl
cyBlZmZlY3QsIHRvIGF2b2lkIG11bHRpcGxlIHJlcXVlc3RzLiI8L2VtPjwvcD4KCjxwPjxhIGhy
ZWY9Imh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2ltYWdlcy5odG1sI3Vw
ZGF0aW5nLXRoZS1pbWFnZS1kYXRhIj5odHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRp
cGFnZS9pbWFnZXMuaHRtbCN1cGRhdGluZy10aGUtaW1hZ2UtZGF0YTwvYT48L3A+Cgo8cD5DYXNl
IDMgbmVlZHMgdGhlIHBhZ2Ugc2VydmVkIG92ZXIgaHR0cCBvciBodHRwcywgYmVjYXVzZSBpdCBy
ZWFkcyBSZXNvdXJjZSBUaW1pbmcuIENhc2VzIDEKYW5kIDIgd29yayBmcm9tIGEgZmlsZTovLyBV
UkwgdG9vLiBUaGUgaW1hZ2UgVVJMcyBkbyBub3QgbmVlZCB0byBleGlzdDogYSA0MDQgc3RpbGwg
c2hvd3Mgd2hldGhlcgp0aGUgcmVxdWVzdCB3YXMgbWFkZS48L3A+Cgo8dGFibGUgaWQ9Im91dCI+
CiAgPHRyPjx0aD4jPC90aD48dGg+Q2hlY2s8L3RoPjx0aD5FeHBlY3RlZDwvdGg+PHRoPkFjdHVh
bDwvdGg+PHRoPjwvdGg+PC90cj4KPC90YWJsZT4KCjxzY3JpcHQ+CmNvbnN0IFQgPSBNYXRoLnJh
bmRvbSgpLnRvU3RyaW5nKDM2KS5zbGljZSgyLCA4KTsKY29uc3QgQSA9IGBpbWFnZS1hLnBuZz90
PSR7VH1gOwpjb25zdCBCID0gYGltYWdlLWIucG5nP3Q9JHtUfWA7CmNvbnN0IEMgPSBgaW1hZ2Ut
Yy5wbmc/dD0ke1R9YDsKY29uc3QgYWJzID0gdSA9PiBuZXcgVVJMKHUsIGxvY2F0aW9uLmhyZWYp
LmhyZWY7CmNvbnN0IHJvd3MgPSBbXTsKCmZ1bmN0aW9uIHJvdyhuLCBjaGVjaywgZXhwZWN0ZWQs
IGFjdHVhbCwgb2spIHsKICByb3dzLnB1c2goeyBuLCBjaGVjaywgZXhwZWN0ZWQsIGFjdHVhbCwg
b2sgfSk7Cn0KCi8vIENhc2UgMS4gUmVhZGluZyBjdXJyZW50U3JjIGluIHRoZSBzYW1lIHRhc2sg
YXMgdGhlIGFzc2lnbm1lbnQuIFBlciBzdGVwIDggdGhlIHJlc3Qgb2YgdGhlCi8vIGFsZ29yaXRo
bSBoYXMgbm90IHJ1biB5ZXQsIHNvIHRoZSBjdXJyZW50IHJlcXVlc3QgaGFzIG5vIFVSTCBhbmQg
Y3VycmVudFNyYyBpcyBzdGlsbCBlbXB0eS4KY29uc3QgaTEgPSBuZXcgSW1hZ2UoKTsKaTEuc3Jj
ID0gQTsKcm93KDEsICdjdXJyZW50U3JjIGltbWVkaWF0ZWx5IGFmdGVyIGltZy5zcmMgPSBBJywg
JyIiJywgSlNPTi5zdHJpbmdpZnkoaTEuY3VycmVudFNyYyksCiAgICBpMS5jdXJyZW50U3JjID09
PSAnJyk7CgovLyBDYXNlIDIuIE9uZSBtaWNyb3Rhc2sgbGF0ZXIgaXQgc2hvdWxkIGJlIHRoZSBy
ZXNvbHZlZCBVUkwuIFRoaXMgaXMgdGhlIGNvbnRyb2w6IGl0IHNob3dzIHRoZQovLyB0ZXN0IGlz
IGxvb2tpbmcgYXQgdGhlIHJpZ2h0IHByb3BlcnR5IGFuZCB0aGF0IGNhc2UgMSBpcyBub3QgZmFp
bGluZyBmb3Igc29tZSB1bnJlbGF0ZWQgcmVhc29uLgpxdWV1ZU1pY3JvdGFzaygoKSA9PiB7CiAg
cm93KDIsICdjdXJyZW50U3JjIG9uZSBtaWNyb3Rhc2sgbGF0ZXIgKGNvbnRyb2wpJywgSlNPTi5z
dHJpbmdpZnkoYWJzKEEpKSwKICAgICAgSlNPTi5zdHJpbmdpZnkoaTEuY3VycmVudFNyYyksIGkx
LmN1cnJlbnRTcmMgPT09IGFicyhBKSk7CgogIC8vIENhc2UgMy4gc3JjIGFzc2lnbmVkIHR3aWNl
IGluIG9uZSB0YXNrLiBPbmx5IHRoZSBsYXN0IGluc3RhbmNlIG1heSB0YWtlIGVmZmVjdCwgc28g
QiBpcwogIC8vIHJlcXVlc3RlZCBhbmQgQSBuZXZlciBpcy4KICBjb25zdCBpMiA9IG5ldyBJbWFn
ZSgpOwogIGkyLnNyYyA9IEI7CiAgaTIuc3JjID0gQzsKICBkb2N1bWVudC5ib2R5LmFwcGVuZENo
aWxkKGkyKTsKCiAgc2V0VGltZW91dCgoKSA9PiB7CiAgICBpZiAobG9jYXRpb24ucHJvdG9jb2wg
PT09ICdmaWxlOicpIHsKICAgICAgcm93KDMsICdpbWcuc3JjID0gQjsgaW1nLnNyYyA9IEM7IGlu
IG9uZSB0YXNrLCByZXF1ZXN0cyBmb3IgQicsCiAgICAgICAgICAnMCcsICdub3QgbWVhc3VyYWJs
ZSBmcm9tIGZpbGU6Ly8nLCBudWxsKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnN0IG5hbWVzID0g
cGVyZm9ybWFuY2UuZ2V0RW50cmllc0J5VHlwZSgncmVzb3VyY2UnKS5tYXAoZSA9PiBlLm5hbWUp
OwogICAgICBjb25zdCBuQiA9IG5hbWVzLmZpbHRlcih1ID0+IHUuaW5jbHVkZXMoJ2ltYWdlLWIu
cG5nP3Q9JyArIFQpKS5sZW5ndGg7CiAgICAgIGNvbnN0IG5DID0gbmFtZXMuZmlsdGVyKHUgPT4g
dS5pbmNsdWRlcygnaW1hZ2UtYy5wbmc/dD0nICsgVCkpLmxlbmd0aDsKICAgICAgcm93KDMsICdp
bWcuc3JjID0gQjsgaW1nLnNyYyA9IEM7IGluIG9uZSB0YXNrLCByZXF1ZXN0cyBmb3IgQicsICcw
JywgU3RyaW5nKG5CKSwgbkIgPT09IDApOwogICAgICByb3coNCwgJ3NhbWUsIHJlcXVlc3RzIGZv
ciBDIChjb250cm9sKScsICcxJywgU3RyaW5nKG5DKSwgbkMgPT09IDEpOwogICAgfQogICAgcmVu
ZGVyKCk7CiAgfSwgMTAwMCk7Cn0pOwoKZnVuY3Rpb24gcmVuZGVyKCkgewogIGNvbnN0IHQgPSBk
b2N1bWVudC5nZXRFbGVtZW50QnlJZCgnb3V0Jyk7CiAgZm9yIChjb25zdCByIG9mIHJvd3MpIHsK
ICAgIGNvbnN0IHRyID0gdC5pbnNlcnRSb3coKTsKICAgIGNvbnN0IHZlcmRpY3QgPSByLm9rID09
PSBudWxsID8gWydza2lwJywgJ04vQSddIDogci5vayA/IFsncGFzcycsICdQQVNTJ10gOiBbJ2Zh
aWwnLCAnRkFJTCddOwogICAgdHIuaW5uZXJIVE1MID0gYDx0ZD4ke3Iubn08L3RkPjx0ZD4ke3Iu
Y2hlY2t9PC90ZD48dGQ+PGNvZGU+JHtyLmV4cGVjdGVkfTwvY29kZT48L3RkPmAgKwogICAgICAg
ICAgICAgICAgICAgYDx0ZD48Y29kZT4ke3IuYWN0dWFsfTwvY29kZT48L3RkPjx0ZCBjbGFzcz0i
JHt2ZXJkaWN0WzBdfSI+JHt2ZXJkaWN0WzFdfTwvdGQ+YDsKICB9Cn0KPC9zY3JpcHQ+Cg==
</data>

          </attachment>
      

    </bug>

</bugzilla>