Tags: ice

673

sparkline

Monday, September 20th, 2021

11ty/api-indieweb-avatar: Return an optimized avatar image from a domain name input.

Here’s a nifty little service from Zach: pass in a URL and it returns an image of the site’s icon.

Here’s mine.

Think of it as the indie web alternative to showing Twitter avatars.

Thursday, September 16th, 2021

Notes on synthetic speech - Tink - Léonie Watson

This is a fascinating deep dive by Léonie on the inner workings of speech synthesis. She has quite a conundrum: she wants fast playback, but she also wants a voice that doesn’t sound robotic. Unfortunately it’s the robotic-sounding voices that work best at speed.

If you’re interested in this topic, I highly recommend listening to (or reading) the accessibility episode of the Clearleft podcast which featured Léonie as a guest giving demos and explanations.

Writing the Clearleft newsletter

The Clearleft newsletter goes out every two weeks on a Thursday. You can peruse the archive to see past editions.

I think it’s a really good newsletter, but then again, I’m the one who writes it. It just kind of worked out that way. In theory, anyone at Clearleft could write an edition of the newsletter.

To make that prospect less intimidating, I put together a document for my colleagues describing how I go about creating a new edition of the newsletter. Then I thought it might be interesting for other people outside of Clearleft to get a peek at how the sausage is made.

So here’s what I wrote…

Topics

The description of the newsletter is:

A round-up of handpicked hyperlinks from Clearleft, covering design, technology, and culture.

It usually has three links (maybe four, tops) on a single topic.

The topic can be anything that’s interesting, especially if it’s related to design or technology. Every now and then the topic can be something that incorporates an item that’s specifically Clearleft-related (a case study, an event, a job opening). In general it’s not very salesy at all so people will tolerate the occasional plug.

You can use the “iiiinteresting” Slack channel to find potential topics of interest. I’ve gotten in the habit of popping potential newsletter fodder in there, and then adding related links in a thread.

Tone

Imagine you’re telling a friend about something cool you’ve just discovered. You can sound excited. Don’t worry about this looking unprofessional—it’s better to come across as enthusiastic than too robotic. You can put real feelings on display: anger, disappointment, happiness.

That said, you can also just stick to the facts and describe each link in turn, letting the content speak for itself.

If you’re expressing a feeling or an opinion, use the personal pronoun “I”. Don’t use “we” unless you’re specifically referring to Clearleft.

But most of the time, you won’t be using any pronouns at all:

So-and-so has written an article in such-and-such magazine on this-particular-topic.

You might find it useful to have connecting phrases as you move from link to link:

Speaking of some-specific-thing, this-other-person has a different viewpoint.

or

On the subject of this-particular-topic, so-and-so wrote something about this a while back.

Structure

The format of the newsletter is:

  1. An introductory sentence or short paragraph.
  2. A sentence describing the first link, ending with the title of the item in bold.
  3. A link to the item on its own separate line.
  4. An excerpt from the link, usually a sentence or two, styled as a quote.
  5. Repeat steps 2 to 4 another two times.


Take a look through the archive of previous newsletters to get a feel for it.

Subject line

Currently the newsletter is called dConstruct from Clearleft. The subject line of every edition is in the format:

dConstruct from Clearleft — Title of the edition

(Note that’s an em dash with a space on either side of it separating the name of the newsletter and the title of the edition)

I often try to come up with a pun-based title (often a punny portmanteau) but that’s not necessary. It should be nice and short though: just one or two words.

Tuesday, August 10th, 2021

Care at Scale | Comment Magazine

A superb piece of writing by Debbie Chachra on infrastructure, fairness, and the future.

Alone in my apartment, when I reach out my hand to flip a switch or turn on a tap, I am a continent-spanning colossus, tapping into vast systems that span thousands of miles to bring energy, atoms, and information to my household. But I’m only the slenderest tranche of these collective systems, constituting the whole with all the other members of our federated infrastructural cyborg bodies.

Wednesday, July 7th, 2021

Back to the Bad Old Days of the Web – Jorge Arango

We’ve enjoyed a relatively long period when we didn’t have to think about which browser to use. Alas, that period is ending: I must now keep Chrome running all the time, much like I needed that PC in the early 2000s.

Tuesday, July 6th, 2021

Don’t Feed the Thought Leaders - Earthly Blog

A great tool is not a universal tool it’s a tool well suited to a specific problem.

The more universal a solution someone claims to have to whatever software engineering problem exists, and the more confident they are that it is a fully generalized solution, the more you should question them.

Sunday, June 6th, 2021

Let’s talk about failure

Denise shares a cautionary tale of service design gone wrong.

Thursday, April 22nd, 2021

Full Stack Service Design – Sarah Drummond

Katie shared this (very good) piece about service design on Slack at work today, and when I got to the bit about different levels, my brain immediately went “pace layers!”

  1. The Service
  2. The Infrastructure
  3. The Organisation
  4. The Intent
  5. The Culture

Tuesday, April 13th, 2021

Remote to who? A working letter

The idea that your job should be the primary source of meaning in your life is an elaborately made trap, propped up across industries, designed to make you a loyal worker who uses the bulk of their intellectual and creative capacity to further their own career.

Tuesday, March 23rd, 2021

Service worker weirdness in Chrome

I think I’ve found some more strange service worker behaviour in Chrome.

It all started when I was checking out the very nice new redesign of WebPageTest. I figured while I was there, I’d run some of my sites through it. I passed in a URL from The Session. When the test finished, I noticed that the “screenshot” tab said that something was being logged to the console. That’s odd! And the file doing the logging was the service worker script.

I fired up Chrome (which isn’t my usual browser), and started navigating around The Session with dev tools open to see what appeared in the console. Sure enough, there was a failed fetch attempt being logged. The only time my service worker script logs anything is in the catch clause of fetching pages from the network. So Chrome was trying to fetch a web page, failing, and logging this error:

The service worker navigation preload request failed with a network error.

But all my pages were loading just fine. So where was the error coming from?

After a lot of spelunking and debugging, I think I’ve figured out what’s happening…

First of all, I’m making use of navigation preloads in my service worker. That’s all fine.

Secondly, the website is a progressive web app. It has a manifest file that specifies some metadata, including start_url. If someone adds the site to their home screen, this is the URL that will open.

Thirdly, Google recently announced that they’re tightening up the criteria for displaying install prompts for progressive web apps. If there’s no network connection, the site still needs to return a 200 OK response: either a cached copy of the URL or a custom offline page.

So here’s what I think is happening. When I navigate to a page on the site in Chrome, the service worker handles the navigation just fine. It also parses the manifest file I’ve linked to and checks to see if that start URL would load if there were no network connection. And that’s when the error gets logged.

I only noticed this behaviour because I had specified a query string on my start URL in the manifest file. Instead of a start_url value of /, I’ve set a start_url value of /?homescreen. And when the error shows up in the console, the URL being fetched is /?homescreen.

Crucially, I’m not seeing a warning in the console saying “Site cannot be installed: Page does not work offline.” So I think this is all fine. If I were actually offline, there would indeed be an error logged to the console and that start_url request would respond with my custom offline page. It’s just a bit confusing that the error is being logged when I’m online.

I thought I’d share this just in case anyone else is logging errors to the console in the catch clause of fetches and is seeing an error even when everything appears to be working fine. I think there’s nothing to worry about.

Update: Jake confirmed my diagnosis and agreed that the error is a bit confusing. The good news is that it’s changing. In Chrome Canary the error message has already been updated to:

DOMException: The service worker navigation preload request failed due to a network error. This may have been an actual network error, or caused by the browser simulating offline to see if the page works offline: see https://w3c.github.io/manifest/#installability-signals

Much better!

Thursday, March 18th, 2021

Now THAT’S What I Call Service Worker! – A List Apart

This is terrific! Jeremy shows how you can implement a fairly straightforward service worker for performance gains, but then really kicks it up a notch with a recipe for turning a regular website into a speedy single page app without framework bloat.

