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

<bugzilla version="5.0.4"
          urlbase="https://www.w3.org/Bugs/Public/"
          
          maintainer="sysbot+bugzilla@w3.org"
>

    <bug>
          <bug_id>24711</bug_id>
          
          <creation_ts>2014-02-18 12:36:21 +0000</creation_ts>
          <short_desc>&lt;img&gt;: Refactor the image loading model</short_desc>
          <delta_ts>2014-06-16 18:41:44 +0000</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WHATWG</product>
          <component>HTML</component>
          <version>unspecified</version>
          <rep_platform>Other</rep_platform>
          <op_sys>other</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc>http://www.whatwg.org/specs/web-apps/current-work/#update-the-image-data</bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>normal</bug_severity>
          <target_milestone>Unsorted</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter>contributor</reporter>
          <assigned_to name="Simon Pieters">zcorpan</assigned_to>
          <cc>annevk</cc>
    
    <cc>bzbarsky</cc>
    
    <cc>ian</cc>
    
    <cc>johns</cc>
    
    <cc>mike</cc>
    
    <cc>zcorpan</cc>
          
          <qa_contact>contributor</qa_contact>

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>100798</commentid>
    <comment_count>0</comment_count>
    <who name="">contributor</who>
    <bug_when>2014-02-18 12:36:21 +0000</bug_when>
    <thetext>Specification: http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html
Multipage: http://www.whatwg.org/C#update-the-image-data
Complete: http://www.whatwg.org/c#update-the-image-data
Referrer: http://www.whatwg.org/specs/web-apps/current-work/multipage/

Comment:
Should probably only abort the fetch if the selected source is different from
the last selected source. (step 2)

Posted from: 90.230.218.37 by simonp@opera.com
User agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.90 Safari/537.1</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101287</commentid>
    <comment_count>1</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-02-24 23:13:39 +0000</bug_when>
    <thetext>This test says Safari/Chrome do what the spec says:
   http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2840
...whereas Firefox does what you suggest.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101288</commentid>
    <comment_count>2</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-02-24 23:22:31 +0000</bug_when>
    <thetext>Nevermind, that test is busted.

This shows that Safari/Chrome do what you suggest, but Firefox does what the spec says: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2845</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101426</commentid>
    <comment_count>3</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-02-26 07:17:40 +0000</bug_when>
    <thetext>OK, good that there is impl precedent. :-)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101437</commentid>
    <comment_count>4</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-02-26 15:39:37 +0000</bug_when>
    <thetext>Any Firefox people want to make a case for leaving the spec as is rather than changing to the arguably better behaviour of not aborting the load in the redundant case? (Note that this doesn&apos;t affect srcset changes based on environment changes, since those loads use a different algorithm.)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101438</commentid>
    <comment_count>5</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-02-26 15:53:23 +0000</bug_when>
    <thetext>&gt; This shows that Safari/Chrome do what you suggest, but Firefox does what the
&gt; spec says: http://software.hixie.ch/utilities/js/live-dom-viewer/saved/2845

How does this testcase show anything about the behavior?

The main hard web compat constraint here I&apos;m aware of is that given a loaded image, setting its src to the same value should check whether it&apos;s expired (HTTP caching semantics) and if so reload the image.  Gecko implements this by just always forcing a load on src set; if there is an existing load (whether done or not), it&apos;s dropped to make way for the new one.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101565</commentid>
    <comment_count>6</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-02-28 00:16:13 +0000</bug_when>
    <thetext>slow-second-dim.cgi is a script that takes 3 seconds and returns an image whose width equals the current time&apos;s seconds component. I should probably have mentioned that. :-)

This bug is just about whether to drop the existing load and trigger a new one, or defer to an already-in-flight load if there is one. I don&apos;t think it affects the compat need mentioned in comment 5, since either way we are doing a load.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101598</commentid>
    <comment_count>7</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-02-28 05:04:33 +0000</bug_when>
    <thetext>So what matters for the testcase is whether the two logged widths are identical?

&gt; or defer to an already-in-flight load if there is one.

