Skip to content

perf(ui): render icons through an svg sprite#26950

Open
Hona wants to merge 2 commits into
anomalyco:devfrom
Hona:perf/icon-sprite-rendering
Open

perf(ui): render icons through an svg sprite#26950
Hona wants to merge 2 commits into
anomalyco:devfrom
Hona:perf/icon-sprite-rendering

Conversation

@Hona
Copy link
Copy Markdown
Member

@Hona Hona commented May 11, 2026

Benchmark: dribble.tf GitHub CLI session initial timeline load

Scenario: start on \Read couple of files, click \GitHub CLI: sticky jump movement & physics analysis for Momentum Mod project, wait for the target timeline to stabilize. Electron dev build, \OPENCODE_DB=~/.local/share/opencode/opencode.db, 3 traces per build.

Metric upstream/dev this PR Delta
INP median 857ms 618ms -239ms (-28%)
INP runs 747 / 857 / 869ms 611 / 618 / 777ms
Icon CPU median during INP window 44ms 18ms -26ms (-59%)
Icon CPU runs 34 / 44 / 53ms 15 / 18 / 22ms

Reference: https://css-tricks.com/svg-symbol-good-choice-icons/

Copilot AI review requested due to automatic review settings May 11, 2026 23:05
@Hona Hona added the beta label May 11, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR optimizes icon rendering in the @opencode-ai/ui package by switching from inlining SVG paths per <Icon> instance to referencing symbols in a shared SVG sprite, aiming to reduce per-render CPU cost (as reflected in the provided INP/icon CPU benchmarks).

Changes:

  • Add a DOM-injected SVG sprite containing <symbol> definitions for all icons.
  • Update <Icon> to render via <use href="#..."> instead of innerHTML path injection.
  • Centralize per-icon viewBox selection logic for sprite symbols and instances.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 143 to +160
@@ -123,11 +152,12 @@ export function Icon(props: IconProps) {
[local.class ?? ""]: !!local.class,
}}
fill="none"
viewBox={viewBox()}
innerHTML={icons[local.name as keyof typeof icons]}
viewBox={viewBox(local.name)}
aria-hidden="true"
{...others}
/>
>
<use href={`#${symbol(local.name)}`} />
</svg>
Comment on lines 143 to +145
const [local, others] = splitProps(props, ["name", "size", "class", "classList"])
const viewBox = () =>
local.name === "magnifying-glass" || local.name === "arrow-undo-down" ? "0 0 16 16" : "0 0 20 20"
onMount(ensureSprite)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants