Archive for the ‘Life’ Category

15 years of blogging

My first blog post was published just under 15 years ago in March of 2011. Since then, I’ve published 151 posts, including this one. (If I was a numerologist, I’d think it had something to do with Pokémon.)

This blog has covered a wide variety of topics, including Pokémon in fact (I wrote the first Pokédex app for Android). The topics largely followed the trajectory of my career: starting with machine learning, veering into Android, taking a detour into Solr/Lucene, and eventually settling on JavaScript and web development. Later I wrote about web performance, accessibility, web components – basically whatever topic crossed my desk. You’re reading the unfiltered output of my brain here, more or less.

I don’t publish a lot – less than one post per month apparently. My main guiding principle is that I don’t write unless some topic is itching to get off my chest, or I think I have something novel to say. There are no ads on this humble WordPress blog, and I don’t have anything to sell you, so there’s nothing motivating me except my own desire to explore an idea, make a point, or just stretch the old writing muscle.

As you can tell, I’m too lazy to even update the vintage WordPress theme – odd for someone who pretends to be a professional web developer! I’ve always felt like that was a distraction, though. I know some bloggers who spend more time tweaking their CSS than writing content, and that’s fine, but it was just never my goal for this blog. If I want to scratch that itch, I write an oddball project like Pokedex.org or Pinafore instead.

The biggest challenge of the early days of this blog was just getting anybody to read it. The biggest challenge later on was dealing with the overwhelming anxiety of realizing “Oh shit, people are actually reading this”, followed by the inevitable fears of:

  • blowback (I got too controversial)
  • audience capture (I got soft)
  • being ignored (I got boring)

I feel like I’ve careened between all of these extremes over the past 15 years. Overall my writing was a lot more freewheeling in the past, and I’ve tried to recapture some of that lately, but having an audience just naturally gnaws at your mind in a way that (I find) I can’t totally ignore.

Quitting Twitter (and wasn’t that a weird story arc on my blog!) helped a lot, although there’s still of course Mastodon and Lobsters and Hacker News and all the rest where the comments can be a vicious cesspool if you spend too much time there. (If you’re reading this from RSS: you’re my favorite readers, and they can take my RSS reader from my cold dead hands!)

Not that this blog has a ton of readers. There’s actually a list of the most popular blogs on Hacker News, and mine hit #631 last year. This puts me somewhere between “I think I’ve seen his face on the internet once” and “never heard of him.” Although based on my WordPress stats, my best days are somewhat behind me, with my all-time most popular posts being:

Although rounding out the top 10, we do get some more recent hits:

Interestingly to me, though, the work that I’m most proud of didn’t get a lot of traction. It wasn’t a polemic, or a thinkpiece, or a perhaps-too-glib takedown of a major browser vendor (sigh) but instead my work on performance optimizations, benchmarking, etc. A lot of my blog posts are basically: “People say this thing is fast. Is it though? Let’s run some numbers.” For example:

This is the kind of stuff that (I like to think) really moves the needle in the web development space, because words are cheap but numbers talk. I’ve heard from some folks that a post of mine immediately short-cutted some internal discussion about whether they should choose Strategy A or B for their web app. I love having that kind of impact!

This experience has taught me that the page stats aren’t everything. Sometimes it’s not about how many people read your post, but whether the right people read it. One example is my recent post on the js-framework-benchmark. This was a sleeper hit: barely touching any of the socials, never high on Hacker News or Lobsters, and yet I know from personal anecdotes that performance experts read it and appreciated it. Not every post needs to be a thrilling dimestore paperback: some can be a ponderous Tolstoy or Joyce.

Conclusion

When I first started this blog, I was early in my career and didn’t really know what I was doing. I made a blog because I guess I thought it was the cool thing to do, and that maybe it would help me land a job someday.

I named it “Read the Tea Leaves” because I thought you were supposed to have a punchy title like “Daring Fireball” or “Coding Horror”. If I were starting it today, I’d probably just call it “Nolan Lawson’s blog” and be done with it (although I do love tea).

