Avoid triggering spurious downloads for no-store responsive images

When responsive images are not cached in the memory cache (due to
`no-store` or devtools settings) and the viewport is being resized,
that triggers spurious downloads.

This CL fixes that, by aligning to the spec (somewhat) and making sure
that viewport changes that don't modify the image URL do not trigger a
resource load.

Bug: 960633
Change-Id: I8105bcf5dbef99767ac704872800f4d417caf8b7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1622168
Reviewed-by: Fredrik Söderquist <fs@opera.com>
Commit-Queue: Yoav Weiss <yoavweiss@chromium.org>
Cr-Commit-Position: refs/heads/master@{#664269}
diff --git a/third_party/blink/renderer/core/html/html_image_element.cc b/third_party/blink/renderer/core/html/html_image_element.cc
index b47fb7d..5941d76 100644
--- a/third_party/blink/renderer/core/html/html_image_element.cc
+++ b/third_party/blink/renderer/core/html/html_image_element.cc
@@ -745,9 +745,17 @@
         FastGetAttribute(kSrcAttr), FastGetAttribute(kSrcsetAttr),
         &GetDocument());
   }
+  AtomicString old_url = best_fit_image_url_;
   SetBestFitURLAndDPRFromImageCandidate(candidate);
 
-  GetImageLoader().UpdateFromElement(behavior, referrer_policy_);
+  // Step 5 in
+  // https://html.spec.whatwg.org/multipage/images.html#reacting-to-environment-changes
+  // Deliberately not compliant and avoiding checking image density, to avoid
+  // spurious downloads. See https://github.com/whatwg/html/issues/4646
+  if (behavior != HTMLImageLoader::kUpdateSizeChanged ||
+      best_fit_image_url_ != old_url) {
+    GetImageLoader().UpdateFromElement(behavior, referrer_policy_);
+  }
 
   ImageResourceContent* image_content = GetImageLoader().GetContent();
   // Images such as data: uri's can return immediately and may already have
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/avoid-reload-on-resize.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/avoid-reload-on-resize.html
new file mode 100644
index 0000000..a8038e5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/avoid-reload-on-resize.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>Avoid srcset image reloads when viewport resizes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({explicit_done:true});
+const image_was_loaded = () => {
+  const iframe = document.getElementById("iframe");
+  // Resize the iframe
+  iframe.width="400";
+  // Wait 500 ms
+  step_timeout(() => {
+    // Check that the iframe only loaded a single resource
+    const entries = iframe.contentWindow.performance.getEntriesByType("resource");
+    assert_equals(entries.length, 1);
+    done();
+  }, 500);
+}
+</script>
+<iframe id=iframe width="401" src="resources/resized.html" onload="image_was_loaded()"></iframe>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png
new file mode 120000
index 0000000..c0d95fa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png
@@ -0,0 +1 @@
+../../image.png
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png.headers b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png.headers
new file mode 100644
index 0000000..edaec7a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/image.png.headers
@@ -0,0 +1,3 @@
+Cache-Control: no-store
+
+
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/resized.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/resized.html
new file mode 100644
index 0000000..6fb6847
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/srcset/resources/resized.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<img srcset="image.png?400 400w, image.png?800 800w, image.png?1600 1600w" sizes="50vw">