[HN Gopher] A Broken Heart
___________________________________________________________________
A Broken Heart
Author : memalign
Score : 144 points
Date : 2026-02-01 07:58 UTC (4 days ago)
(HTM) web link (allenpike.com)
(TXT) w3m dump (allenpike.com)
| llm_nerd wrote:
| This is a legitimately fun piece about a bug (or extraordinary
| levels of inefficiency) in CoreSVG, manifested in massive
| computational loads to display a single SVG fallback for a
| colour-specified emoji.
|
| But, isn't the heart emoji red anyways, across basically every
| font that has emojis? I mean, even with variations. I'm not sure
| what COLRv1 brings to that table for that scenario. Although
| maybe the special font is overkill if you really wanted to do
| something crazy with an emoji or text, and it seems to focus on
| gradients and the like.
|
| Maybe this is why they humorously blame Claude for getting them
| to use that font and its affordances in the first place.
| llm_nerd wrote:
| As a bit more on this, until this piece I was oblivious to this
| COLRv1 thing, which is adding more of SVG-style functionality
| to already vector font standards.
|
| https://nabla.typearture.com/
|
| https://developer.chrome.com/blog/colrv1-fonts
|
| My natural cynicism is to ask "should a font really do this?"
| But I guess it's pretty neat.
| StilesCrisis wrote:
| It's not solid red. It has shading.
| jsnell wrote:
| I don't think the blog post itself is using that emoji font.
| The screenshot on the Noto Emoji Github page[0] doesn't look
| like it's using any gradients for the heart emoji, just flat
| shading. But it is using gradients for some of the other
| emojis (e.g. the croissant), and obviously the SVG fallback
| is all or nothing, not per-glyph.
|
| [0] https://github.com/googlefonts/noto-emoji
| derefr wrote:
| You need to look closer; the heart emoji has a flat fill,
| but a gradient in its outline stroke, from lighter-than-red
| near the top, to darker-than-red on the bottom.
| stavros wrote:
| The conclusion of "yes, Claude helped fix this, but it also
| caused it by recommending an emoji font" seems a bit disingenuous
| to me. Using an emoji font is a good suggestion, it's not like
| Claude (or anyone) could have known there's an SVG but that will
| cause this slowness.
| andra_nl wrote:
| Still, I'm going to quote the living daylights out of "These
| coding agents are very much like a power saw. Profoundly
| useful, and proportionately dangerous."
|
| Even though this particular case may not be fair, the
| comparison feels like a very fair one to me. The notion that
| these things can be very valuable in capable hands, but costly
| in others.
| vdupras wrote:
| ... and a broken world.
|
| How infuriating it is to see complexity so spuriously piled up
| upon an already holy mess.
| BobBagwill wrote:
| FTFY. I have created a font with a 1BP LLM inside which
| executes each time the glyph is rendered and figures out the
| appropriate representation. It will also recursively check the
| contents of the page and punch up the text.
|
| The LLM contains copies of QEMU, so it can bootstrap itself
| throughout the enterprise. Naturally, if it finds another LLM,
| it replaces it. Running an OS and LLM is redundant, so
| eventually all the machines boot directly into the LLM. It can
| emulate all the popular desktops, so users won't notice the
| difference. ;-)
| cousin_it wrote:
| Maybe off topic, but I couldn't help thinking that "we need to
| show a heart icon" -> "let's use a heart emoji because it's easy"
| -> "let's use a specific emoji font for consistency across
| platforms" -> "let's import it from Google Fonts every time"
| seems like a problematic developer mindset.
|
| A better heuristic is always keep in mind not only developer
| efficiency, but also program efficiency. I'm not saying optimize
| everything, but keep program efficiency in mind at least a little
| bit. In this case, that would've led the developer to download a
| tiny SVG or PNG and serve it from the app itself. Which would've
| avoided the problem in the post, and maybe other problems as
| well.
| kitd wrote:
| I would say just reusing widely-used emojis you have already
| downloaded would be less error prone
|
| ... assuming it all works ofc (though you could say that about
| serving svgs too)
| riwsky wrote:
| I agree that the font and emoji hops aren't great for
| complexity or performance, but the problem in the post was in
| the rendering of a tiny SVG; serving it directly would not have
| avoided the problem.
| bambax wrote:
| Not OT at all. Emojis everywere are ridiculous. And coding
| agents love them! They put emojis in Python log lines which
| inevitably break the console, and of course in web pages. Logs
| don't need emojis. Not sure if anything does.
| qingcharles wrote:
| I love using emojis in my log lines, especially symbols for
| info/warn/error, but it does add another layer of complexity
| as you have to go through so many things to make sure the
| text is now rendered in the right font, has Unicode support
| enabled, etc, etc.
| apike wrote:
| Not off topic at all!
|
| While in this case we'd included the emoji font for displaying
| user content in another part of the app, the hazard of letting
| a "simple" approach expand and get out of hand is part of what
| I wanted to convey in writing this.
| nananana9 wrote:
| > And despite being the least-bad approach for web frontends
| today, the React ecosystem...
|
| As if anyone has seriously tried anything other than the
| "reactive UI hacked together with callbacks or proxies, with
| weird XML-like syntax in the JS code" paradigm for the last 10
| years.
|
| At this point I just have to conclude that anyone who believes
| this stuff is good is either too indoctrinated into this workflow
| or just lacks ability to do even the tiniest amount of
| cost/benefit analysis.
| exogen wrote:
| I'd give people the benefit of the doubt. Personally, having
| built UI with Win32, WinForms, VisualBasic, Cocoa/Interface
| Builder, Qt, Tcl/Tk, XSLT, vanilla HTML/JS, jQuery, Backbone,
| Ember, Knockout, Bootstrap, MooTools, YUI, ExtJS, Svelte, Web
| Components, and React (including Preact, SolidJS...)... I'll
| happily choose the React approach. The only other one I would
| even describe as "good" was Qt.
|
| I also don't get why "XML-like syntax in the JS code" is even a
| point worth complaining about. If anything, we should be
| encouraging people to experiment with _more_ DSLs for building
| UIs. Make your tools suit the task. Who the fuck cares, if it
| 's clear and productive?
| throwaway243123 wrote:
| Whoa backbone, ember, knockout, what throwbacks right there.
| zelphirkalt wrote:
| But it is not really XML like syntax, is it? It is still a
| string, even if a template string or whatever it is called,
| no?
|
| That still leaves the door open for XSS. A good (proper?)
| (e?)DSL would have the things that make the DOM as keywords
| in the language, and then we could ensure, that things which
| should merely be a text, are really only rendered as text,
| not injected DOM nodes. And the next failure is, that this
| DSL that is jsx needs to rename HTML attributes, because of
| overlap with JS keywords like "class". It lacks the awareness
| of context and therefore is not truly like HTML, no matter
| how hard it tries to be. It also comes with hacks like "<>"
| or fragment.
|
| Overall it is usable, but not a particularly well made DSL.
| It might be as good as it gets with JS.
|
| For inspiration check SXML in various lisps, which comes with
| immunity to XSS and which works just like the rest of the
| language, can be structurally pattern matched upon and
| iterated through, like a proper tree structure.
| exogen wrote:
| > It is still a string, even if a template string or
| whatever it is called, no?
|
| No.
|
| > That still leaves the door open for XSS.
|
| The door for that in React is called
| `dangerouslySetInnerHTML`, but it's extremely rarely used.
|
| > jsx needs to rename HTML attributes, because of overlap
| with JS keywords like "class"
|
| That's not really inherent to JSX, just React's use of it.
| SolidJS, for example, uses `class` instead. But in any case
| - JSX didn't make up those names. Those are the property
| names on JavaScript's DOM classes. The fact that there's
| confusion between "attributes" and "properties" is pretty
| baked-in to the Web platform, even causing confusion in
| standard Web Components. Every DOM library and framework
| (even jQuery) has needed to decide whether it's operating
| on properties or attributes. const div =
| document.createElement('div'); div.className =
| 'foo';
|
| > It also comes with hacks like "<>" or fragment.
|
| The DOM has the same concept, DocumentFragment. How else
| would you represent e.g. "two sibling nodes with no parent
| node"?
|
| > It lacks the awareness of context and therefore is not
| truly like HTML.
|
| On the contrary, I'd argue it has way _more_ context. It
| knows, and will warn you, if you try to do any DOM element
| nesting that the HTML spec forbids, for example.
|
| > can be structurally pattern matched upon and iterated
| through, like a proper tree structure.
|
| You are literally describing the output of JSX. Glad you
| like it ;)
| exogen wrote:
| https://github.com/jquery/jquery/blob/df16f7360d4db41de64
| 589...
| nine_k wrote:
| Reactive UIs with unidirectional data binding (very important)
| seem to be the sweet spot. Spreadshees, which pioneered it in
| consumer software, still reign supreme.
|
| React is quite fast, and is very compact (preact is half the
| sizef htmx). It seems to be the sweet spot for making rich web
| UIs.
|
| In the end, this all was a red herring. The problem was in
| CoreSVG taking 1400ms to render an emoji, clearly a regression.
| A tweet would suffice to communicate this nugget, but for some
| reason the author wrote a long and winding piece.
| layer8 wrote:
| > Noto Color Emoji is a Google font that is helpful in that it
| gives you consistent emoji rendering across platforms.
|
| I'm not sure how that is helpful if users are used to the emoji
| look of their respective platform.
| conartist6 wrote:
| Mostly read like a normal article if you skip over the parts
| about using agents, which I did.
|
| There could not possibly be a single thing in the world more
| boring than listening to someone describe using an AI agent.
| Might as well describe in arduous detail how you use a gas pump
| or a grocery store checkout.
| DetroitThrow wrote:
| The part where Claude specifically tipped them off felt helpful
| to include. Stating that you used Claude to do a first pass
| just sounds like "I opened Vscode with highlighting to do a
| first pass" and that doesn't sound so relevant.
|
| I might be too used to using coding agents in various parts of
| my workflow, and others are still getting acquainted, or others
| find it still much different than just another standard
| debugging tool.
|
| And fwiw it's probably not Claude's fault that emoji fonts load
| this slow, though. Wtf Safari?
| munificent wrote:
| I found the bit about using an agent to produce a minimal repro
| case interesting.
|
| I'm very much on the side of "artisanally writing all code by
| hand" in terms of preference, but I have to admit that
| sometimes it puts me in a bind where there's stuff I wish I
| could do but don't because it's too time-consuming for the
| value provided. Isolating repro cases sometimes falls into that
| bucket.
|
| This seems like a good use case for AI. Even if the resulting
| code isn't great, as long as it repros the issue and is fairly
| small, it's fine. It's eventually throwaway code anyway. At
| best, it will be harvested for a test case, but otherwise it's
| gone once the bug is fixed.
| robocat wrote:
| Maybe consider that other people are not as au fait with AI.
|
| There are plenty of people learning to use AI and this article
| helps them.
|
| A reasonable amount of repetition of "things you should know"
| is good.
|
| The article is well written because you could skip the parts
| you knew, and learn from the parts you were unfamiliar with.
| nephihaha wrote:
| I think the problem is that the public is often being
| encouraged to use AI in ways that are not productive, or are
| misleading... At least at this point in time.
| iamcreasy wrote:
| > At that point, I reached for an age-old tool that has gotten
| more useful in the modern age: binary search. That is, you
| explain the symptom to your coding agent. Then you have it
| repeatedly remove stuff from your code that might be causing the
| problem
|
| Can someone give me some high level pointers on how to setup this
| scaffolding?
| Toutouxc wrote:
| Not sure what you mean, just have a coding agent (e.g. Claude
| Code) and talk to it.
| apike wrote:
| How well agents can do this is mostly proportional to how well
| they can understand and navigate your codebase broadly.
|
| There are various contributing factors to this, but they
| include clear docs, notes and refactors that clear up parts the
| agent commonly gets confused by, choosing boring technology
| (your dependencies are well understood) and access to command-
| line tools that let it lint + typecheck + test the code. A lot
| of the scaffolding and wiring necessary are built into Cursor
| and Claude Code themselves now. Hope that helps!
| iainmerrick wrote:
| "git bisect" usually does the trick.
| calmingsolitude wrote:
| When I read the first sentence, I expected the author to use
| `git bisect`.
|
| However, what the author seems to have done is used a prompt
| with claude that probably looked something like this:
|
| "Some piece of code is causing the page to load very slowly. To
| debug this, I'd like to use binary search, where we keep
| commenting/uncommenting 50% of the remaining code, and then I
| manually check if the page is still very slow. Let's start now;
| Comment out a component (or parts of a component) that you
| estimate is 50% of the page, and I will tell you if the page is
| still slow."
| fix4fun wrote:
| `git bisect` is interesting option. I haven't heard about it
| before. Thanks for info. Still learning something ;)
|
| I'm old school. I used to do "manual bisection" on git
| history by just `git checkout <commit_id>` until I find first
| introducing bug commit.
|
| Then another "bisection" on commit changes until minimal
| change found.
|
| Deterministic bugs are quite "fine". For me personally worst
| are randomly occurring bugs in specific conditions for eg.
| some race conditions.
| cullenking wrote:
| I do this all the time in a dumb but effective way. Add logging
| statements to code paths that drop timing info. Another dumb
| but effective way, instead of using a step through debugger, is
| drop "here, value is {val}". Telling claude to do this is
| trivial, it's quick, and it can read its own output and self-
| solve the problem all with just the code itself.
|
| IMHO git bisect is slower, especially depending on the
| reload/hot-reload/compile/whatever process your actual app is
| using.
| maxall4 wrote:
| I think you could have discovered this bug more easily by looking
| at the commit(s) that were made when the problem started.
| apike wrote:
| This is a great technique!
|
| In this case, I had made an overlarge squashed merge that
| included both the Intercom integration (a suspiciously likely
| cause of slowness) and the feedback button that added the heart
| - so I needed to go deeper to figure out the true cause. (Noto
| Emoji was in the app from before, but wasn't triggered in the
| dashboard until we added an emoji there.)
| rubenflamshep wrote:
| Enjoyed this piece! I use binary search to investigate data
| pipeline issues. Didn't think to use it to debug features with
| agents which was a very cool approach.
| arturocamembert wrote:
| > Naturally, I blamed React.
|
| Did the author start a client-side debugging process without
| running any kind of diagnostics in the dev tools?
|
| To me this sounds like "I saw some slowness in my application, so
| naturally I started adjusting indexes in my database." Without
| doing any upfront research, you're basically just throwing darts
| and hoping one sticks. This type of approach to debugging has
| never served me well.
___________________________________________________________________
(page generated 2026-02-05 23:01 UTC)