Skip to content

Commit

Permalink
fix: check srcset when hydrating to prevent needless requests
Browse files Browse the repository at this point in the history
fixes #8838
  • Loading branch information
dummdidumm committed Jun 28, 2023
1 parent 1c7ed55 commit 015b7ae
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/six-teachers-divide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte': patch
---

fix: check srcset when hydrating to prevent needless requests
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
/** @type {boolean} */
is_src;

/** @type {boolean} */
is_srcset;

/** @type {boolean} */
is_select_value_attribute;

Expand Down Expand Up @@ -120,6 +123,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
this.is_src =
this.name === 'src' &&
(!this.parent.node.namespace || this.parent.node.namespace === namespaces.html);
this.is_srcset =
this.name === 'srcset' &&
(!this.parent.node.namespace || this.parent.node.namespace === namespaces.html);
this.should_cache = should_cache(this);
}

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

/** @param {AttributeWrapper} attribute */
function should_cache(attribute) {
return attribute.is_src || attribute.node.should_cache();
return attribute.is_src || attribute.is_srcset || attribute.node.should_cache();
}
const regex_contains_checked_or_group = /checked|group/;

Expand Down
26 changes: 25 additions & 1 deletion packages/svelte/src/runtime/internal/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ export function safe_not_equal(a, b) {

let src_url_equal_anchor;

/** @returns {boolean} */
/**
* @param {string} element_src
* @param {string} url
* @returns {boolean}
*/
export function src_url_equal(element_src, url) {
if (!src_url_equal_anchor) {
src_url_equal_anchor = document.createElement('a');
Expand All @@ -77,6 +81,26 @@ export function src_url_equal(element_src, url) {
return element_src === src_url_equal_anchor.href;
}

/**
* @param {HTMLSourceElement | HTMLImageElement} element_srcset
* @param {string} srcset
* @returns {boolean}
*/
export function srcset_url_equal(element_srcset, srcset) {
/** @param {string} _srcset */
function split(_srcset) {
return _srcset.split(',').map((src) => src.trim().split(' ')[0]);
}

const element_urls = split(element_srcset.srcset);
const urls = split(srcset);

return (
urls.length === element_urls.length &&
urls.every((url, i) => src_url_equal(element_urls[i], url))
);
}

/** @returns {boolean} */
export function not_equal(a, b) {
return a != a ? b == b : a !== b;
Expand Down

0 comments on commit 015b7ae

Please sign in to comment.