Remove proxy for most images
I've noticed that our Fastly proxy adds a surprising amount of latency on cache misses (500-1000ms). And, while our overall hit ratio of 80% is pretty good, most misses happen at inopportune times, like loading items from search. But now that the Neopets CDN supports HTTPS, we can safely switch back to theirs for *most* image loads. (Some features, like downloads and movies, still require CORS headers, which our proxy is still reponsible for adding.) This forgoes some minor performance wins (like the Download button now requires separate network requests), and some potential filesize reduction opportunities (like Fastly's auto-gzip which we're today using for SVGs, and eventually using their Image Optimizer for assets), to decrease latency. We could still potentially do something more powerful for low-power connections someday… but for now, with the cache miss latency being *so* heavy, this seems like the clear win for almost certainly *all* users today.
This commit is contained in:
parent
beb606c6ca
commit
c2535f811f
4 changed files with 32 additions and 24 deletions
|
@ -607,7 +607,13 @@ function useDownloadableImage(visibleLayers) {
|
||||||
// performance (can use cached SVG), and predictability (image will
|
// performance (can use cached SVG), and predictability (image will
|
||||||
// look like what you see here).
|
// look like what you see here).
|
||||||
const imagePromises = visibleLayers.map((layer) =>
|
const imagePromises = visibleLayers.map((layer) =>
|
||||||
loadImage(getBestImageUrlForLayer(layer, { hiResMode }))
|
loadImage({
|
||||||
|
src: getBestImageUrlForLayer(layer, {
|
||||||
|
hiResMode,
|
||||||
|
crossOrigin: "anonymous",
|
||||||
|
}),
|
||||||
|
crossOrigin: "anonymous",
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
let images;
|
let images;
|
||||||
|
|
|
@ -290,7 +290,9 @@ export async function loadMovieLibrary(librarySrc) {
|
||||||
library.properties.manifest.map(({ id, src }) => [
|
library.properties.manifest.map(({ id, src }) => [
|
||||||
id,
|
id,
|
||||||
loadImage({
|
loadImage({
|
||||||
src: safeImageUrl(librarySrcDir + "/" + src),
|
src: safeImageUrl(librarySrcDir + "/" + src, {
|
||||||
|
crossOrigin: "anonymous",
|
||||||
|
}),
|
||||||
crossOrigin: "anonymous",
|
crossOrigin: "anonymous",
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
|
|
|
@ -262,16 +262,7 @@ export function OutfitLayers({
|
||||||
) : (
|
) : (
|
||||||
<Box
|
<Box
|
||||||
as="img"
|
as="img"
|
||||||
src={getBestImageUrlForLayer(layer, { hiResMode }).src}
|
src={getBestImageUrlForLayer(layer, { hiResMode })}
|
||||||
// The crossOrigin prop isn't strictly necessary for loading
|
|
||||||
// here (<img> tags are always allowed through CORS), but
|
|
||||||
// this means we make the same request that the Download
|
|
||||||
// button makes, so it can use the cached version of this
|
|
||||||
// image instead of requesting it again with crossOrigin!
|
|
||||||
crossOrigin={
|
|
||||||
getBestImageUrlForLayer(layer, { hiResMode })
|
|
||||||
.crossOrigin
|
|
||||||
}
|
|
||||||
alt=""
|
alt=""
|
||||||
objectFit="contain"
|
objectFit="contain"
|
||||||
maxWidth="100%"
|
maxWidth="100%"
|
||||||
|
@ -341,11 +332,14 @@ export function FullScreenCenter({ children, ...otherProps }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getBestImageUrlForLayer(layer, { hiResMode = false } = {}) {
|
export function getBestImageUrlForLayer(
|
||||||
|
layer,
|
||||||
|
{ hiResMode = false, crossOrigin = null } = {}
|
||||||
|
) {
|
||||||
if (hiResMode && layer.svgUrl) {
|
if (hiResMode && layer.svgUrl) {
|
||||||
return { src: safeImageUrl(layer.svgUrl), crossOrigin: "anonymous" };
|
return safeImageUrl(layer.svgUrl, { crossOrigin });
|
||||||
} else {
|
} else {
|
||||||
return { src: safeImageUrl(layer.imageUrl), crossOrigin: "anonymous" };
|
return safeImageUrl(layer.imageUrl, { crossOrigin });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,12 +386,12 @@ export function usePreloadLayers(layers) {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return loadImage(getBestImageUrlForLayer(layer, { hiResMode })).then(
|
return loadImage({
|
||||||
(image) => ({
|
src: getBestImageUrlForLayer(layer, { hiResMode }),
|
||||||
type: "image",
|
}).then((image) => ({
|
||||||
image,
|
type: "image",
|
||||||
})
|
image,
|
||||||
);
|
}));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ export function useCommonStyles() {
|
||||||
/**
|
/**
|
||||||
* safeImageUrl returns an HTTPS-safe image URL for Neopets assets!
|
* safeImageUrl returns an HTTPS-safe image URL for Neopets assets!
|
||||||
*/
|
*/
|
||||||
export function safeImageUrl(urlString) {
|
export function safeImageUrl(urlString, { crossOrigin = null } = {}) {
|
||||||
if (urlString == null) {
|
if (urlString == null) {
|
||||||
return urlString;
|
return urlString;
|
||||||
}
|
}
|
||||||
|
@ -141,12 +141,18 @@ export function safeImageUrl(urlString) {
|
||||||
return "https://impress-2020.openneo.net/__error__URL-was-not-parseable__";
|
return "https://impress-2020.openneo.net/__error__URL-was-not-parseable__";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rewrite Neopets URLs to their HTTPS equivalents, or to our proxy if we
|
||||||
|
// need CORS headers.
|
||||||
if (url.origin === "http://images.neopets.com") {
|
if (url.origin === "http://images.neopets.com") {
|
||||||
url.protocol = "https:";
|
url.protocol = "https:";
|
||||||
url.host = "images.neopets-asset-proxy.openneo.net";
|
if (crossOrigin) {
|
||||||
|
url.host = "images.neopets-asset-proxy.openneo.net";
|
||||||
|
}
|
||||||
} else if (url.origin === "http://pets.neopets.com") {
|
} else if (url.origin === "http://pets.neopets.com") {
|
||||||
url.protocol = "https:";
|
url.protocol = "https:";
|
||||||
url.host = "pets.neopets-asset-proxy.openneo.net";
|
if (crossOrigin) {
|
||||||
|
url.host = "pets.neopets-asset-proxy.openneo.net";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (url.protocol !== "https:") {
|
if (url.protocol !== "https:") {
|
||||||
|
|
Loading…
Reference in a new issue