This involves some fun defining of what makes for an in-flight load.  If the load has the image metadata but but not all the image data, is it in-flight?  If it&apos;s an animated gif and it has the first frame but not the other frames yet, is it in-flight?  If the bits are off the wire and in the image library but the DOM doesn&apos;t know anything about that yet, is the image in-flight?

I&apos;m probably OK trying to change Gecko&apos;s behavior here assuming there&apos;s a clear spec and a good reason to make the change, but it would be pretty low priority, I suspect.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101664</commentid>
    <comment_count>8</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-02-28 22:00:01 +0000</bug_when>
    <thetext>bz: Well from a spec perspective I would just define it as an ongoing instance of the &quot;fetch&quot; algorithm. In practice the edge cases are a race condition that I don&apos;t think your could black-box text anyway, so it probably doesn&apos;t need to be super-precise.

zcorpan: Your call. Do you still want to make this change given bz&apos;s comments? The spec&apos;s current state (what Firefox does) has fewer potential races...</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101672</commentid>
    <comment_count>9</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-02-28 22:05:46 +0000</bug_when>
    <thetext>You can black-box test things like &quot;size available, data is not&quot; to some extent, if you control the server...  Especially given animated gifs.  We&apos;ve run into problems with that sort of timing issue for images in the past.  :(</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101680</commentid>
    <comment_count>10</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-02-28 23:49:23 +0000</bug_when>
    <thetext>Those would both fall under &quot;an ongoing instance of the &quot;fetch&quot; algorithm&quot;.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101690</commentid>
    <comment_count>11</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-03-01 03:06:24 +0000</bug_when>
    <thetext>Yes, but is that compatible?

As in, if you do img.src = img.src on an image in that state, you&apos;re saying it should be a no-op.  Is that what UAs currently do in that situation and what sites expect?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101779</commentid>
    <comment_count>12</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-03-03 19:44:36 +0000</bug_when>
    <thetext>I dunno about what sites expect. From what I can tell, it&apos;s not what Gecko does, it is what Safari/Chrome do; see the test in comment 2.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101783</commentid>
    <comment_count>13</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-03-03 20:21:05 +0000</bug_when>
    <thetext>The test in comment 2 is not testing a partially-downloaded animated gif.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101784</commentid>
    <comment_count>14</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-03-03 20:23:03 +0000</bug_when>
    <thetext>To make my concern clearer:  I&apos;m willing to consider switching to another widely-implemented behavior.  I&apos;m less willing to consider switching to a simplified version of another widely-implemented behavior; we&apos;ve been bitten far too often recently by doing that and discovering that the differences in various edge cases meant the simplified version is not web-compatible.

A clear description from some WebKit/Blink folks about what their exact behavior is would be a good start in evaluating how happy I am with it...</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101876</commentid>
    <comment_count>15</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-03-04 23:56:58 +0000</bug_when>
    <thetext>Can you elaborate on your animated GIF concern? I guess I didn&apos;t understand what you meant by &quot;that state&quot; in comment 11.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101889</commentid>
    <comment_count>16</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-03-05 02:40:22 +0000</bug_when>
    <thetext>Say I have an animated gif.  The UA has some frames and has started showing them, but the rest of the data is coming in from the network so the fetch is still in progress.  Now the page does img.src = img.src on that gif.  What should happen?  Is a new network load started?  Does the animation get reset to the beginning?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101938</commentid>
    <comment_count>17</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-03-05 23:14:24 +0000</bug_when>
    <thetext>Crazy. With animated GIFs, I get the opposite result.

   http://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2869

I&apos;m very confused now.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>101960</commentid>
    <comment_count>18</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-03-06 03:27:13 +0000</bug_when>
    <thetext>Is that test testing network requests, or just whether the animation is restarted?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>102012</commentid>
    <comment_count>19</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-03-06 19:35:44 +0000</bug_when>
    <thetext>Both, though detecting a new request is a bit subtle (as far as I can tell, if it&apos;s a new request, you&apos;ll get a bigger pause between &quot;0&quot; and &quot;2&quot; than if the UA already has the data).

In the results below, a comma indicates a one-second-or-so pause, Z indicates that the log just had &quot;zapped&quot; added to it.

Chrome and Safari restart the animation, but don&apos;t start a new load.
That is, they render:
 (blank space),,0,,12,3,4,5Z,0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F.,0,1,2....

Firefox doesn&apos;t restart the animation until the load is over, and then it does. It doesn&apos;t actually trigger a new network request (according to the Web console, anyway. Not sure how reliably that is. But it matches the results — if there was a new request here, you&apos;d expect a stutter between the second &quot;0&quot; and &quot;2&quot;).
That is, it renders:
 (placeholder),,0,,2,3,4,5Z,6,7,8,9,A0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F.,0,1,2...

I guess the difference between this test and the earlier one is that here we have already started decoding by the time the URL changes? If that&apos;s what Firefox is relying on, it seems like a very race-prone design (more so even than just relying on the network connection being open — at least the author has some visibility into that on the client and server side via events, even if it&apos;s not precise).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>102014</commentid>
    <comment_count>20</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-03-06 19:55:39 +0000</bug_when>
    <thetext>Oh, I see part of the confusion here.

So what Gecko does is it can have up to two &quot;image requests&quot; per image element: a &quot;current&quot; one and a &quot;pending&quot; one.  An &quot;image request&quot; includes both the fetch and the resulting data.

When we go to do the equivalent of &quot;update the image data&quot;, we check whether the current request is in a state where we know the size of the image.  If it is, we make the new request a &quot;pending request&quot; and keep showing the old thing until the new request&apos;s size is available.  Then we drop the old &quot;current request&quot; and make the pending request be current.

The intent of the setup is that if you have an &lt;img&gt; whose src you set to different things every so often (like a slideshow, say), but the loads are slow you don&apos;t keep bouncing between &quot;showing an image&quot; and &quot;broken image, with different layout&quot;.  That&apos;s why the size-available check is important: that&apos;s when your layout is likely to stay stable.

I just tested Chrome, using a testcase like so:

&lt;!DOCTYPE html&gt;
&lt;img height=&apos;10&apos; src=&quot;http://software.hixie.ch/utilities/cgi/dynamic-images/second-dim.cgi&quot;&gt;
&lt;script&gt;
  onload = function() {
    document.querySelector(&quot;img&quot;).src = &quot;http://software.hixie.ch/utilities/cgi/dynamic-images/slow-second-dim.cgi&quot;;
  }
&lt;/script&gt;

and they also seem to keep the current image showing while the new one loads, as far as I can tell.  I don&apos;t know how they decide when to do that or not.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>102561</commentid>
    <comment_count>21</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-03-18 14:25:40 +0000</bug_when>
    <thetext>Comment 5 seems like a new spec bug. img.src = img.src is always a no-op per spec given the definition of &quot;change&quot; in http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#dom-trees

Comment 20 also seems like a new spec bug.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>102585</commentid>
    <comment_count>22</comment_count>
    <who name="Ian &apos;Hixie&apos; Hickson">ian</who>
    <bug_when>2014-03-18 17:51:22 +0000</bug_when>
    <thetext>comment 5 is bug 24958.

comment 20 seems like a core part of this bug, or at least a prereq. Sounds like I&apos;ll have to move the &lt;img&gt; section to that model before we can really figure out what to do for comment 0.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>102639</commentid>
    <comment_count>23</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-03-19 14:44:52 +0000</bug_when>
    <thetext>Yeah.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>106317</commentid>
    <comment_count>24</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-05-19 08:36:06 +0000</bug_when>
    <thetext>(In reply to Boris Zbarsky from comment #5)
&gt; The main hard web compat constraint here I&apos;m aware of is that given a loaded
&gt; image, setting its src to the same value should check whether it&apos;s expired
&gt; (HTTP caching semantics) and if so reload the image.  Gecko implements this
&gt; by just always forcing a load on src set; if there is an existing load
&gt; (whether done or not), it&apos;s dropped to make way for the new one.

I can&apos;t get Firefox 26 to reload the image when setting src to the same value. Is the compat constraint just restarting the animation? As far as I can tell animations are restarted even if it&apos;s not expired.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>106352</commentid>
    <comment_count>25</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-05-19 15:55:09 +0000</bug_when>
    <thetext>&gt; I can&apos;t get Firefox 26 to reload the image when setting src to the same value.

How are you determining that?  Note that the &quot;reload&quot; will still follow HTTP cache semantics...

&gt; Is the compat constraint just restarting the animation?

I don&apos;t believe so, given https://bugzilla.mozilla.org/show_bug.cgi?id=980243</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>106416</commentid>
    <comment_count>26</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-05-20 02:31:37 +0000</bug_when>
    <thetext>(In reply to Boris Zbarsky from comment #25)
&gt; &gt; I can&apos;t get Firefox 26 to reload the image when setting src to the same value.
&gt; 
&gt; How are you determining that?  Note that the &quot;reload&quot; will still follow HTTP
&gt; cache semantics...

https://github.com/zcorpan/web-platform-tests/blob/img-bug-24711/html/semantics/embedded-content/the-img-element/update-the-image-data/set-src-idl-same-value-loaded-not-cacheable.html
https://github.com/zcorpan/web-platform-tests/blob/img-bug-24711/html/semantics/embedded-content/the-img-element/update-the-image-data/resources/common.js
https://github.com/zcorpan/web-platform-tests/blob/img-bug-24711/html/semantics/embedded-content/the-img-element/update-the-image-data/resources/stash-count-requests.py

Review for the tests at https://critic.hoppipolla.co.uk/r/1593

So what the test is doing is that it loads an image with the headers:

Cache-Control: no-store, no-cache, must-revalidate
Expires: Tue, 19 Nov 1985 21:00:00 GMT

Then, in img.onload, it does img.src = url_put; (which is the same value).

The test counts the number of requests on the server side and I only see 1 request in Firefox 26 for this test.

&gt; I don&apos;t believe so, given https://bugzilla.mozilla.org/show_bug.cgi?id=980243

OK, thanks.

(I also found https://bugzilla.mozilla.org/show_bug.cgi?id=183470 which seems related.)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>106420</commentid>
    <comment_count>27</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-05-20 03:36:27 +0000</bug_when>
    <thetext>&gt; So what the test is doing is that it loads an image with the headers:

Is there a live version of the test somewhere I could take a look at?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>106423</commentid>
    <comment_count>28</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-05-20 05:39:35 +0000</bug_when>
    <thetext>http://w3c-test.org/submissions/996/html/semantics/embedded-content/the-img-element/update-the-image-data/set-src-idl-same-value-loaded-not-cacheable.html

(When the PR gets merged in the future, remove &quot;submissions/996/&quot; from the URL.)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>106541</commentid>
    <comment_count>29</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-05-21 06:25:26 +0000</bug_when>
    <thetext>Hmm.  Looks like there&apos;s some deal in Gecko now that basically assumes non-HTTP semantics are OK as long as the document is the same...  So maybe resetting animations (and perhaps firing load events; unclear) is all that&apos;s needed for compat.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>106542</commentid>
    <comment_count>30</comment_count>
    <who name="Boris Zbarsky">bzbarsky</who>
    <bug_when>2014-05-21 06:26:18 +0000</bug_when>
    <thetext>And thank you for the link, by the way!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107843</commentid>
    <comment_count>31</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-06-16 10:45:45 +0000</bug_when>
    <thetext>Specify how parallel image fetching works.
https://github.com/ResponsiveImagesCG/picture-element/commit/22efd4478d7714ac12fd128ca2c455d0f91f42a4

(Leaving open for comment 0.)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>107861</commentid>
    <comment_count>32</comment_count>
    <who name="Simon Pieters">zcorpan</who>
    <bug_when>2014-06-16 18:41:44 +0000</bug_when>
    <thetext>Reuse ongoing fetches in &apos;update the image data&apos;.
https://github.com/ResponsiveImagesCG/picture-element/commit/a67d019f75f95ec3552adc36376522059c582ccc</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>