Skip to main content

Posts

Messing around with kaboom.js

I created a simple "about me" website in the most ridiculous possible way I could imagine.  https://jompanakumpana.fi/ I did it with kaboom.js , a simple library by  replit . It's best explained by just trying it out. Trust me, it is a fun way to spend an afternoon or two!

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 c...

Seriously uncool Java?

A couple of podcasts I have listened to recently have flamed Java. It is a good "kusitolppa", a seriously uncool technology.  I'm pleased about not having to write Java anymore. Yet, I'll risk career suicide and take a stance to defend it against some of the low blows. After all, it was my bread and butter for quite many years. I get it; writing Java is not in fashion. It is likely a wrong choice for a modern startup. The language is full of mysterious cargo-cultish traditions, is verbose, has annotations on top of annotations and you have to use an editor which eats half of your memory (the other half is used by the Java process you are working on). Traditional Java and JDKs are ill-fitted for short-running processes like lambdas; it needs time to warm to get up to speed and needs more than one core to work efficiently. It has horrible dependency management tools by today's standards. Running a JVM process requires all kinds of weird flags, its defaults are unlik...

React native lazy screens

React native 0.64 by default has "inline requires"  enabled. We can now easily squeeze some milliseconds out of the app startup time. Here are a couple of examples of how to do it with React Navigation . If some navigation paths are behind feature flags, you can import them conditionally at the navigator level, skipping potentially unused code to be loaded on startup while preventing users' access to unreleased features. You can also create lazy loading screens that will require the actual implementation only when it has received a navigation event.

Distroless image internals

We used a Google "distroless" image as the base image on a go application deployment in a project a while ago. I never looked into what distroless really means, but I had a guess. I'm also curious to look under the hood of a docker image if they really are just merged archives. Recently there was a "Docker without docker" blog post in Hacker news about how simple docker (or rather, OCI) image format is. Spoiler: an image is tar archives on top of tar archives. The post has also a detailed explanation of how to pull images from a container registry. I shamelessly took the image pull script they shared and modified it a bit to pull the static distroless image from the Google container registry. The image is only one layer, and here is how it looks like after I extracted it and removed all the root level empty directories with all directories with at least one file expanded. It looks pretty empty to me, and I suppose that's th...

Remote file size with a HTTP HEAD request

I learned from my brilliant colleagues a nice trick that left me once again wondering why on earth I discover these things only now. It's funny to run into something literally everyone else knows, and somehow, I miss. Say you have a file that you want to download on some trusted server. You may have a version of the file downloaded, but it may be somehow corrupted or partially downloaded. You could verify the file integrity by comparing the local and remote file hashes, and that is indeed a proper way to do it.  If you trust the remote, you can use plain old HTTPS to get the headers only with a HEAD request and get the content length. Just compare the result to local, and there you have it, a naive yet adequate method to check if you need to redownload a file. Note that this does not validate that the file contents are equal. 

Rule of three

Of all the horrific code I have written, by far, the most harmful and destructive have involved too early abstraction. Everyone knows the issues stemming from the wrong abstraction. Even copy-paste code would have been a better choice than creating some seemingly fancy, say, adapter pattern implementation. To be honest, I think copy-paste has a worse reputation than it should. A given project might have started with best practices, module structure, libraries of a prior project/16k star primer. That can be good! Some best practices naturally transcend projects. We should bring in the lessons learned but the timing matters. Upon a closer look, the project might indeed have agreeable abstractions. Still, those could be hollow and bring only extra LOCs and solve the issues faced in the previous projects, which have never occurred in the current one. Upon recently starting two soon-to-be large projects, I learned to leave some wisdom from previous lives behind. While deep in the coding zen...