Reading List
The most recent articles from a list of feeds I subscribe to.
2018 in review
The year is about to end, so here is another year in review post!
Some might think it is odd to summarise one’s own year, but I think it is fun to share some facts and thoughts. I love reading these kinds of posts from others (hi Zell, Andy, Chee-Aun, Nienke, Heydon). So here we go. Like last year, I’ve divided stuff into highlights and things I learned. To be clear, that doesn’t mean I had a year consisting of 100% highlights and learnings. That would be weird. Of course there was also stuff that went wrong, wasn’t amazing or was personal. I just think they’re for elsewhere (in person over drinks).
Highlights
Projects
In 2018, I spent most of my time in Mozilla’s Open Innovation team, that I’ve been part of for over a year now (as a contractor). I feel very lucky to get to work with so many smart people. I’m specifically working on the IAM project. For those unfamiliar with the acronym: IAM is short for identity and access management, it is about how people prove who they are (for instance, with email or a third party) and get access to stuff with as little friction as possible. That is particularly challenging when people have multiple identities, which most do. As part of the IAM effort, it’s been super exciting to build most of the front-end for a project codenamed “DinoPark”, which is currently in closed beta. I’m excited to continue this work in 2019 and share more when we can.
In Q4, I also spent a day a week working at the City of The Hague, specifically helping with improving accessibility and profesionalising front-end development of their digital services. It’s been great to see improvements shipped both in the application’s code as well as the content management system product. Looking forward to what we’ll do next year.
Other short engagements included:
- teaming up with Jeroen and Peter, I helped NOS, the Dutch broadcaster, with an accessibility audit, user tests with visually impaired users and an in-house presentation on technical accessibility
- I ran a one day workshop on accessibility guidelines at Zilveren Kruis
- with Peter, I worked on JavaScript to power a chat-like interface for the Dutch government
Volunteering
I did not do a lot of volunteering this year, but I did translate the Inclusive Design Principles into Dutch and worked on improving MDN documentation on accessibility.
Cities
This year, I traveled to Munich, Bristol, Munich (twice), Taipei, San Francisco, Mountain View, Paris, Como, London (twice), Berlin (twice), and Düsseldorf. I’m not so proud of this carbon footprint, and experimented with European train travel, which took a bit more time, but was pretty ok for productivity.
My terrible attempt at taking a panorama picture from the rooftop of the Mozilla offices in San Francisco
Conferences and events
This year, I attended these events:
- Beyond Tellerand Munich
- Fronteers Conference
- Mozilla Festival (UK)
- performance.now()
- Design Ethics Conference
Proof that I attended events: new stickers!
I spoke multiple times, too:
- about password managers at MozTW community meetup (Taiwan) and #HackOnMDN (UK)
- about graphic design and the web at Front-end United and CSS Day
- about accessibility essentials at Refresh Conference
- about philosophical ethics at Accessibility Club Conference (Germany)
I did my CSS Layout workshop three more times (for Fronteers and at Front-end United) and ran a new accessible components workshop (for Frozen Rockets).
Organisers, thanks so much for having me, a newbie speaker. The first time conference speaking was stressful, time-consuming and very scary, but also satisfying. I got great feedback, both praise (yay!) and things I can improve on (thanks, you know who you are).
I’d love to speak more in 2019, please do get in touch if you want to have me present at your event or give a workshop.
Writing
I published 26 posts on this blog, not including this one. Like I said in last year’s review: I very much recommend writing to fellow people who work on the web, it can be helpful in many ways. It is also great to be able to do this on a domain you own, on pages you designed and built. If anyone needs mentoring around this, get in touch, I would love to help!
Some of the most read posts:
- More accessible markup with display:contents on a bug in
display: contents
implementation in major browswers that undoes accessibility benefits the property could have brought otherwise (since fixed in Firefox stable and being fixed in Chromium) - What kind of ethics do front-end developers need? - in which I tried to make the idea of ‘more ethics’ practical for front-end developers
- Let’s serve everyone good looking content on, wow, really, in 2018, that websites don’t need to look the same in 2018. I find this is still a thing at my clients and those of devs I talked to.
- How to make password managers play ball with your login form sharing what I learned about password manager compatibility
Reading
It felt a bit weird to have the Goodreads app keep me in check reading-wise, but it did the job. I managed to read more than the goal I set: 46 books. Some that readers of this blog might find interesting:
- Brotopia, about the ‘bros’ that founded some of the biggest Sillicon Valley corporations and the culture they created. I must admit some doubts towards the word ‘bro’ , but wow, the book taught me a lot about how I don’t want to be and where I don’t want to work.
- Klont – if you read Dutch, get it! This novel brilliantly captures the phenomenon ‘datafication’ and how it endangers some of the basic concepts of free societies, as well as, unrelated, the phenomenon of ‘experts’ traveling the world to give talks
- Common sense, the Turing test and the quest for real AI – sometimes fairly technical and academic, but I loved the hype-free thinking about artifical intelligence and what to expect from it
- Killing Commendatore – if you’re into Murakami or want to start reading his work, this is great. It is a lot of pages, in two parts, but worthwile. I read the Dutch translation, it is available in many other languages, too.
For all the ‘big data’ and AI expertise that Amazon, which owns Goodreads, has, the app is still very bad at recommending new books. For me, it doesn’t go beyond what the most generic airport bookshops stock. The real human beings I follow on the platform brought much more reading inspiration.
Things I learned
Some random things I learned:
- I finally got my hands dirty in declarative client-side component frameworks. My framework of choice was Vue.JS. I learned concepts like routers, props down / events up, reactivity and lifecycle hooks, found they mostly just made sense and enjoyed working in this paradigm. I also found that within these concepts, I mostly wrote just JavaScript, good markup and sensible CSS. For instance, X is now ran inside a lifecycle hook, but X itself is just a method in JavaScript. Y is exposed as a component template, but Y itself is just plain old good
table
. - I learned in multiple projects this year how hard it can be to explain the concept of focus. It exists as a thing in the browser (the
document.activeElement
), but also as a thing in people’s thinking, not necessarily the same way. And then I’m not even talking about indicating focus yet. In my talk in Groningen I spent a number of slides trying to get it crystal clear. I like Laura Carvajals “You wouldn’t steal their cursor” and tried a streetlights metaphor (they are not pretty, but if they’re not there, you can’t see where you’re going at night) - I worked with WCAG 2.1 in real projects (testing for the newly added success criteria and talking about them in slides)
- I added CSPs to some sites (see also How I learned to stop worrying and love CSPs)
- I did more background reading to better understand the world we’re developing front-ends for (super meta), inspired by various colleagues, conference speakers and friends
- It’s totally workable to use Firefox Nightly as a main development browser, I had expected the occasional crash, because it is an early release channel, but had none. It is not as unstable as it advertises as. Also: tabs and sessions get recovered after updating (I knew this, but had not taken the risk before).
What I want to get better at next year:
- writing and presenting
- I want to try and build something with Rust
- get more people excited about having a personal website with a blog
- take more time off
With that, I wish all readers a fantastic 2019! If anyone has written year in review posts, I’d love to hear about them in the comments/webmentions, and read what you have done.
Originally posted as 2018 in review on Hidde's blog.
Making single color SVG icons work in dark mode
In a project I work on, we had a couple of buttons that consisted of just icons (with visually hidden help text). The QA engineer I worked with, found some of those did not show up in dark mode, which rendered the buttons unusable for users of that mode. Using inline SVGs with currentColor
fixed the issue.
What’s dark mode?
Dark mode (similar-ish to high contrast mode) is a setting on platforms, browsers or devices that inverts a user’s colour scheme: from dark elements on a light background to light elements on a dark background.
This setting improves the experience for all sorts of users. For instance, people who work in the evening, those spend a lot of time behind their screens and users with low vision. It also saves energy on some types of screens.
Dark mode is available on the latest macOS and Windows 10, but also in the form of a browser plugin (Dark Background and Light Text add-on for Firefox, Dark Night Mode Chrome extension). In this post I’ll refer to Dark Modes as one thing that generally works the same across different implementations. In reality, there can be inconsistencies, of course. They can be tricky to test remotely, as testing platforms like Browserstack don’t support dark modes for security reasons.
Some dark modes will flip colors on existing websites, turning your white colours black. In our project, we try to make our interface work with that kind of dark mode, as some of our users use these settings and it lets them have a much better experience. This is a relatively cheap accessibility win.
Inline SVGs to the rescue
Let’s assume our site has a light background with black icons. One way to include an SVG icon is to use an <img>
tag pointing to the SVG. Here’s an example of a chevron icon:
<img src="chevron-right.svg" alt="" aria-hidden="true" role="presentation" />
In Windows High Contrast, Dark Background and Light Text and Dark Night Mode, the icon simply did not show. I believe the reason is that Dark Modes generally parse style sheets only, they ignore the contents of markup (including SVG files). In those cases, they will not replace black with white.
If we could only set the color for these SVGs in our stylesheets! Well, currentColor
allows for that, and, it turns out, that actually works with Dark Modes:
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<polyline points="9 18 15 12 9 6" />
</svg>
For those new to currentColor
: it resolves to whatever the CSS color
is (as set or inherited) of the element the svg
is used in. So if a tool updates all color
s in the page, the SVGs automagically change colour too. It is also popular because it works great with states like hovers: for icons with text, icon colours will change whenever you change the text colour.
Declaring supported color schemes
After I posted this, Amelia Bellamy-Royds helpfully pointed me at a proposal for declaring color schemes preference. It is proposed to be a property you can set at root level (supported-color-schemes: light || dark
) or as a meta tag, so that browsers can be in the know before they start parsing CSS. The property basically lets you tell a browser that your CSS supports dark modes and will not break in them. Safari has experimental support for the property in Technology Preview 71.
The supported-color-schemes
property is meant to be used in conjunction with the prefers-color-scheme
media query.
Conclusion
So, if you use currentColor
for the only (or primary) colour in your SVG icons, they will work better in dark modes. I’ve not done much more research than this, but hope it helps others who try to make their icons work in dark mode. Feedback more than welcome!
Originally posted as Making single color SVG icons work in dark mode on Hidde's blog.
Scroll an element into the center of the viewport
Say your page displays a list of names and you want a certain person to be highlighted and scrolled into view. There’s a browser API for that: Element.scrollIntoView()
, which scrolls an element into view.
Element.scrollIntoView()
can take two types of elements: a boolean or an object. The object argument gives developers more control over how elements ‘in view’ are aligned, but has slightly less browser support. Let’s look at what we can do with both.
The boolean argument
Say, you have a couple of people in a list:
<ul>
<li id="alice">Alice Cruz</li>
<li id="daniel">Daniel Ho</li>
…
<li id="julie">Julie Howard</li>
…
</ul>
If you want Julie to be scrolled into view, find the relevant element, then call scrollIntoView()
:
const julie = document.getElementById('julie');
julie.scrollIntoView();
This scrolls the element into view. With a boolean argument, you can have some control over alignment. If you pass true
(default), the browser will scroll so that the element is at the top of your viewport or other scrollable element. With false
, it scrolls so the element is at the bottom of the viewport:
julie.scrollIntoView(true) // align top
julie.scrollIntoView(false) // align bottom
Note that the underlying terminology is not ‘top’ or ‘bottom‘, I’ll get into that in the next section.
For most use cases, this boolean argument may be all you need. It lets you choose if you want the element to align top or bottom.
This isn’t always ideal, sometimes you may have a sticky header, so scrollling an element to the top of the document would not actually get it into view. If something like that is the case in your project, the object argument comes in handy. It gives more control over alignment and allows for smooth scroll.
The object argument
In the latest version, you can also pass Element.scrollIntoView()
an object, which lets you set two things:
- should it scroll smoothly or jump instantly?
- how should the element align along the block and inline axes?
julie.scrollIntoView({
behavior: "smooth" | "auto";
block: "start" | "center" | "end" | "nearest";
inline: "start" | "center" | "end" | "nearest";
});
Smooth scroll
With the behavior
parameter, you can set whether scrolling should be instant, so the page just jumps to the element, or smoothly, over a number of seconds (to be decided by the browser).
Unsurprisingly, the "smooth"
value triggers smooth scroll. The "auto"
value triggers instant scroll, as long as the element’s computed value for the scroll-behavior
in CSS is not "smooth"
.
Alignment
Where I’ve been saying ‘top’ and ‘bottom’, I should have said ‘start‘ or ‘end’. They are the logical properties that you might recognise from other recent CSS specs like Grid Layout and flexbox.
As a quick reminder, the inline direction is the direction in which your text runs: it is the direction in which the words of this article are added. The block direction is the opposite of that, it is where block level elements are stacked, or where paragraphs of this text are added.
In a page with a vertical scrollbar, on the block axis, start
means top, end
means bottom. That’s the case on this page, for instance. But if your page uses vertical writing mode, you’d scroll horizontally, like in Hui-Jing Chen’s example of Chinese typography; in those cases, start
means right, end
means left on the block axis.
Fallbacks can be tricky
All browsers that understand element.scrollIntoView()
accept the boolean argument. But only some accept the object argument. The good thing is, browsers will fallback for you. The default for the boolean argument is true
, which sets the equivalent to block: start
. If you use the object argument to use block: center
or block: end
, browsers that don’t do the object argument, will regard the argument to be true
(because objects are truthy). So you’ll end up with block: start
in those browsers. That’s often great, except when it is the opposite of what you’re fallbacking for.
If your interface requires precisely control over scroll alignment, fallbacks can be tricky. As an alternative you can also roll your own alignment with element.scrollTo()
, as Jan Hoogeveen pointed out (thanks Jan!). If you end up going for that, I would recommend using coordinates as an argument, as the object argument does not work in some recent browsers, including Edge. See also window.scrollTo on MDN.
In the works: scroll snap
If you find scrollIntoView
interesting, you may be interested in Scroll Snap, too. This is new CSS, currently being worked on, which lets you define things like a padding for the scroll container. Rachel Andrew has written a guide on the basic concepts of Scroll Snap on MDN. Some of the properties are already available in some browsers.
Originally posted as Scroll an element into the center of the viewport on Hidde's blog.
Calm tech, platform abuse and reality
This week I attended the Digital Design Ethics conference in Amsterdam. I learned about calm technology, how platforms are abused, what our options are and how to try and prevent abuse earlier. My write-up of the day.
Calm technology
Amber Case started off. She explored the kind of technology she wants to see more of: calm technology. In this age, she explained, attention is more scarce than technology. So we ought to be critical of how we want our tech to interrupt us. Does it really need to talk? Often quieter signals are just as effective. Our industry replicates voice assistants we saw in films, instead of informing solutions by social norms and human needs. Humanity is important in general, Amber explained. For instance, if we make smart machines, let’s consider how to include human intelligence to contribute to that smartness. She mentioned an algorithm that helps find cancer cures, and complements raw data with input from PhD students, instead of figuring out everything alone. Or if we make a smart fridge that refuses to operate if the wrong human stands in front of it, let’s consider they may require food for their diabetic brother. Let’s take reality into account, said Amber.
Slightly shorter version of Amber’s talk: Calm Technology on YouTube
Amber Case on the dystopian kitchen of the future
Indifferent platform executives
The theme of reality continued in talk two. I’m not sure if I’ve ever seen a web conference speaker so furious on stage. Mike Monteiro talked about Mark Zuckerberg of Facebook and Jack Dorsey and Biz Stone of Twitter. The thing is: people use their platforms to spread fake news and declare nuclear war (the US president did). In response to the latter, Twitter did not kick the president off their platform and hid behind corporate speak. Mike finds this problematic, because there is insincerity in pretending to fairly apply rules, if instead, you bend them to keep profitable accounts online. It doesn’t take much cynicism to conclude these decisions are about money. Monteiro backed this up with an analyst’s valuation of what removing Trump from Twitter would cost the company: 2 billion dollars, or a fifth of its value.
We should not look away. Photo: Peter van Grieken
It isn’t just the executives, Mike explained: everyone who works at a company like Twitter should ask themselves why they are still there. Paying a mortgage, he said, is not enough. He warned us: if you work as a designer or developer at a company that has terrible effects on the world, be mindful of not “slowly moving your ethical goalposts”. I cannot help but think there’s quite some space between moving ethical goalposts and completely quitting your job. Mike mentioned the Google walkout: they try to move stuff from the inside.
If you’d like to watch Mike’s talk, see How to Build an Atomic Bomb - Mike Monteiro - btconfDUS2018. Warning: contains a lot of swearing and Holocaust references.
Design as applied ethics
According to Cennydd Bowles, we should regard design as applied ethics. In his recent book Future Ethics, he explains that in detail (go read, it is great). At his Amsterdam talk, he gave a fantastic overview of his book’s themes. Cennydd talked about when ethics comes into play: always. When you invent a thing, it’s extremely likely it can be used for bad things. So, worrying about avoiding bad consequences should be intrinsic to our design processes.
Cennydd’s talk had good advice for mitigating the issue that Mike mentioned earlier: if you create a platforms that is abused, how should you respond? Cennydd went into concrete actions that help take abuse into account in the design stage.
One of the actions Cennydd mentioned: add people who would potentially suffer from your product to the list of stakeholders. Another one: the persona non grata: design for the persona of someone with bad intentions as a strategy to make your product less bad. And he talked about Steve Krug’s well known ‘don’t make me think’: if we want to give users agency, Cennydd explained, sometimes the opposite, making them think, is preferred. For example, if you give people privacy settings, a ‘consent to all the things’ button requires less thinking, but a more fine-grained control yields more privacy and shows you view people as people.
The veil of ignorance
Both Mike and Cennydd mentioned the veil of ignorance, a thought experiment by the political philosopher John Rawls. I used this concept in a talk I gave a couple of weeks ago (Trolleys, veils and prisoners), please allow me to quickly reiterate that here. The idea is: imagine a group of people that you ask to come up with all the rules that govern our world. But there’s one trick: you strip them away from their position in society. Whether they were Uber’s CEO or an Uber driver, from a rich or a poor family, haves or have-nots… they are now none of those things. They wear a ‘veil of ignorance’. They are in what Rawls called the ‘original position’. After they made up the rules, they’re randomly distributed into positions in society. If they are put in the ‘original position’, the theory goes, these people will distribute rules fairly. This is simply because they don’t know how they’ll get them applied to themselves. It’s a powerful concept, and I believe something that applies brilliantly to tech. In quite practical terms, it means if you build or design something, would you want to be the person using that product?
If I had to summarise the event in four words, they would be ‘take reality into account’. Amber Case said we should do so in the opening talk. Mike Monteiro said we should not let ourselves get away with ignoring reality. Cennydd Bowles offered some great tips for getting bringing reality into our design process. Hearing these three useful perspectives on bringing ethical thinking to our design processes, I had great day at the Digital Design Ethics conference.
Originally posted as Calm tech, platform abuse and reality on Hidde's blog.
Up to speed with web performance
On Thursday and Friday I learned all sorts of things about making sites faster at the performance.now() conference in Amsterdam. I frantically took notes at each talk, so here’s my summary of the event.
Performance has always been one of my main interests in web development: if you want a good user experience, speed is essential. The performance.now() conference was two days, with eight talks on each day. Some had lots of theory, others were case studies. The balance between different types of content was excellent. I thoroughly enjoyed learning more about resource hints, HTTP/2, rendering performance of UI and fonts, the web itself and how performance works in large organisations.
See also: the conference videos on YouTube.
HTTP/2 was a recurring theme
Day 1
Steve Souders - Making JavaScript fast
The conference kicked off with the grand… eh godfather of web performance: Steve Souders. He talked about the issues that stand in the way of everything (the ‘long poles in the tent’), based on data from the HTTPArchive. The longest pole: JavaScript fatigue. Scripts are not just bad news for performance because of download time, but also because parsing them costs CPU time on our user’s devices. Steve recommended reducing it (check code coverage, budget 3rd parties), and for what is left: load it async (or better: defer), use <link rel=preload as=script>
(or better: as a header) and double-check your assets are actually compressed.
Harry Roberts - Third-party scripts
Harry Roberts discussed third party scripts in four stages: understanding what the problem is, auditing for it, talking to internal teams and vendors and reducing the problem where possible (Harry’s slides). Third party scripts can affect user’s security, they can slow things down (or even be a single point of failure). For auditing, Harry mentioned Request Map, a tool that takes a Web Performance Test as input and creates a map. With the data in hand, he explained, you can go talk to the vendor or the scripts (note: they might lie). Or you can go to the department responsible for the scripts and have a polite meeting with them (‘ask questions, don’t demand immediate removal’). This sparked some discussion at the drinks afterwards: polite is probably good, but shouldn’t developers really be quite strong about reducing tracking? To mitigate third party performance issues, Harry recommended self-hosting, async
loading where possible and preconnect
to ‘warm up’ the connections to origins that are most important and that you’ll need frequently.
Anna Migas - Debugging UI perf issues
Anna Migas showed us how to impove what she calls ‘perceived load performance’ (Anna’s slides). If we want smooth interactions, we have to do our calculation work between frames. This is because we should ensure our users get not only 60fps, but possibly also 120fps, it’s a thing on iPad Pro and Razer devices. She exposed step by step how a browser builds a frame and shared great tricks for avoiding jank (offload tasks outside the main thread) and diagnosing its cause in Dev Tools (Performance, Rendering and Layering tabs). She also explained issues with certain interaction patterns, like animations (janky if wrong properties or too many), parallax scrolling (‘paint storms’), fixed elements (lots of repainting) and lazy loading images (content jumps). A great trick for improving performance of fixed or sticky elements: try to get browsers to load them in their own layer (can be forced by using will-change
or transform: translate3D(0,0,0)
). She did warn here: be mindful that more layers consume more memory, use them wisely.
Adrian Holovaty – Geeking out with performance tweaks
Adrian created Soundslice, which is a cleverly built web interface for sheet music. Because it displays sheet music, it displays complex combinations of notes. Hard to get performant, one might think. Soundslice works with a canvas
that can (has to) do redraw very often. It has clever things like that it will highlight the currently played note. You can get kind of stuff super performant with very careful coding, Adrian showed. You do just the things required, not too often, etc. Being the co-creator of a famous library himself, Django for Python, he surprised some by saying he recommends not to use frameworks, as they are often full of things your app doesn’t need. Specifically this is true for front-end frameworks, as their redundant code gets shipped to and parsed by users. Food for thought, I heard many say in the break after. So, no big library, but a small set of 8 utility functions in vanilla JavaScript. Adrian also showed how requestAnimationFrame
helped to not redraw too often. Google Dev Tools and Google’s Closure Compiler helped him ship better code. Other cool tricks: one global tmpList
that gets reused every time a function requires a temporary array, singleton functions where possible to allow for a cache of fractions to avoid memory overuse, caches for expensive calculations and bitfields to use less bytes for saving meta information of notes (one byte per boolean instead of the default 8). Mind. Blown.
Adrian shows sheet music
Zach Leatherman - Fonts
Those who had hoped to walk out of Zach Leatherman’s talk with the one, ultimate, bullet-proof solution to loading fonts fast, were out of luck (Zach’s slides). There is just too much to think about. Most solutions will be a trade-off in some way. But there’s lots to tweak. Zach walked us through improving font loading in a default WordPress theme. He showed lots of tools that can help us deal with what he called the biggest enemies of font loading: invisible text (because font not yet loaded) and moving text (because of fallback font getting replaced by the real thing). Reflowing content is annoying, so Zach proposed a new performance metric: ‘web font reflow count’. Good web font implementations try and keep this number low, while no web font implementations have it at zero. Waiting endlessly for final versions of all fonts is also not ideal. Reflow could also be avoided if fallback fonts look a lot like the webfonts, or if bold webfonts are fallbacked by synthetically bolded regular weights (which, Zach showed, Safari can do). He also talked about how to use preconnect
(in some cases), self hosting, font-display
(can have sensible results without JS), the Font Loading API (full control over what and when) and subsetting, with clear and helpful examples. I loved it and will review this site’s web font choices.
Natasha Rooney - Protocols
As someone who is just an ordinary front-end developer, I always find people who understand all about networking a bit intimidating. So was Natasha Rooney, even though she said ‘protocols are easy’. She works on protocols and networking standards at the W3C and IETF. In one of her first slides, Natasha showed the absolute boundaries of network speeds on a map. They are dictated by physics, ‘you can’t beat the speed of light’. To optimise that part of the web stack, the advice is to serve content from servers physically closer to your users (think CDNs). With awesome supermarket metaphors, she explained pipelining. She then went into the details of SPDY, Google’s protocol that later was the basis for HTTP/2, and QUIC, again a Google invention. QUIC may help solve head of line blocking issues by reducing latency. It could end up becoming standardised as HTTP/3. Both SPDY and QUIC run on existing protocols (TCP and UDP respectively), because middle boxes often disallow other protocols.
Andrew Betts – Fun with headers
When Andrew Betts worked in the Technical Architecture Group (TAG), he had to review proposals for new HTTP Headers, amongst, presumably, lots of other tasks. For this talk, he looked into the HTTPArchive to show us some headers. Those we should want and those we should not want. The ones to keep were restrictive headers like Content-Security-Policy
, Strict-Transport-Security
and Referrer-Policy
(all for security) and permissive ones like Access-Control
and client hints (full overview in Koen Kivit’s tweet). Andrew also looked a bit at the future. Particularly Feature-Policy
looked pretty interesting and the idea of setting some of these headers in a JSON file served from a well-known endpoint.
Tammy Everts - What’s the best UX metric?
Tammy Everts shared with us what she thinks works best as a performance metric focused on user experience (Tammy’s slides). She started by sharing some history of performance metrics and what their problems are, then went into current metrics that aid UX. More modern metrics often start with ‘First’ (First Paint, First Interactive, etc), and SpeedCurve introduced metrics for important things on the page (like ‘largest background image rendered’). Tammy also said you can define your own custom metrics. Some companies do, like Twitter (‘Time to First Tweet’). Collecting measurements is one thing, but what to do with them? Tammy talked a bit about per page performance budgets, based on some of the metrics she showed before.
Day 2
Tim Kadlec - The long tail of performance
Tim Kadlec’s talk opened day two and it was about ‘the long tail’. That isn’t always the same people: it could be you on a flight, you who forgot to charge or you visiting a rural area. In other words: the real world. Tim showed how he worked with the MDN team to reduce loading times. A large part of page size was fonts. Choosing a system font instead of Mozilla’s brand sans-serif and subsetting their slab serif helped heaps. Talking more generally, Tim explained he had, in years and years of audits, never seen a case where the site couldn’t have improved making the core user tasks faster. There’s always assets, old code or other stuff that could be removed. And we can choose to do that, Tim explained, we can be proactive and provide a resilient and solid experience. Truly inspiring opening words. Practically, he recommended us to test on older devices and slower connections.
Speakers quoting speakers: Tim Kadlec refers back to what Steve Souders said the day before
Yoav Weiss - Resource Loading
Yoav Weiss talked about what makes resource loading slow, how we can solve it today and how it will be better in the future. The problems: establishing a connection has many roundtrips, servers take time to process requests, starts are slower than necessary, browsers sometimes have idle time while figuring out which resources to load, when they’re loading they go in turns and then we sometimes load more than necessary (bloat). HTTP/2 helps with a lot, not everything. In the future, we’ll be able to use the wait time by using HTTP/2 Push, we should unshard domains (as it is an antipattern in HTTP/2) and take advantage of preload
and preconnect
headers (responsibly; adding it to everything messes with prioritisation and make things worse) and we can turn on BBR (See also: Optimizing HTTP/2 prioritization with BBR, via Tammy Everts).
Kornel Lesiński - Optimising images
Did you know JPEG images don’t contain pixels? Kornel Lesiński explained they have layers of abstract patterns instead. Together they form the image. Some parts contain details and others don’t, and by moving all non-detail data to the beginning of the file, you get this effect of low res slowly becoming hi-res, they load ‘progressively’. Progressive JPEGs have one issue: if you have multiple, they load one by one. In other words, as a group they’re not progressive. This can be mitigated by configuring nginx to send just the first 15%, then wait so that the network can do other things, then send the rest of the file. The doesn’t work on CDNs, they’ll serve static from cache, unless you use Edge Workers. Kornel also showed different future image compression techniques, the best of which just exist in browsers as video codecs. The trick to that? Load hero images in a <video>
and you’re good to go, Kornel explained. Clever. And probably not for production.
Katie Sylor-Miller - Performance archeology
Katie Sylor-Miller (Katie’s slides) had this fantastic approach of marrying archeology (her background) with web performance, and with… Indiana Jones. The talk was, at the same time, a case study of Katie’s work at Etsy. The team’s hypothesis was that listing page performance improvements would lead to more conversion, so they surveyed, found the culprits and acted on them. It involved manual JS removals at first, but that was later replaced by a very nifty looking (in-house) solution called ‘Vimes’. It automatically finds which parts of the JS are never or rarely used. To avoid having to do this, Katie recommended to ‘architect for deletion’. Interesting findings from the research were that before/after difference got much larger on slower connection speed and that, yes, performance definitely affected conversion.
Jason Grigsby - Progressive Web Apps challenges
It’s been a couple of years since the idea of Progressive Web Apps was introduced. Jason Grigsby talked about some challenges in 2018 PWA land (Jason’s slides). One such challenges is the definition, it would make sense to have different definitions for developers (like Jeremy’s) and marketeers (Alex and Francis’ original definition, or Google’s, that has gone through a couple of iterations). If anything, the acronym is not for developers. There’s plenty of FUD around Progressive Web Apps, Jason explained, and they can do more than we think. Geolocation, Web Payments, an app shell architecture and offline support can all be part of a good PWA experience. Hidden challenges include appearing to use more storage than expected (security measures in browsers dealing with opaque responses) and designing for the intricacies of a seamless offline experience.
Scott Jehl - Move fast and don’t break things
While most speakers talked about how to make existing sites faster, Scott Jehl recommended us all to not make them slow in the first place. His technique of choice for this: progressive enhancement. It as effective many years ago and it is effective still, Scott explained. For performance, but also for accessibiliy and SEO. He discussed various techniques that fit well within this mindset: HTTP/2 Server Push (Filament already use it in PROD), inlining CSS (or the most critical subset of it if there’s a lot), the lazyload
attribute that is in experimental Chrome (PR for lazyload against the HTML specification) and Service Workers on the CDN level so that you can A/B test without bothering users (if you do it on the client, consider this new metric: second meaningful content). Great conclusion: it is easier to make a fast website than to keep a website fast.
Michelle Vu - Performance at Pinterest
Michelle Vu runs the performance team at Pinterest. Her fantastic talk gave us insight in how they got and keep their site fast. The results were very positive: 30% faster got them 10% more sign-ups. Michelle explained that what worked for them is to pick a key metric, which in Pinterest’s case was a custom metric. She said it is helpful to tie performance metrics into business metrics. When measuring, it is helpful to look both at synthetic data (test runs) and RUM data (real users). Michelle showed they each serve a need: synthetic results are consistent and you can run the tests before deploying (e.g. upon code merge) and RUM data shows impact on real users. Michelle also showed a bit of their performance tooling: regressions are measured and there’s performance regression pager duty. So cool! The most important lesson I learned from this talk is that education is very important. Pinterest do this in their pattern library and document things like the experiments (how they were ran, results, etc) and the details of optimisations. Besides documentation, communication and in-person training was just as important to educate others.
Paul Irish - Closing keynote
Closing of the last day of the conference was Paul Irish. He talked about the state of metrics, specifically two kinds: visual metrics and interactivity metrics. Visual metrics are things like First Meaningful Paint, Visual Completion, Layout Stability (a.k.a. ‘layout jank’) and something Paul called Last Painted Hero, a measurement for the last paint of most important content (see also: Rendering Metrics by Steve Souders). Interactivity metrics are things like First CPU Idle and First Input Delay. Paul also showed how to measure these metrics with real users using a PerformanceObserver. The flow he recommends for this is to write code, test it synthetically (‘in the lab’), ship it, then validate it with real users (‘RUM’).
Originally posted as Up to speed with web performance on Hidde's blog.