Reputation: 632
Good evening,
I'm using a material-ui Card inside a React functional component, with a CardMedia such as :
<CardMedia
className={classes.media}
image={props.image}
title={props.cardTitle}
/>
I'm trying to determine the image file size in bytes. After some research I found solutions which use XMLHttpRequest. It seems strange to me to download the file again. I found how to get the image width and height using :
function checkImage() {
var img = new Image();
img.addEventListener("load", function(){
console.log( this.naturalWidth +' '+ this.naturalHeight );
});
img.src = props.image;
}
It works, but this is not what I'm looking for and if I'm not mistaken this downloads the image again. I looked into Mozilla doc, Image
only has width and height properties. Since the image is already loaded, I should have a way to determine its size in byte without using XMLHttpRequest ?
Upvotes: 6
Views: 1628
Reputation: 5584
#1:
You can fetch the Content-Length
header of a resource with a HEAD
request like so:
fetch('https://your-domain/your-resource', { method: 'HEAD' })
.then(r => console.log('size:', r.headers.get('Content-Length'), 'bytes'));
This way only the headers are downloaded, nothing more.
#2: Alternatively you can use the Resource Timing API:
const res = performance.getEntriesByName('https://your-domain/your-resource');
console.log(res[0].transferSize, res[0].encodedBodySize, res[0].decodedBodySize);
Just be aware that the resource needs to be on the same subdomain, otherwise you'll have to add a Timing-Allow-Origin
CORS header.
#3: Yet another alternative is to download the image as a blob:
fetch('https://your-domain/your-resource')
.then(r => r.blob())
.then(b => console.log(b.size, URL.createObjectURL(b)));
This would of course re-download the image if called after the initial load, but you can use the object URL to reference your image if using this method to load it initially.
Upvotes: 4