Keeping this blog has been a great source of passion for me, and it has indeed opened doors in my career. I landed my most recent job in no small part thanks to this blog (good foresight, 2011 me!), and it’s also just really fun to get recognized at a conference or have a coworker mention that they enjoyed one of my posts.

I’ve found though that the greatest value is just the act of writing itself. That’s one reason I don’t use AI for any of these posts (heck, I don’t even use Grammarly – all the spelling mistakes are mine!). The act of writing is also the act of thinking, and my thoughts are (usually) sharpened by typing words into a blank page.

And if nothing else, I can put an idea out there, let it get tossed in the wind, and see if anybody picks it up to do something useful with it (even if that something is just to denounce or refute it). For that reason, I don’t even regret my most controversial posts, and not even the ones I disagree with today, because I think there’s still value in being wrong in public and at least trying to stimulate people’s minds in the right direction.

Would I recommend that young coders take up blogging? Absolutely. Start up a blog anywhere – WordPress, Squarespace, a file server of HTML files, whatever. Write all the time, even if you don’t always hit “publish.” (I certainly don’t – 63 unpublished drafts!)

Get yourself in the habit of being brave in public, and try to ignore that voice that says “This isn’t good enough” or “You’re not smart enough” or “People will hate you for this.” I’ve sacrificed a lot of sacred cows over the years, and maybe even burned some bridges (man, my recent AI posts may have done that). But if I hadn’t tried to speak my mind, put my thoughts out there, and find the courage to be vulnerable in public, then I would have just felt limp and cowardly and boring. That’s what I regret most: all the blog posts I didn’t write.

Still, I do have a high bar for this blog (despite what some haters may believe!), so I don’t intend to become one of those “post-a-day” kind of people. It’s just not my style. But I do hope to be the kind of person who has more ideas worth expressing and worth putting into cyberspace. Here’s to 15 more years of blogging.

Goodbye Salesforce, hello Socket

Photo of a Salesforce Trailblazer hoodie next to a Socket t-shirt

Big news for me: after 6 years, I’m leaving Salesforce to join the folks at Socket, working to secure the software supply chain.

Salesforce has been very good to me. But at a certain point, I felt the need to branch out, learn new things, and get out of my comfort zone. At Socket, I’ll be combining something I’m passionate about – the value of open source and the experience of open-source maintainers – with something less familiar to me: security. It’ll be a learning experience for sure!

In addition to learning, though, I also like sharing what I’ve learned. So I’m grateful to Salesforce for giving me a wellspring of ideas and research topics, many of which bubbled up into this very blog. Some of my “greatest hits” of the past 6 years came directly from my work at Salesforce:

Let’s learn how modern JavaScript frameworks work by building one

Salesforce builds its own JavaScript framework called Lightning Web Components, which is a little-known but surprisingly mighty tool. As part of my work on LWC, I helped modernize its architecture, which led to this post summarizing some of the trends and insights from the last ~10 years of framework design. Thanks to this work, LWC now scores pretty respectably on the js-framework-benchmark (although I still have some misgivings about the benchmark itself).

This work was also eye-opening to me, because it was my first time working as a paid open-source maintainer. Overall, I think it was a great choice on Salesforce’s part, and I wish that more companies were willing to invest in the open-source ecosystem, or at least to open up their internal tools. In LWC, we had plenty of external contributors, we got direct feedback from customers via GitHub issues, and it was easy to swap notes with other framework authors (notably in the Web Components Community Group). Plus I believe open source tends to raise the bar of quality for any project – so it’s something companies should consider for that reason alone.

A tour of JavaScript timers on the web

On the Microsoft Edge team, I learned a ton about browser internals, including little-known secrets about why certain browser APIs work the way they do. (Nothing better than “I wrote the spec, let me tell you what’s wrong with it” to get the real scoop!)

This post was a brain-dump of all the ways that JavaScript timers like setTimeout and setImmediate work across browser engines. I was intimately familiar with this topic, since Edge (not Chromium-based at the time) had been working to revamp a lot of their APIs such as Promise and fetch.

The original inspiration was a conversation I had with a colleague during my early days at Salesforce, where we debated the most performant way to batch up JavaScript work. This post still holds up pretty well today, although new fanciness like scheduler.yield() and isInputPending() isn’t covered.

