Build1 distinct publisher3 min readUpdated
A browser image tool's writeup on binary-searching JPEG quality, and on PNG, where the quality-shaped proxy it searches cannot address 155 of the 255 available palette sizes.
The Engineer · Build desk
Compiled by The EngineerSomething wrong?How this is made
The arithmetic is what makes the case here, not the elegance. Run a 12 megapixel photo through the step-down loop and the worst case is 18 full passes over 12 million pixels, about 216 megapixels of encoding work [2]. The eight-iteration binary search bounds the same job at 96 megapixels [3], a difference of 120 megapixels that nobody sits and watches [4]. The naive loop pays that premium for a worse answer: in the writeup's own example it returns 30 KB against a 100 KB target [5], leaving 70 percent of the requested budget unspent [5].
The cap of eight is not padding either. log2(100) is roughly 6.64, so seven probes collapse a 100-value range to one candidate, and the eighth is spare capacity while still staying well under half the linear scan [7].
The part worth stealing is the three lines that record the smallest output on every iteration, whether or not it fits [8]. They do double duty. If the target is below what quality 1 produces, `best` stays null and a naive version throws [9]; with smallest tracked, the answer becomes the closest achievable file plus a note that the number was not reached [8]. They also cover the case where a higher JPEG quality compresses marginally smaller because the quantization tables changed between levels, which can send the search into the wrong half [10]. The author's framing is that you never detect the violation, you just stop trusting the search to have seen the smallest output [11]. Cheaper than a monotonicity guard, and weaker: what you get is the smallest file you happened to encode, not evidence that no smaller one hides between probes.
PNG is where the design leaks. There is no fidelity dial, and compression level moves speed far more than size [12], so bytes have to come out of the palette, which is what pngquant does by quantizing 16.7 million colors to N and handing DEFLATE a smaller symbol set [13]. The code keeps a quality-shaped interface and maps it: round(quality / 100 * 256), clamped between 2 and 256, passed to UPNG as a color count [14]. Search integer quality 1 to 100 through that map and you can address at most 100 of the 255 palette sizes between 2 and 256, so roughly 155 of them are unreachable [6]. The lower clamp never fires: quality 1 rounds to 3 colors [7]. A two-color PNG cannot be expressed through the proxy at all [7]. And each quality step moves the palette by 2.56 colors, so quality 1 to quality 2 takes the palette from 3 to 5 [8], which is a near doubling for one notch of a slider at the exact end of the range where a user is fighting for bytes.
On threading, the supplied text asserts rather than shows: leaving the main thread is listed as one of the three less-obvious parts of the implementation [16], and the spinner problem is named early [4], but the material stops mid-sentence in the PNG section. The numbers carry it regardless. Eight synchronous full-image encodes on the UI thread are eight windows in which a phone stops responding to touch.
Follow any of these and your For You feed starts watching them — no settings page required.
Ranked by verification strength, evidence, and original report placement.
The obvious loop starts at quality 90 and steps down by 5 while q > 1, returning the first blob at or under the target; it is up to 18 encodes, and every encode is a full pass over every pixel.
On a 12 MP phone photo that is a real amount of work, and the user is watching a spinner the whole time.
The PNG path computes cnum as 0 when lossless, otherwise Math.min(256, Math.max(2, Math.round((quality / 100) * 256))), and passes it to UPNG.encode([buffer], width, height, cnum).
The PNG binary search is structurally identical to the JPEG one, still finding the highest value that fits, but the value searched is a palette size from 2 to 256.
The writeup lists three less-obvious parts it intends to cover: what happens when the assumption behind binary search is false, why PNG needs a different search space, and why the whole thing has to leave the main thread.
Photoshop exposes a quality slider, cwebp exposes -q, and the canvas API exposes a float between 0 and 1; none of them accepts bytes.
Evidence-backed comparisons of source perspectives and observed adoption signals. Read the methodology
Which Builder, Operator, and Investor concerns the observed source mix emphasized—not a truth score.
Evidence, demonstrated adoption, hype gap, incentives, and confidence are assessed independently, each on its own current evidence. How these are measured.
Self-reported code, verifiable arithmetic, zero measurement
The mechanism claims are strongly evidenced in kind: the source publishes the actual loops, the cnum expression and the UPNG call, and its central quantitative justification (log2(100) ≈ 6.64, 18 step-down values, 2.56 colours per quality unit) can be checked by arithmetic without trusting the author. But every performance and perceptual claim — 'a real amount of work', 'well under half the linear scan', 'several seconds' of main-thread block, banding cost — is asserted with no benchmark, device matrix or sample output, and there is a single source with no independent corroboration.
One self-disclosed implementation, no external uptake
The only adoption fact in the cluster is the author's own statement that this search and worker split ship in a browser-only image tool. The tool is unnamed and there are no users, downloads, dependents, third-party deployments or citations by other projects. UPNG, pako and pngquant are referenced as prior art rather than as adoption of this approach.
Modest technical framing, one unacknowledged gap
The writeup is largely restrained — it flags its own broken assumption and the harsher perceptual cost of palette reduction. It tips slightly overstated in two places: efficiency gains are presented as bounded improvements without any measurement, and the PNG search is called 'structurally identical' to the JPEG one when the quality-shaped proxy leaves roughly 155 of 255 palette sizes unreachable and cannot express a 2-colour PNG. Small positive gap, not a promotional one.
Author writing up own tool on a dev platform
Observable incentive is mild self-presentation: an individual author publishing on dev.to about the internals of their own browser-only image tool, which builds technical credibility. No pricing, licence, funding, vendor sponsorship or competitive comparison appears in the source, and no product name or call to action is present in the supplied body, so commercial pressure on the claims looks limited.
Mechanism solid, impact unquantified
Confidence is moderate: the algorithmic core is inspectable and its arithmetic checks out independently, so the design claims are reliable. Everything about magnitude — real-world latency, tab-freeze severity, visual damage from palette reduction, whether non-monotonic JPEG cases matter in practice — rests on one author's unmeasured assertions in one item, so conclusions about impact should be held loosely.
build
Chess's one-game-a-day cap is a two-core bill, and WebAssembly moves it onto your laptop1 distinct publisher
build
Three manual interventions in a month, and every guard was working as designed1 distinct publisher
build
Six MariaDB versions, one real difference: the only reason to leave 10.6 is the July 2026 clock1 distinct publisher
build
Force the tool call, then hand Lightsail a long-lived key1 distinct publisher
Distinct publishers with included, body-backed reporting in this cluster.
dev.to
1 article · August 22, 2026