I have a script that fetches urls and downloads images. It works fine with most servers, but for some of them the request will remain pending if the tab is not the active one (lets say, I switch windows, or move to some other app). When that tab gets focus, it will continue downloading (I noticed some gaps between requests, as seen in picture). When tab has focus, they would be no gaps. enter image description here
I use chrome 89.0.4389.114 (64 bits). Didn't try with other navigators.
Is there any kind of lazy fetching (for Chrome tabs) working here?
Update:
Usage: downloadAllImages({thumbs})
;
const downloading = [];
const downloadErrors = [];
// thumbs is a set of links with an image as child, like "<a href='http:...'><img src='http:..'></a>"
const thumbs = Array.from(document.querySelectorAll(".thumb")).map(thumb => {
const img = thumb.querySelector("img");
img.addEventListener("error", e => {
img.src = "/img/404.png";
});
img.addEventListener("click", e => {
e.preventDefault();
e.stopPropagation();
console.log(img);
});
const opaque = thumb.querySelector(".opaque") ;
if (img.complete) {
if (opaque) opaque.style.height = `${img.height}px`;
thumb.style.opacity = 1;
}
else {
img.addEventListener("load", e => {
if (opaque) {
const rects = img.getClientRects()[0];
opaque.style.height = `${rects.height}px`;
}
thumb.style.opacity = 1;
});
}
thumb.addEventListener("click", e => {
e.preventDefault();
e.stopPropagation();
});
return thumb;
});
async function downloadAllImages({thumbs}) {
let i = 0;
while (thumbs[i]) {
const elem = thumbs[i];
if (!Number(elem.getAttribute('data-local'))) {
if (downloadErrors.length > 3) break;
while (downloading.length > 3) await timeout(500);
downloadImage({elem, i});
}
i++;
}
while(downloading.length) await timeout(1000);
console.log('done');
}
async function downloadImage({elem, i}) {
downloading.push(elem);
showDownloadingAnimation({elem, i});
const body = [
{ name: 'index', value: i },
{ name: 'src', value: elem.querySelector("img").src },
{ name: 'href', value: elem.href },
{ name: 'location', value: viperg.location },
].map(e => {
return `${e.name}=${e.value}`;
}).join("&");
let r = await fetch(`/images/download`, createOptions({ body }));
// images/download is pretty simple. I use Guzzle::HTTP to retrieve the contents for cettain url
if (r.ok) {
r = await r.json();
if (r.filename) {
let filename = r.filename;
r = await modifyJSONGallery({ index: i, attributes: [{ p: 'main', v: r.filename }] });
if (r) {
downloading.pop();
elem.querySelector(".opaque").classList.add('animateHeight');
removeDownloadingAnimation({elem});
elem.href = `http://wpcontent/${viperg.location}/i-${filename}`;
elem.querySelector("img").src = `http://wpcontent/${viperg.location}/t-${filename}`;
return 1;
}
}
}
downloading.pop();
removeDownloadingAnimation({elem}); // a simple png, with no animation
showDownloadingError({elem});
downloadErrors.push(elem);
return 1;
}
async function modifyJSONGallery({index = -1, attributes = {}} = {}) {
const body = `index=${index}&location=${viperg.location}&attrs=${JSON.stringify(attributes)}`;
let r = await fetch(`/galleries/modifyjsongallery`, createOptions({ body }));
if (r.ok) {
r = await r.json();
if (r.s) return 1;
}
return 0;
}
function timeout(time) {
return new Promise(resolve => setTimeout(resolve, time));
}
As read in post recommended by @esqew, I had some animation that used keyframes. I tried removing them, but there was no change (I left the animation disabled):
Test Two
Another way to test it is to log the timestamp repeatedly with setInterval and requestAnimationFrame and view it in a detached console. You can see how frequently it is updated (or if it is ever updated) when you make the tab or window inactive.
Results
Chrome ... requestAnimationFrame is paused when the tab is inactive.