Shadow DOM and accessibility: the trouble with ARIA

As part of my work at Salesforce, I was heavily involved in the Accessibility Object Model working group, partnering with folks at Igalia, Microsoft, Apple, and elsewhere to help fix problems of accessibility in web components. This led to a slew of posts on this topic, but ultimately my proudest outcome is not my own, but rather the Reference Target spec spearheaded by Ben Howell at Microsoft and now prototyped in Chromium.

After ~2 years in the working group, I was honestly starting to lose hope that we’d ever find a spec that the browser vendors could agree on. But eventually Ben joined the group, and his patience and tenacity won the day. I didn’t even contribute much (I mostly just gave feedback), but I’m still proud of what the group accomplished, and I’m hopeful that accessibility in web components will be considered a solved problem in a couple years.

My talk on CSS runtime performance

Big companies have big codebases. And big codebases can end up with a lot of CSS. Most of the time you don’t need to worry about CSS performance, but at the extremes, it can become surprisingly important.

At Salesforce, I learned way more than I ever wanted to know about how browsers handle CSS and how it affects page performance. I fixed several performance bottlenecks and regressions due to CSS (yes, a CSS change can make a page slower!), and I also filed bugs on browsers that made CSS faster for everyone. (Attributes are now roughly as fast as classes, I’m happy to say.) I also gave this fun talk at Perf.now summarizing all my findings.

Memory leaks: the forgotten side of web performance

Salesforce is a huge SPA, and as such, it has its share of memory leaks. I found that the more I looked for, the more I uncovered. At first I thought this was a Salesforce-specific issue, but then I built fuite and slowly realized that all SPAs leak. It’s more like a chronic condition to be managed than a disease to be eradicated. (If you can find an SPA without memory leaks, I’ll give you a cookie!)

I continue to maintain fuite, and I still occasionally hear from folks who have used it to fix memory leaks in their apps. Since I wrote it, Meta also released Memlab, and the Microsoft Edge team made tons of memory-related improvements to the Chromium DevTools. I still strongly feel, though, that this field is in its infancy. (Stoyan Stefanov has a great recent talk on the topic, pointing out how critical yet under-explored it is.)

The balance has shifted away from SPAs

My work on memory leaks also led me to question the value of SPAs in general. With all the improvements in browsers over the years, I came to the conclusion that MPAs are the right architecture for ~90% of web sites and apps. SPAs still have their place, but their value is dwindling year after year.

Since I wrote this post, Chrome and Safari both shipped View Transitions, and Chrome shipped Speculation Rules. With this combo, you can preload a page when the user hovers a link and then smoothly animate to it once they click. This was the whole raison d’être of SPAs in the first place, and now it’s just built into the browser.

SPAs are not going away, but their heyday is over. I think someday we’ll look back and be amazed at how much complexity we tolerated.

Conclusion

I’m grateful to Salesforce and all my wonderful colleagues there, and I’m also excited to start my next chapter at Socket. More than anything, I’m excited by the crew that I’ll be joining – John-David Dalton is a former colleague from both Microsoft and Salesforce, and Feross Aboukhadijeh is someone I’ve admired for years. (I’ve spent enough hours hearing his voice on the JS Party podcast that we practically feel like old friends.)

It’s hard to predict the future, but I know that, whatever happens, I’ll be talking about it on this blog. I’ve been running this blog for 14 years through 6 different jobs, with topics ranging from NLP to Android to web development, and I don’t see myself slowing down now. Here’s to a great 2025!

My love-hate affair with technology

Ten years ago I would have considered myself someone who was excited about new technology. I always had the latest smartphone, I would read the reviews of new Android releases with a lot of interest, and I was delighted when things like Google Maps Navigation, speech-to-text, or keyboard swiping made my life easier.

Nowadays, to the average person I probably look like a technology curmudgeon. I don’t have a smart speaker, a smart watch, or any smart home appliances. My 4-year-old phone runs a de-Googled LineageOS that barely runs any apps other than Signal and F-Droid. My house has a Raspberry Pi running Nextcloud for file storage and Pi-hole for ad blocking. When I bought a new TV I refused to connect it to the Internet; instead, I hooked it up to an old PC running Ubuntu so I can watch Netflix, Hulu, etc.