Friday, March 12th, 2021

The Performance Inequality Gap, 2021 - Infrequently Noted

Developers, particularly in Silicon Valley firms, are definitionally wealthy and enfranchised by world-historical standards. Like upper classes of yore, comfort (“DX”) comes with courtiers happy to declare how important comfort must surely be. It’s bunk, or at least most of it is.

As frontenders, our task is to make services that work well for all, not just the wealthy. If improvements in our tools or our comfort actually deliver improvements in that direction, so much the better. But we must never forget that measurable improvement for users is the yardstick.

Thursday, March 11th, 2021

When service workers met framesets

Oh boy, do I have some obscure browser behaviour for you!

To set the scene…

I’ve been writing here in my online journal for almost twenty years. The official anniversary will be on September 30th. But this website has been even online longer than that, just in a very different form.

Here’s the first version of adactio.com.

Like a tour guide taking you around the ruins of some lost ancient civilisation, let me point out some interesting features:

  • Observe the .shtml file extension. That means it was once using Apache’s server-side includes, a simple way of repeating chunks of markup across pages. Scientists have been trying to reproduce the wisdom of the ancients using modern technology ever since.
  • See how the layout is 100vw and 100vh? Well, this was long before viewport units existed. In fact there is no CSS at all on that page. It’s one big table element with 100% width and 100% height.
  • So if there’s no CSS, where is the border-radius coming from? Let me introduce you to an old friend—the non-animated GIF. It’s got just enough transparency (though not proper alpha transparency) to fake rounded corners between two solid colours.
  • The management takes no responsibility for any trauma that might befall you if you view source. There you will uncover JavaScript from the dawn of time; ancient runic writing like if (navigator.appName == "Netscape")

Now if your constitution was able to withstand that, brace yourself for what happens when you click on either of the two links, deutsch or english.

You find yourself inside a frameset. You may also experience some disorienting “DHTML”—the marketing term given to any combination of JavaScript and positioning in the late ’90s.

Note that these are not iframes, they are frames. Different thing. You could create single page apps long before Ajax was a twinkle in Jesse James Garrett’s eye.

If you view source, you’ll see a React-like component system. Each frameset component contains frame components that are isolated from one another. They’re like web components. Each frame has its own (non-shadow) DOM. That’s because each frame is actually a separate web page. If you right-click on any of the frames, your browser should give the option to view the framed document in its own tab or window.

Now for the part where modern and ancient technologies collide…

If you’re looking at the frameset URL in Firefox or Safari, everything displays as it should in all its ancient glory. But if you’re looking in Google Chrome and you’ve visited adactio.com before, something very odd happens.

Each frame of the frameset displays my custom offline page. The only way that could be served up is through my service worker script. You can verify this by opening the framest URL in an incognito window—everything works fine when no service worker has been registered.

I have no idea why this is happening. My service worker logic is saying “if there’s a request for a web page, try fetching it from the network, otherwise look in the cache, otherwise show an offline page.” But if those page requests are initiated by a frame element, it goes straight to showing the offline page.

Is this a bug? Or perhaps this is the correct behaviour for some security reason? I have no idea.

I wonder if anyone has ever come across this before. It’s a very strange combination of factors:

  • a domain served over HTTPS,
  • that registers a service worker,
  • but also uses framesets and frames.

I could submit a bug report about this but I fear I would be laughed out of the bug tracker.

Still …the World Wide Web is remarkable for its backward compatibility. This behaviour is unusual because browser makers are at pains to support existing content and never break the web.

Technically a modern website (one that registers a service worker) shouldn’t be using deprecated technology like frames. But browsers still need to be able support those old technologies in order to render old websites.

This situation has only arisen because the same domain—adactio.com—is host to a modern website and a really old one.

Maybe Chrome is behaving strangely because I’ve built my online home on ancient burial ground.

Update: Both Remy and Jake did some debugging and found the issue…

It’s all to do with navigation preloads and the value of event.preloadResponse, which I believe is only supported in Chrome which would explain the differences between browsers.

