Speedy tunes

Performance is a high priority for me with The Session. It needs to work for people all over the world using all kinds of devices.

My main strategy for ensuring good performance is to diligently apply progressive enhancement. The core content is available to any device that can render HTML.

To keep things performant, I’ve avoided as many assets (or, more accurately, liabilities) as possible. No uneccessary images. No superfluous JavaScript libraries. Not even any web fonts (gasp!). And definitely no third-party resources.

The pay-off is a speedy site. If you want to see lab data, run a page from The Session through lighthouse. To see field data, take a look at data from Chrome UX Report (Crux).

But the devil is in the details. Even though most pages on The Session are speedy, the outliers have bothered me for a while.

Take a typical tune page on the site. The data is delivered from the server as HTML, which loads nice and quick. That data includes the notes for the tune settings, written in ABC notation, a nice lightweight text format.

Then the enhancement happens. Using Paul Rosen’s brilliant abcjs JavaScript library, those ABCs are converted into SVG sheetmusic.

So on tune pages there’s an additional download for that JavaScript library. That’s not so bad though—I’m using a service worker to cache that file so there’ll only ever be one initial network request.

If a tune has just a few different versions, the page remains nice and zippy. But if a tune has lots of settings, the computation starts to add up. Converting all those settings from ABC to SVG starts to take a cumulative toll on the main thread.

I pondered ways to avoid that conversion step. Was there some way of pre-generating the SVGs on the server rather than doing it all on the client?

In theory, yes. I could spin up a headless browser, run the JavaScript and take a snapshot. But that’s a bit beyond my backend programming skills, so I’ve taken a slightly different approach.

The first time anyone hits a tune page, the ABCs getting converted to SVGs as usual. But now there’s one additional step. I grab the generated markup and send it as an Ajax payload to an endpoint on my server. That endpoint stores the sheetmusic as a file in a cache.

Next time someone hits that page, there’s a server-side check to see if the sheetmusic has been cached. If it has, send that down the wire embedded directly in the HTML.

The idea is that over time, most of the sheetmusic on the site will transition from being generated in the browser to being stored on the server.

So far it’s working out well.

Take a really popular tune like The Lark In The Morning. There are twenty settings, and each one has four parts. Previously that would have resulted in a few seconds of parsing and rendering time on the main thread. Now everything is delivered up-front.

I’m not out of the woods. A page like that with lots of sheetmusic and plenty of comments is going to have a hefty page weight and a large DOM size. I’ve still got a fair bit of main-thread work happening, but now the bulk of it is style and layout, whereas previously I had the JavaScript overhead on top of that.

I’ll keep working on it. But overall, the speed improvement is great. A typical tune page is now very speedy indeed.

It’s like a microcosm of web performance in general: respect your users’ time, network connection and battery life. If that means shifting the work from the browser to the server, do it!

Have you published a response to this? :

Responses

Caro

@adactio This came across my feed *just* as I was taking a break from tackling a very similar problem with abcjs performance on a big page! Thanks so much for the tips, and for all the work you do on The Session

# Posted by Caro on Friday, September 15th, 2023 at 2:34pm

2 Shares

# Shared by Sergey Chernyshev :verified: on Friday, September 15th, 2023 at 1:34pm

# Shared by Caro on Friday, September 15th, 2023 at 3:01pm

3 Likes

# Liked by Sergey Chernyshev :verified: on Friday, September 15th, 2023 at 1:34pm

# Liked by Caro on Friday, September 15th, 2023 at 3:01pm

# Liked by Rasmus Kaj on Friday, September 15th, 2023 at 3:34pm

Related posts

Securing client-side JavaScript

Tightening up my content security policy.

My approach to HTML web components

Naming custom elements, naming attributes, the single responsibility principle, and communicating across components.

Pickin’ dates

HTML web components for augmenting date inputs.

Secure tunes

Closing a security hole on The Session.

Relative times

Messing around with Intl.RelativeTimeFormat on The Session.

Related links

How Microsoft Edge Is Replacing React With Web Components - The New Stack

“And so what we did is we started looking at, internally, all of the places where we’re using web technology — so all of our internal web UIs — and realized that they were just really unacceptably slow.”

Why were they slow? The answer: React.

“We realized that our performance, especially on low-end machines, was really terrible — and that was because we had adopted this React framework, and we had used React in probably one of the worst ways possible.”

Tagged with

The State of ES5 on the Web

This is grim:

If you look at the data below on how popular websites today are actually transpiling and deploying their code to production, it turns out that most sites on the internet ship code that is transpiled to ES5, yet still doesn’t work in IE 11—meaning the transpiler and polyfill bloat is being downloaded by 100% of their users, but benefiting none of them.

Tagged with

Reckoning: Part 1 — The Landscape - Infrequently Noted

I want to be a part of a frontend culture that accepts and promotes our responsibilities to others, rather than wallowing in self-centred “DX” puffery. In the hierarchy of priorities, users must come first.

Alex doesn’t pull his punches in this four-part truth-telling:

  1. The Landscape
  2. Object Lesson
  3. Caprock
  4. The Way Out

The React anti-pattern of hugely bloated single-page apps has to stop. And we can stop it.

Success or failure is in your hands, literally. Others in the equation may have authority, but you have power.

Begin to use that power to make noise. Refuse to go along with plans to build YAJSD (Yet Another JavaScript Disaster). Engineering leaders look to their senior engineers for trusted guidance about what technologies to adopt. When someone inevitably proposes the React rewrite, do not be silent. Do not let the bullshit arguments and nonsense justifications pass unchallenged. Make it clear to engineering leadership that this stuff is expensive and is absolutely not “standard”.

Tagged with

Every website and web app should have a service worker | Go Make Things

Needless to say, I agree with this sentiment.

I’ve worked with a lot of browser technology over the years. Service workers are pretty mind-blowing.

Tagged with

Faster Connectivity !== Faster Websites - Jim Nielsen’s Blog

The bar to overriding browser defaults should be way higher than it is.

Amen!

Tagged with

Previously on this day

2 years ago I wrote Let’s get logical

Let me hear your blocky talk.

3 years ago I wrote Design engineering on the Clearleft podcast

If you like the sound of being a design engineer, come and join us at Clearleft.

4 years ago I wrote A declarative Web Share API

button type=”share”

11 years ago I wrote Parsing webmentions

Hell has frozen over …you can now comment on my site. But there’s a catch.

12 years ago I wrote Listen to Brighton SF

The audio (and transcript) is available for your listening (and reading) pleasure.

13 years ago I wrote Boston Global Scope

This. This is how we should build for the web.

15 years ago I wrote The devil in the details

The HTML5 spec has been updated again.

15 years ago I wrote Wayfinders keepers

I want you to show me the way.

16 years ago I wrote Self loathing for Sumo

I’m a cheap and dirty little blogslut.

22 years ago I wrote Adactizilla

It’s time for a new CSS theme ‘round here.