Skip to content

Commit 015b7ae

Browse files
committed
fix: check srcset when hydrating to prevent needless requests
fixes #8838
1 parent 1c7ed55 commit 015b7ae

File tree

3 files changed

+42
-2
lines changed

3 files changed

+42
-2
lines changed

.changeset/six-teachers-divide.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'svelte': patch
3+
---
4+
5+
fix: check srcset when hydrating to prevent needless requests

packages/svelte/src/compiler/compile/render_dom/wrappers/Element/Attribute.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
6464
/** @type {boolean} */
6565
is_src;
6666

67+
/** @type {boolean} */
68+
is_srcset;
69+
6770
/** @type {boolean} */
6871
is_select_value_attribute;
6972

@@ -120,6 +123,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
120123
this.is_src =
121124
this.name === 'src' &&
122125
(!this.parent.node.namespace || this.parent.node.namespace === namespaces.html);
126+
this.is_srcset =
127+
this.name === 'srcset' &&
128+
(!this.parent.node.namespace || this.parent.node.namespace === namespaces.html);
123129
this.should_cache = should_cache(this);
124130
}
125131

@@ -164,6 +170,11 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
164170
b`if (!@src_url_equal(${element.var}.src, ${init})) ${method}(${element.var}, "${name}", ${this.last});`
165171
);
166172
updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`;
173+
} else if (this.is_srcset) {
174+
block.chunks.hydrate.push(
175+
b`if (!@srcset_url_equal(${element.var}, ${init})) ${method}(${element.var}, "${name}", ${this.last});`
176+
);
177+
updater = b`${method}(${element.var}, "${name}", ${should_cache ? this.last : value});`;
167178
} else if (property_name) {
168179
block.chunks.hydrate.push(b`${element.var}.${property_name} = ${init};`);
169180
updater = block.renderer.options.dev
@@ -403,7 +414,7 @@ Object.keys(attribute_lookup).forEach((name) => {
403414

404415
/** @param {AttributeWrapper} attribute */
405416
function should_cache(attribute) {
406-
return attribute.is_src || attribute.node.should_cache();
417+
return attribute.is_src || attribute.is_srcset || attribute.node.should_cache();
407418
}
408419
const regex_contains_checked_or_group = /checked|group/;
409420

packages/svelte/src/runtime/internal/utils.js

+25-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ export function safe_not_equal(a, b) {
6868

6969
let src_url_equal_anchor;
7070

71-
/** @returns {boolean} */
71+
/**
72+
* @param {string} element_src
73+
* @param {string} url
74+
* @returns {boolean}
75+
*/
7276
export function src_url_equal(element_src, url) {
7377
if (!src_url_equal_anchor) {
7478
src_url_equal_anchor = document.createElement('a');
@@ -77,6 +81,26 @@ export function src_url_equal(element_src, url) {
7781
return element_src === src_url_equal_anchor.href;
7882
}
7983

84+
/**
85+
* @param {HTMLSourceElement | HTMLImageElement} element_srcset
86+
* @param {string} srcset
87+
* @returns {boolean}
88+
*/
89+
export function srcset_url_equal(element_srcset, srcset) {
90+
/** @param {string} _srcset */
91+
function split(_srcset) {
92+
return _srcset.split(',').map((src) => src.trim().split(' ')[0]);
93+
}
94+
95+
const element_urls = split(element_srcset.srcset);
96+
const urls = split(srcset);
97+
98+
return (
99+
urls.length === element_urls.length &&
100+
urls.every((url, i) => src_url_equal(element_urls[i], url))
101+
);
102+
}
103+
80104
/** @returns {boolean} */
81105
export function not_equal(a, b) {
82106
return a != a ? b == b : a !== b;

0 commit comments

Comments
 (0)