mohitk05/react-insta-stories

Preloading images

slytter opened this issue · 6 comments

Hey thanks for a cool lib!

Am I right that react-insta-stories does not preload given images? From what I can see from the network profiler, it only loads an image when it is has become active on screen.

@ashmuradyann (#199) have suggested looping trough alle images with display:none, in order to preload the images. But I feel like this could be done more effectively e.g. by prioritizing loading of neighbouring images. Also shouldn't it preloading be a priority feature or what is your take on this @mohitk05?

Thanks

Here is a simple implementation of how it could be done for both video and images, with the Story type. This loads stories in parallel (using Promise.all), but could also be loaded in sequence which would properly make it less expensive and load more 'linearly'.

import {Story} from "react-insta-stories/dist/interfaces";

export const cacheContent = async (contents: Story[]) => {
	const promises = contents.map((content) => {
		return new Promise(function (resolve, reject) {
			const xhr = new XMLHttpRequest();
			if(!content.url) return
			
			if(content.type === 'video') {
				xhr.responseType = 'blob';
				xhr.onload = function () {
					resolve(URL.createObjectURL(xhr.response));
				}
				xhr.onerror = reject
			}
			const img = new Image();
			img.src = content.url;
			img.onload = resolve;
			img.onerror = reject;
		})
	})
	await Promise.all(promises);
}

I currently run it in an effect, like so:

	useEffect(() => {
		if(!images) return;

		(async () => {
			await cacheContent(images);
		})()
	}, [images])

Hey @slytter, thanks for creating the issue. I remember implementing a simple preloading logic in the package, but I think it got removed during one of the refactors.

Your solution looks great, and I would do something similar to cache the content early. Any reason for using xhr though? I would assume if you directly create a new Image() or Video() and set the src attribute, it should load similarly, right?

Also, feel free to raise a PR, the solution can be integrated in the package itself. We should provide enough options to configure/disable it though.

Aight, might do a PR during the week :)
Yeah you're right with the xhr solution, properly simpler using Video().

Also how should the content load? Maybe it should load x slides forward from the current cursor, such that it is not loading all content at once. Considering doing a preload: boolean prop and a preloadCount: number or something.

Cool!

If I remember correctly the preload strategy of the video sources is implemented differently (and not well documented) from browser to browser.
The XHR-blob method would then allow, from what I can see, a certain consistency (and certainty).

Also how should the content load? Maybe it should load x slides forward from the current cursor, such that it is not loading all content at once. Considering doing a preload: boolean prop and a preloadCount: number or something.

Absolutely agree. Having it configurable would be extremely useful.

I checked Instagram webpage and they're also using blobs and extensive caching techniques.
From what I can see from the network tab and some tests, it looks like they are caching content up to one user more of what it's currently visible.

Closed with #274