According to this post by Jake:

event.preloadResponse is a promise that resolves with a response, if:

  • Navigation preload is enabled.
  • The request is a GET request.
  • The request is a navigation request (which browsers generate when they’re loading pages, including iframes).

Otherwise event.preloadResponse is still there, but it resolves with undefined.

Notice that iframes are mentioned, but not frames.

My code was assuming that if event.preloadRepsonse exists in my block of code for responding to page requests, then there’d be a response. But if the request was initiated from a frameset, it is a request for a page and event.preloadRepsonse does exist …but it’s undefined.

I’ve updated my code now to check this assumption (and fall back to fetch).

This may technically still be a bug though. Shouldn’t a page loaded from a frameset count as a navigation request?

Monday, March 8th, 2021

The Right Number

The Right Number is a gentle, noncommercial space where your only job is to be yourself. Upon dialing you’ll be connected to a voicemail box and given a brief prompt. You have three minutes to answer however you’d like.

Saturday, February 20th, 2021

Iceberger

Draw an iceberg and see how it will float.

Thursday, February 11th, 2021

The web didn’t change; you did

The problem with developing front end projects isn’t that it’s harder or more complicated, it’s that you made it harder and more complicated.

Yes! THIS!

Web development did not change. Web development grew. There are more options now, not different options.

You choose complexity. You can also choose simplicity.

Thursday, January 28th, 2021

How to be clear – gilest.org

Good advice for writing:

  • Think about what your readers might already know
  • Write shorter sentences, with simpler words
  • Constantly think about audiences
  • Communicate with purpose
  • Clear communication helps teams solve problems

Saturday, January 16th, 2021

Enable/unmute WebAudio on iOS, even while mute switch is on

Remember when I wrote about Web Audio weirdness on iOS? Well, this is a nice little library that wraps up the same hacky solution that I ended up using.

It’s always gratifying when something you do—especially something that feels so hacky—turns out to be independently invented elsewhere.

Monday, December 21st, 2020

Web Audio API weirdness on iOS

I told you about how I’m using the Web Audio API on The Session to generate synthesised audio of each tune setting. I also said:

Except for some weirdness on iOS that I had to fix.

Here’s that weirdness…

Let me start by saying that this isn’t anything to do with requiring a user interaction (the Web Audio API insists on some kind of user interaction to prevent developers from having auto-playing sound on websites). All of my code related to the Web Audio API is inside a click event handler. This is a different kind of weirdness.

First of all, I noticed that if you pressed play on the audio player when your iOS device is on mute, then you don’t hear any audio. Seems logical, right? Except if using the same device, still set to mute, you press play on a video or audio element, the sound plays just fine. You can confirm this by going to Huffduffer and pressing play on any of the audio elements there, even when your iOS device is set on mute.

So it seems that iOS has different criteria for the Web Audio API than it does for audio or video. Except it isn’t quite that straightforward.

On some pages of The Session, as well as the audio player for tunes (using the Web Audio API) there are also embedded YouTube videos (using the video element). Press play on the audio player; no sound. Press play on the YouTube video; you get sound. Now go back to the audio player and suddenly you do get sound!

It’s almost like playing a video or audio element “kicks” the browser into realising it should be playing the sound from the Web Audio API too.

This was happening on iOS devices set to mute, but I was also getting reports of it happening on devices with the sound on. But it’s that annoyingly intermittent kind of bug that’s really hard to reproduce consistently. Sometimes the sound doesn’t play. Sometimes it does.

Following my theory that the browser needs a “kick” to get into the right frame of mind for the Web Audio API, I resorted to a messy little hack.

In the event handler for the audio player, I generate the “kick” by playing a second of silence using the JavaScript equivalent of the audio element:

var audio = new Audio('1-second-of-silence.mp3');
audio.play();

I’m not proud of that. It’s so hacky that I’ve even wrapped the code in some user-agent sniffing on the server, and I never do user-agent sniffing!

Still, if you ever find yourself getting weird but inconsistent behaviour on iOS using the Web Audio API, this nasty little hack could help.