[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)