I'm loading large images and having the browser resize them. I'm explicitly setting the size.
<img src="http://example.com/image1.jpg" width="240" height="360"/>
There are many such images on the page. Scrolling is very slow and choppy. The Events Timeline in chrome looks something like this when scrolling:
Paint
* Image decode (JPEG)
* Image resize (non-cached)
* Image decode (JPEG)
* Image resize (non-cached)
* ...
Paint
* Image resize (cached)
* Image resize (cached)
* Image resize (cached)
* Image resize (cached)
Paint
* Image decode (JPEG)
* Image resize (non-cached)
* Image decode (JPEG)
* Image resize (non-cached)
* ....
Paint
* Image resize (non-cached)
* Image resize (non-cached)
* Image resize (non-cached)
* Image resize (non-cached)
Paint
* Image decode (JPEG)
* Image resize (cached)
* Image decode (JPEG)
* Image resize (cached)
* ...
etc.
I'm not sure why some of the Paint events include image decoding and others don't, nor why sometimes the resizing is cached and sometimes it is not. I guess it must have to do with new images coming into the view-port.
Is there anything I can do to ensure that I only pay the image resize cost once per image when the page loads, and avoid image resizing during scroll?
(Of course, I understand that the best solution is to avoid browser resizing by loading in an image that is already of the appropriate size. In this case this is not practical.)
This function will permit you to resize an image only once, by replacing it with a new image resized at the desired scale :
function resizeImage(image, maxWidth, maxHeight) {
// Output scale is the minimum of the two possible scales
var scale = Math.min((maxWidth / image.width), (maxHeight / image.height))
// Output canvas
var outputCanvas = document.createElement('canvas')
outputCanvas.width = image.width * scale
outputCanvas.height = image.height * scale
// Draw image content in output canvas
var outputContext = outputCanvas.getContext('2d')
outputContext.drawImage(image, 0, 0, parseInt(image.width * scale), parseInt(image.height * scale))
// Replace image source
image.src = outputCanvas.toDataURL()
}
It takes the image you pass as image
parameter, and creates a canvas where it resizes image
, and then sets the image.src
attribute to the content of the output canvas, using toDataURL()
.
Images you resize have to be in RELATIVE path (yes it's not cool), or you will have security error due to CORS if not fulfilled.
But you can pass base64 data as src
attribute, and it can be easy to do it with AJAX.
Your problem is that you are downloading lots of images at the same time, lots of large images. The rendering of them to differnt sizes other than the orginal will also be slow if there are lots of large images and the users individual ram and processor limitations.
no matter what size you tell the browser to render the image the browser still loads the original image size and then adjusts it on the fly. The large image has to travel down the users internet connection to the browser from the server. by using html attributes all you are doing really is using CSS to change the image size once it has been downloaded.
Your best option would in mho be to create multiple image sizes server side, preferably at the time of creation of the asset rather than on the fly and call the image size closest to your needs. If you create images on the fly using scripts etc keep them on the server to use again later on and reduce load time and server resources.
one last tip is also make sure you are caching. more info here http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With