Another potentially massive step is to use the srcset [1] attribute of the <img> tag. It lets you provide a bunch of different resolutions for the same image, and the browser will choose the best one to download and render based on the physical screen pixel density, zoom level, and possibly in the future even things like bandwidth preferences or battery level.
Combine the imagemin plugin with a webpack-loader [2] that will auto-generate 5-ish different downscaled versions of an image as srcset, and you get a pretty perfect setup.
My web apps now always use the highest resolution image I have available by default (within reason, I do cut it down to a realistic value), then provide 5 different downscaled versions alongside it in the srcsets automatically which are all run through a battery of optimization to compress them as good as possible. And the browsers will only download the biggest one it can realistically use. Everyone gets high quality images, nobody wastes bandwidth because of support for higher res screens.
[0] https://github.com/Klathmon/imagemin-webpack-plugin
[1] https://css-tricks.com/responsive-images-youre-just-changing...
MozJPEG is actually using something similar called trellis quantization or soft-thresholding. The idea is to further quantize DCT coefficients in noisy areas. There are some limitations [1] though. But it's not an issue with locally sensitive metrics and can be improved with edge detection.
Another challenge here is to estimate the current image quality and the target error.
The standard metrics these tools provide (JPEG quality or PSNR) are not enough to preserve the visual quality for the variety of images. I'm working on the project to actually do it [1].
My favorite example is the actual Google logo [2]. It's 13 504 bytes and can be reduced almost 2 times to 7 296 bytes saving probably gigabytes of bandwidth each day.
[1] http://getoptimage.com [2] https://www.google.ru/images/branding/googlelogo/2x/googlelo...