mirror of
https://github.com/captbaritone/webamp.git
synced 2026-07-26 03:24:18 +00:00
Cancel image downloads when scrolling qickly (FF/Chrome)
This commit is contained in:
parent
a5085adbcc
commit
ce95cd9e6a
2 changed files with 34 additions and 1 deletions
32
src/components/CancelableImg.js
Normal file
32
src/components/CancelableImg.js
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
import React, { useState, useEffect } from "react";
|
||||
|
||||
// When the user is scrolling quickly, we can render a ton of images. So many
|
||||
// that we saturate the number of concurrent network requests that the browser
|
||||
// will allow.
|
||||
//
|
||||
// With a naive implement, this leads to images that are in the viewport being
|
||||
// blocked because images that we've scrolled past are still in the queue to
|
||||
// download. By removing the `src` attribute, we signal to the browser that the
|
||||
// request can be canceled.
|
||||
//
|
||||
// Another approach I tried was issuing a `fetch` request for the image with an
|
||||
// `AbortController` to allow canceling on unmount, and only adding the `src` to
|
||||
// the image _after_ the `fetch` completed. The ideas was that the `<img>` would
|
||||
// end up loading the image from the cache which was warmed by `fetch`. However,
|
||||
// on Safari, it looks like it ends up making two requests. Perhaps it thinks
|
||||
// the fetch/img requests look too different due to different headers or
|
||||
// something.
|
||||
export default function CancelableImg(props) {
|
||||
const [ref, setRef] = useState(null);
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (ref != null) {
|
||||
// This will cause Chrome and Firefox to cancel the request.
|
||||
// Safari does not seem to get the message.
|
||||
ref.removeAttribute("src");
|
||||
}
|
||||
};
|
||||
}, [ref]);
|
||||
|
||||
return <img {...props} ref={setRef} />;
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
import React, { useState, useCallback } from "react";
|
||||
import * as Utils from "../utils";
|
||||
import { SCREENSHOT_HEIGHT } from "../constants";
|
||||
import CancelableImg from "./CancelableImg";
|
||||
|
||||
function Skin({
|
||||
style,
|
||||
|
|
@ -85,7 +86,7 @@ function Skin({
|
|||
onClick={clickHandler}
|
||||
href={permalink}
|
||||
>
|
||||
<img
|
||||
<CancelableImg
|
||||
tabIndex={1}
|
||||
src={src}
|
||||
style={imgStyle}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue