Repository navigation
perf(coins): load resized coin logo variants for badges and icons - #14712
Merged
Merged
Conversation
Coin badges are drawn at 14-24px but load the full logo_uri, which averages 500 KB (up to 2.2 MB) across prod coins. Add getCoinLogoUrl, which rewrites validator node logo URLs (/content/<cid>) to the smallest square variant that is sharp at 3x for the display size. Other URLs (Irys, static assets) pass through unchanged. Prod logos are all on Irys today, so this takes effect as logo_uri moves to validator nodes via the Irys -> Audius migration (pedalboard#90 for new coins, migrate-logos-to-audius for existing). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Coin badges are drawn at 14–24px, but they load the coin's full
logo_uri. On signed-out/trending(Lighthouse mobile, 2026-10-26) three badge PNGs were 462 KB, 101 KB and 40 KB, about 600 KB of the page's 823 KB of images.It's not just those three. All 57 coin logos on prod:
logo_uritoday)$STEEL, 1000×1000 PNG)150x150.jpgvariant (est.)Where the logos come from
artist_coins.logo_uriis whatever the launchpad relay uploaded: the Metaplex token image on Irys/Arweave (gateway.irys.xyz/<id>, which 302s to*.mainnet-1.datasprite-cdn.com). 56 of 57 prod coins point there;$AUDIOis a static asset on audius.co.audius.cohas no Cloudflare image resizing (/cdn-cgi/image/404s). The API returnslogo_urias stored, with no sized variants.GET /content/<cid>/150x150.jpgresizes any stored image, from the original CID too, not just upload IDs. Checked on prod: a 45 KB original came back as 5.7 KB from bothcreatornode.audius.coand a third-party node.img_squareand storehttps://creatornode.audius.co/content/<cid>.artist-coins-scripts/src/scripts/coin/migrate-logos-to-audius.tsre-hosts existing logos the same way and repointslogo_uri. It's committed but hasn't been run on prod yet: every prodlogo_uriis still Irys.What this PR does
Adds
getCoinLogoUrl(logoUri, displaySize)in@audius/common/utils. For a bare validator node URL (…/content/<cid>) it returns the smallest square variant that is sharp at 3× for that display size:150x150.jpgup to 50px, then480x480.jpg, then1000x1000.jpg. Every other URL is returned unchanged: Irys, static assets, and URLs that already name a variant.Used where coin logos are drawn small:
UserBadges(the trending offender),FanClubHoverCard,FanClubTextPostNotification,PriceAndAudienceField,CoinSuccessModal,FanClubInfoSectionheader, andTokenIcon(covers ~15 more call sites)TokenIcon(coversUserBadgesand the rest),DetailsTileHasAccessloading="lazy"/decoding="async"are already set inside harmony'sArtwork, so nothing to add there.Today this is a no-op on prod, because no prod logo is on a validator node yet. It starts saving bytes for each coin as soon as its
logo_urimoves over, with no further client release:migrate-logos-to-audius.ts --applyfor existing coins →/trendingbadge bytes go from ~600 KB to ~15 KBNo new infrastructure. It only uses the resizer every validator node already runs.
Safety
logo_uri, so reachability doesn't change. If the host is down, the original would fail too.Before / after
On prod
/trending, this PR alone changes nothing yet. Every logo there is still on Irys, and the helper leaves those URLs alone. Today's trending page only had$YAK(4.8 KB) in view. The audit's 462 KB / 101 KB / 40 KB logos are typical of the set, and the bytes drop oncelogo_uris are re-hosted.Measured in a local web build against prod at DPR 2, signed in. A temporary, uncommitted shim pointed one artist's badge
logo_uriat an image already stored on validator nodes:/trending(14px CSS, 4 on page)…/content/<cid>/original.jpg…/content/<cid>/150x150.jpg150px is about 5× what a 14–24px badge needs at 2× and covers 3× up to 50px.
What the audit's
/trendinglogos would cost after the re-host, estimated by resizing the actual files the way mediorum does (150px fill, JPEG q75):$STEEL)Not in this PR (API / backend follow-ups)
/trendingnumber.profile_picture({150x150, 480x480, 1000x1000, mirrors}), so clients can fail over to mirrors instead of relying on one host. Not needed for the bytes win.Test plan
getCoinLogoUrlunit tests (variant thresholds, trailing slash, non-resizable URLs, empty values)…/150x150.jpgand stay sharp at 2×. Irys logos unchanged.TokenIcon'ssource.uri. Not run on device.🤖 Generated with Claude Code