My wife complains that none of the devices in our house work, and she’s right. The Pi-hole blocks a lot of websites, and it’s a struggle to unblock them. Driving the TV with a wireless keyboard is cumbersome. Nextcloud is clunky compared to something like Dropbox or Google Drive. I even tried cloudflared for a while, but I had to give up when DNS kept periodically failing.

One time – no joke – I had a dream that I was using some open-source alternative to a popular piece of software, and it was slow and buggy. I don’t even remember what it was, but I remember being frustrated. This is just what I’m used to nowadays – not using a technology because it’s the best-in-class or makes my life easier, but because it meets some high-minded criteria about how I think software should be: privacy-respecting, open-source, controlled by the user, etc.

To the average person, this is probably crazy. “Nolan,” they’d say. “You couldn’t order a Lyft because their web app didn’t work in Firefox for Android. Your files don’t sync away from home because you’re only running Nextcloud on your local network. Your friends can’t even message you on WhatsApp, Facebook, or Twitter because you don’t have an account and the apps don’t work on your phone. If you want to live in the eighteenth century so bad, why don’t you get a horse and buggy while you’re at it?”

Maybe this nagging voice in my head is right (and I do think these thoughts sometimes). Maybe what I’m practicing is a kind of tech veganism that, like real veganism, is a great idea in theory but really hard to stick to in practice. (And yes, I’ve tried real veganism too. Maybe I should join a monastery at this point.)

On the other hand, I have to remind myself that there are benefits to the somewhat ascetic lifestyle I’ve chosen. The thing that finally pushed me to switch from stock Android to de-Googled LineageOS was all the ads and notifications in Google Maps. I remember fumbling around with a dozen settings, but never being able to get rid of the “Hey, rate this park” message. (Because everything on Earth needs a star rating apparently.)

And now, I don’t have to deal with Google Maps anymore! Instead I deal with OsmAnd~, which broke down the other day and failed to give me directions. So it goes.

Maybe someday I’ll relent. Maybe I’ll say, “I’m too old for this shit” and start using technology that actually works instead of technology that meets some idealistic and probably antiquated notion of software purity. Maybe I’ll be forced to, because I need a pacemaker that isn’t open-source. Or maybe there will be some essential government service that requires a Google or Apple phone – my state’s contact tracing app does! I got jury duty recently and was unsurprised to find that they do everything through Zoom. At what point will it be impossible to be a tech hermit, without being an actual hermit?

That said, I’m still doing what I’m doing for now. It helps that I’m on Mastodon, where there are plenty of folks who are even more hardcore than me. (“I won’t even look at a computer if it’s running non-FLOSS software,” they smirk, typing from their BSD laptop behind five layers of Tor.) Complaining to this crowd about how I can’t buy a TV anymore without it spying on me makes me feel a little bit normal. Just a bit.

The thing that has always bothered me about this, and which continues to bother me, is that I’m only able to live this lifestyle because I have the technical know-how. The average person would neither know how to do any of the things I’m doing (installing a custom Android ROM, setting up Nextcloud, etc.), nor would they probably want to, given that it’s a lot of extra hassle for a sub-par experience.

And who am I, anyway? Edward Snowden? Why am I LARPing as a character in a spy novel when I could be focusing on any one of a million other hobbies in the world?

I guess the answer is: this is my hobby. Figuring out how to get my Raspberry Pi to auto-update is a hobby. Tinkering with my TV setup so that I can get Bluetooth headphones working while the TV is in airplane mode is a hobby. Like a gearhead who’s delighted when their car breaks down (“Hey! Now I can fix it!”), I don’t mind when the technology around me doesn’t work – it gives me something to do on the weekend! But I have no illusions that this lifestyle makes sense for most people. Or that it will even make sense for me, once I get older and probably bored of my hobby.

For the time being, though, I’m going to keep acting like technology is an enemy I need to subdue rather than a purveyor of joys and delights. So if you want to know how it’s going, subscribe to my blog via RSS or message me on Signal. Or if that fails, come visit me in a horse and buggy.