fix: check srcset when hydrating to prevent needless requests

fixes #8838
pull/8868/head
Simon Holthausen 3 years ago
parent 1c7ed55385
commit 015b7ae7d7

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: check srcset when hydrating to prevent needless requests

@ -64,6 +64,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
/** @type {boolean} */ /** @type {boolean} */
is_src; is_src;
/** @type {boolean} */
is_srcset;
/** @type {boolean} */ /** @type {boolean} */
is_select_value_attribute; is_select_value_attribute;
@ -120,6 +123,9 @@ export default class AttributeWrapper extends BaseAttributeWrapper {
this.is_src = this.is_src =
this.name === 'src' && this.name === 'src' &&
(!this.parent.node.namespace || this.parent.node.namespace === namespaces.html); (!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); this.should_cache = should_cache(this);
} }
@ -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});` 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});`; 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) { } else if (property_name) {
block.chunks.hydrate.push(b`${element.var}.${property_name} = ${init};`); block.chunks.hydrate.push(b`${element.var}.${property_name} = ${init};`);
updater = block.renderer.options.dev updater = block.renderer.options.dev
@ -403,7 +414,7 @@ Object.keys(attribute_lookup).forEach((name) => {
/** @param {AttributeWrapper} attribute */ /** @param {AttributeWrapper} attribute */
function should_cache(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/; const regex_contains_checked_or_group = /checked|group/;

@ -68,7 +68,11 @@ export function safe_not_equal(a, b) {
let src_url_equal_anchor; let src_url_equal_anchor;
/** @returns {boolean} */ /**
* @param {string} element_src
* @param {string} url
* @returns {boolean}
*/
export function src_url_equal(element_src, url) { export function src_url_equal(element_src, url) {
if (!src_url_equal_anchor) { if (!src_url_equal_anchor) {
src_url_equal_anchor = document.createElement('a'); src_url_equal_anchor = document.createElement('a');
@ -77,6 +81,26 @@ export function src_url_equal(element_src, url) {
return element_src === src_url_equal_anchor.href; 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} */ /** @returns {boolean} */
export function not_equal(a, b) { export function not_equal(a, b) {
return a != a ? b == b : a !== b; return a != a ? b == b : a !== b;

Loading…
Cancel
Save