2

I have a problem rendering images with large file sizes. When I upload a lot of large file sizes of images and display them, it becomes very laggy.

My question is:

The ideal way is the backend should provide an very small image file size url? Or the frontend can do it using Canvas API?

Could you provide an explanation please? Thank you

Joseph
  • 7,042
  • 23
  • 83
  • 181
  • Yeah, have the backend compress the images some. Maybe try compressing each to 1 MB or less, see how that feels. If the page is scrollable, lazy-load the images too. – CertainPerformance Sep 09 '22 at 01:52
  • @CertainPerformance. So using Canvas API works or should the work really is for the backend to make the file sizes much smaller? and if that's it, can you explain why canvas api won't help much? – Joseph Sep 09 '22 at 01:57
  • I don't know how well using the canvas would work - perhaps it would, perhaps it wouldn't - but if the images are so big that browsers are having trouble rendering it, I'd prefer to not send so much data over the network to begin with, to save on bandwidth and storage space. If the lag is due to the download speed, using canvases won't help. – CertainPerformance Sep 09 '22 at 01:59
  • @CertainPerformance. Actually I needed both, one for displaying the images as a thumbnail and one is for zooming it which should use the large resolution file size. Is that good? – Joseph Sep 09 '22 at 02:02

4 Answers4

3

If you have a bunch of thumbnails to display, the source images for those thumbnails should definitely not be the original, full-size images. If those images are large, it will take a long time for the client to download them, no matter how you render them on the client.

When figuring out an image to be shown to client, you should have two versions on the server:

  • Thumbnail version - low resolution, small file size, easy to download and render many at once
  • Full-size version, downloaded when the user wants to zoom in on one of them

It could be that the full-size version should not necessarily be the original image. For example, if the original image is 20MB (yes, they can exist), you wouldn't want to burden clients with that. So you'd want to perform resizes and optimizations on the server for both the thumbnail version and the "full" version - enough such that there isn't much of a delay between when the client tries to zoom in and the full-size image fully loads.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • Download the thumbnails first. When a thumbnail is expanded, you could keep showing the thumbnail as the (expanded) image *for a moment*, while the larger image loads. Or you could optimize the full images with [interlacing](https://en.wikipedia.org/wiki/Interlacing_(bitmaps)) so that the full-size image gradually improves in quality until fully loaded. (but that results in a larger file size overall) – CertainPerformance Sep 09 '22 at 02:12
  • So you want to do it on the client before upload, rather than on the server, after upload? Sure, you could do that - but keep in mind that you can't trust any code that runs on the client. (It's not likely to be an issue, but server-side processing is more reliable) – CertainPerformance Sep 09 '22 at 02:49
  • The resize library that was linked is meant for resizing before the client uploads. If you don't want to resize before uploading or on the server, and only resize after the client downloads it for display, that's a bad idea because they'll be taking up an incredible amount of bandwidth just to show the thumbnails, and a client-size resizer could still have trouble processing that many large images. Better to save the two compressed image formats on the server. – CertainPerformance Sep 09 '22 at 04:02
  • How about this one? https://github.com/codepo8/canvasthumber/blob/master/canvasthumber.js ? This is the demo https://codepo8.github.io/canvasthumber/. The reason why I keep on asking on why client will resize instead of server is the backend don't keep until product is created from image uploaded. we don't store them on database until product is created. – Joseph Sep 10 '22 at 04:15
  • Looks to have the same fundamental issue as the other one - it's done on the client-side. If that's the only approach that you think will work for you, that's your choice, though it sounds odd. – CertainPerformance Sep 10 '22 at 05:16
  • But this will only convert when its an image File? like when you refresh the page, you need to get the image url, you cannot retrieve the image File, then you wont be able to use this, right? – Joseph Sep 10 '22 at 18:31
  • Do you mean, you don't want to upload the image to the server at all, but you want the image to be preserved over page refreshes? I suppose you might be able to save the data in IndexedDB and retrieve it later... but again, it's quite strange to not try to handle it on the server (and only the one user who has the data in IndexedDB would be able to see it, of course) – CertainPerformance Sep 10 '22 at 18:41
  • No. what I mean is when you use this https://github.com/codepo8/canvasthumber/blob/master/canvasthumber.js. Its needs to be an image File to be converted. not like https://sampleImage.jpeg – Joseph Sep 11 '22 at 02:04
  • After uploading to server. what I mean is when you use this `https://github.com/codepo8/canvasthumber/blob/master/canvasthumber.js`. It needs to be an image File to be converted and displayed as an img tag. You can't use `https://2.img-dpreview.com/files/p/E~C1000x0S4000x4000T1200x1200~articles/3925134721/0266554465.jpeg` and convert it to lower size, right? – Joseph Sep 11 '22 at 10:47
  • It's possible, if the images are hosted on your own server without CORS restrictions: https://stackoverflow.com/questions/54983591/image-url-to-file-object-using-js – CertainPerformance Sep 11 '22 at 13:54
1

My recommendation is that you convert the image type to something more performant like .webp or .jpeg and give the element the exact width and height properties.

And react also have a feature to lazy load your images using react.lazy() that can boost your web performance significantly

1

Handling large images is too much work for a frontend client. You should get these images at a smaller size in order to just show them as they are.

Imagine someone trying to use your application with an old computer, or even an old smartphone, you shouldn't rely on client's processing power to handle all this heavy work.

I hope my answer helps you!

1

Jpegs are what you should be using, look at functionPreload() as well

Mattywood
  • 32
  • 5