Say you sell a small hardware gadget and the only good description of it lives in a 3-page PDF manual: one page of dense small print, one page of charts, one page with a big product photo. You want those pages on the product page as images, and every extra megabyte is bandwidth paid on every visit. The rule of thumb "PNG for text, JPEG for photos" sounds safe. On a self-made 3-page A4 sample, half of it held and half didn't, so the rule below is three lines instead of one. Everything on the sample is self-made except the page-3 photo, a CC0 image by Bonnie Moreland from Wikimedia Commons. A single sample on a single Apple-silicon Mac, each method run once: every number here means "on this sample".
Photo pages: JPEG or lossy WebP, never PNG
Two sources fed this post, and their numbers are never mixed. One is poppler rendering each page at 216 DPI on white, with Pillow and pngquant writing every format from those identical pixels. There the photo page was 2,431,138 bytes as PNG against 550,440 as JPEG q92 and 302,318 at q75.
The other is a real export: ImgIng's PDF-to-image tool https://imging.ai/ in a desktop browser at its default 216 DPI (it also offers 144 and 300) saving PNG, JPEG and WebP. On the photo page its PNG was 3,658,462 bytes, the JPEG 476,565 and the WebP 255,978, which makes the PNG 7.7 times the JPEG. Measured against that PNG, the JPEG scored 44.49 dB PSNR and the WebP 44.62 dB, a gap of about 0.1 dB between the two lossy files, and all three looked clear on screen. My guess, not something this run measured, is that the noise and soft gradients in a photo leave a lossless encoder little to work with.
Whole-document totals from that export at 216 DPI: 4,768,689 bytes for three PNG pages, 1,489,274 for JPEG, 679,406 for WebP. Across 13 processing runs the network capture showed no request carrying the file, handy if the manual isn't public yet.
Text and chart pages: lossless WebP first, JPEG at q92 if you must
The text and chart numbers below all come from the poppler set. The text page is where "PNG for text" falls over. Truecolour PNG came to 838,404 bytes. JPEG at q92 was 796,608, so the PNG was about 5% larger than a high-quality JPEG. The chart page went the other way: PNG at 127,051 bytes beat JPEG at q75, q85 and q92 (178,232, 201,943 and 233,599). Neither page made PNG the winner, though. Lossless WebP came in at 161,212 bytes for the text page and 37,390 for the chart page, smaller than every JPEG and lossy WebP setting tried, and smaller than the 256-colour PNG below.
If your pipeline can only emit JPEG for these pages, the quality setting matters more than it does on photos. The count used here is the share of pure-white background pixels within 1 to 3 pixels of a stroke that shifted by more than 8 of 255 levels after encoding. It's a homemade metric, but it tracks the grey haze around small text. On the text page JPEG q75 hit 11.69%, q85 4.86% and q92 0.40%. On the chart page it was 10.13%, 4.22% and 0.70%. On text pages, q75 buys its smaller file with a grey rim around the letters.
When PNG is mandatory, quantise it
Some places only take PNG. In that case a 256-colour palette pass with pngquant is the cheap fix, keeping in mind that it is lossy. The text page dropped from 838,404 to 359,391 bytes, a 57% cut, at 66.86 dB PSNR. The chart page went from 127,051 to 49,019, a 61% cut, at 68.63 dB. On the photo page the same trick only got the file to 1,105,849 bytes, still twice the q92 JPEG at 550,440, which is why rule one doesn't have a PNG escape hatch. On text and chart pages it still loses to lossless WebP, so it's a fallback.
An automated pipeline needs a way to tell page types apart. On this sample the colour count of a quarter-size thumbnail separated them well: about 447 colours on the text page, 2,117 on the chart page, 26,914 on the photo page. Where to draw the line between "chart" and "photo" on other documents is still a guess, and a scanned page wasn't part of this run, so I can't say which bucket a scan lands in.
The three lines, written the way they'd sit in an export script: photo pages to JPEG or lossy WebP; text and chart pages to lossless WebP, or JPEG no lower than q92; PNG only when something downstream demands it, and then through pngquant first. Whatever the format, zoom into the smallest text after exporting and check the letters still look like the original.
