Skip to content

3.5 MB of logos on one page, for circles drawn at 22 pixels - #2938

Merged
Flotapponnier merged 1 commit into
devfrom
perf/shrink-logos
Oct 9, 2026
Merged

Flotapponnier merged 1 commit into
devfrom
perf/shrink-logos

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

3.5 MB of logos on one page, for circles drawn at 22 pixels

The cache header landed in #2934 and fixes the repeat visit: a reader who
already holds the marks no longer asks the server about each one. It does
nothing for the first visit, which still downloads the lot. On /capital that
is 158 files and 3.5 MB, and the marks are rendered in 22 px circles.

The files were simply never sized for their use. ronin.png is 2000x2000 and
227 KB. tradoor.png is 1667x1667. tron.png is 2000x2000 and 104 KB. They are
whatever the provider's press kit shipped.

The largest size any <ProviderLogo> renders at anywhere in the codebase is
56, so every raster over 30 KB is capped at 160 px on its longest side: about
3x retina for the biggest use and 7x for the common 22 px chip. Format is
unchanged file by file — PNG stays PNG, WebP stays WebP — so
logo-manifest.ts needs no edit and no path moves.

97 files 7,371 KB -> 1,333 KB (-81%)
/capital 3,506 KB -> 1,302 KB (-63%)
public/logos 13 MB -> 6.8 MB

Two files were left exactly as they were because re-encoding them came out
larger, which is the rule the script applies: a result that does not shrink
is not written.

Checked rather than assumed, because the failure mode here is silent and
ugly. Alpha and colour space survive on every sampled file (ronin, zircuit,
immutable, rhea-finance, sun, kinetiq, tron, wallet-v: hasAlpha and space
identical before and after), aspect ratios are preserved rather than squared
off (wallet-v 794x203 -> 160x41), and three of the resized files were opened
and look like their logos.

An earlier run of this nearly shipped something worse: tar --exclude=script
while packaging the rpc-cost harness also matched cmd/script/, the entire
Go source. Different job, same lesson about patterns that match more than the
one path they were written for.

The cache header landed in #2934 and fixes the repeat visit: a reader who
already holds the marks no longer asks the server about each one. It does
nothing for the first visit, which still downloads the lot. On /capital that
is 158 files and 3.5 MB, and the marks are rendered in 22 px circles.

The files were simply never sized for their use. ronin.png is 2000x2000 and
227 KB. tradoor.png is 1667x1667. tron.png is 2000x2000 and 104 KB. They are
whatever the provider's press kit shipped.

The largest size any `<ProviderLogo>` renders at anywhere in the codebase is
56, so every raster over 30 KB is capped at 160 px on its longest side: about
3x retina for the biggest use and 7x for the common 22 px chip. Format is
unchanged file by file — PNG stays PNG, WebP stays WebP — so
`logo-manifest.ts` needs no edit and no path moves.

  97 files   7,371 KB -> 1,333 KB   (-81%)
  /capital   3,506 KB -> 1,302 KB   (-63%)
  public/logos   13 MB -> 6.8 MB

Two files were left exactly as they were because re-encoding them came out
larger, which is the rule the script applies: a result that does not shrink
is not written.

Checked rather than assumed, because the failure mode here is silent and
ugly. Alpha and colour space survive on every sampled file (ronin, zircuit,
immutable, rhea-finance, sun, kinetiq, tron, wallet-v: `hasAlpha` and `space`
identical before and after), aspect ratios are preserved rather than squared
off (wallet-v 794x203 -> 160x41), and three of the resized files were opened
and look like their logos.

An earlier run of this nearly shipped something worse: `tar --exclude=script`
while packaging the rpc-cost harness also matched `cmd/script/`, the entire
Go source. Different job, same lesson about patterns that match more than the
one path they were written for.
@Flotapponnier
Flotapponnier merged commit 71e34aa into dev Oct 9, 2026
2 checks passed
bakabhai993 pushed a commit to bakabhai993/OpenChainBench that referenced this pull request Oct 18, 2026
main and dev had diverged both ways: 180 commits on dev, 87 on main, and no
fast-forward since October. A dev to main pull request would have opened
with 32 conflicts and no reviewer able to say which side was right without
reading all of them. This merges main into dev first, where the resolution
can be validated on staging, and leaves the release itself trivial.

Every file resolved in dev's favour was checked rather than assumed:

  the nine keyed RPC specs   main's corrections are already there (the
                             Alchemy figures match on all nine), dev adds
                             Validation Cloud, the p95 and the WebSocket arm
  the recording rules        dev holds all 11 of main's and 12 more
  rpc-capabilities config    dev carries the repair main never got, ChainBench#2935,
                             which replaced four endpoints that had stopped
                             answering; taking main would restore them
  the Hyperliquid family     10 commits on dev against 5, every file larger,
                             and 34 metric names queried against 32
  katana, xrplevm            dev has one more provider each
  the three registries       no entry exists only on main
  stakeangle.png             dev's is the optimised one from ChainBench#2938

Two were not a side to take:

  bench-published.json       the union. It records when a page first
                             appeared, so main's six dates for benches dev
                             has since removed are as true as dev's eleven
                             new ones. Earliest date wins where both know a
                             slug.
  provider-registry.ts       dev's entries, main's types. The triage had
                             compared entries and called them identical,
                             which they were; the module's exports were not.
                             main also landed ProviderClaim and an optional
                             claims field, and lib/provider-claims.ts, its
                             test and a product-page call site came through
                             the merge and failed to compile against dev's
                             registry. Caught by tsc, not by reading.

Gates on the merged tree: 253 specs valid, tsc clean, eslint 0 errors,
594 tests, promtool 23 rules, go build and vet on rpc-keyed-latency,
rpc-capabilities, hl-fills-reduce and hyperliquid-frontends, and a full
next build generating 293 static pages.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant