I've been doing some testing. Canvas#jpegStream() is much faster than what we're currently doing. Also, this is undocumented, so I don't know how stable it will be, but apparently Canvas#toBuffer() can take a second and third argument specifying the PNG compression strength and filter type. Setting them to 1 and 0 respectively speeds it up a lot and doesn't cost us much in terms of file size compared to the default.
This is what I get on my machine (after subtracting the 0.3940 CPU seconds it takes to load the image):
JPEG (quality=75): 0.2628 seconds, 449409 bytes
JPEG (quality=90): 0.2900 seconds, 682475 bytes
uncompressed PNG (0,0): 0.5268 seconds, 15025838 bytes
fast compressed PNG (1,0): 0.5040 seconds, 1415644 bytes
default PNG (toBuffer): 1.2080 seconds, 1567197 bytes
current code (toDataURL): 1.2396 seconds, 1567197 bytes
I'm using the current https://livechan.net/draw.jpg
as input, overlaid over a white background so that the JPEG versions don't come out all black where the image (actually a PNG) is transparent. These are each averaged over 10 runs.
So what do we want to use? JPEG is definitely the best-performing option here, although it has the disadvantage of being lossy. But both quality=75 (the default) and quality=90 look okay, and with stuff being redrawn all the time, most of the image will have only been compressed once. Unless you end up still having to restart the server a lot, in which case generation loss might become a problem.
Post too long. Click here to view the full text.