Skip to main content

Fixing a laggy list

In an app I'm building, I use SVGs in certain list items. The SVGs are custom status icons and thus are pretty simple. They contain trivial path and circle elements, have one color without any fancy gradients.

The list feels a bit janky though, especially on my crappiest Android test device. My intuition was already when I added the SVGs that this might happen. Android is not the most performant with vector graphics, especially when using react-native-svg.

I did some profiling with the Flipper mobile app debugging tool. My gut feeling was confirmed. The component which is the most prominently visible in the flame graph is the SVG, being almost ten times slower to render than the text components. 

Performance of the SVG component

Since the SVGs are so simple, the solution to this performance problem is to convert the set to a font. We use a ton of icon fonts, and they are almost as fast to render as "normal" text.

I used IcoMoon for the conversion. As expected, IcoMoon complained about the SVGs having some incorrect elements that cant convert on the first try. Fortunately, the site has high-grade documentation on how to fix that, awesome! After some Inkscape magic, I got the icon font files out from IcoMoon.

Converting elements to paths made the conversion to font possible

Finished font

What was left is to try out the font. Adding a new icon font was easy, and in no time, I was back profiling. The new flame graphs showed about 4x performance improvement. The lag in the list was gone. Not bad for a half days job!

4x performance improvement! The component is misnamed here, it is not an SVG but an icon.

Comments

Popular posts from this blog

Bird is causing high CPU on my macOS

There is no lack of people complaining about MacOS Tahoe, mostly about rounded corners and inconsistent design decisions. I have not paid that much attentention to that, but there is one mac bug i have paid attention to. It hasn't been a visual or ux but rather few system processes pegging the CPU. trustd , alongside with ecosystemd and ecosystemanalyticsd all reported high CPU usage. I can't exactly recall when this started, it might have predated my Tahoe upgrade but anyway, the trio of processes all had high CPU usage. Sure, it may have been the virtual efficiency cores and whether it affeced battery life or slowed down other processes i don't know to be hon...

How my work has changed in the past few years

When I started at my current job 3ish years ago, we had nothing but a few PowerPoint slides and a Figma prototype. I recall talking with one of the founders, whom I had worked with some 10 years ago, and pointing out that the very next step after PowerPoint and Figma was still the same as it had always been: translating those slides and mockups into CRUDs, forms, and other basic building blocks. Sure, all the new fancy tools and frameworks (we had jQuery then) help, but I still had to tinker with very basic primitives like tables and forms. I could not just say, "here is a table, here is a form." Well, yes, technically I could, but I still needed to write a lot of code to make a working form or table. This was around the time of GPT-3, Copilot beta, and very early Cursor. I did attempt to use them, but they could only perform very basic tasks and were pretty much useless for frontend work. We, being one of the first-wave "ChatGPT wrapper" startups has naturally pus...

Building a OTel sink that follows GenAI semantic conventions

I've been working on an OTel sink recently. To be more specific, it concerns receiving telemetry data from LLM interactions. Fortunately, there is a spec for all of this called GenAI Semantic Conventions . That is what I based my work on, so I can make assumptions about key attributes to highlight in the sink's UI, which is actually a CLI in my case. I dogfooded my handrolled sink using Pydantic AI (my favorite LLM framework), and all good, it follows the spec well. Key attributes flow in as specified. Pydantic AI also includes some of its own attributes, but that is expected. However, pick something like Claude Code, (via anthropic agent sdk), the reality is a bit different. It does not follow the spec at all. It has its own custom attribute layout . Same direction, different flavor with LangChain. The Python source has zero opentelemetry imports anywhere. None. The ls_* namespace ( ls_provider , ls_model_name , ls_temperature ) is its own thing, with LangSmith as the on...