116 matches found
View transitions: Handling aspect ratio changes
This post assumes some knowledge of view transitions. If you're looking for a from-scratch intro to the feature, see this article. When folks ask me for help with view transition animations that "don't quite look right", it's usually because the content changes aspect ratio. Here's how to handle...
Getting the correct HTML codecs parameter for an AV1 video
This post is mostly for my own reference, but I couldn't find a good guide elsewhere, so here we go! I wanted to embed a screencast in a web page, and I wanted it to be as efficient as possible. To achieve this, I created two version of the video, and embedded it like this: The MP4 version uses t...
Service workers at TPAC
Last month we had a service worker meeting at the W3C TPAC conference in Fukuoka. For the first time in a few years, we focused on potential new features and behaviours. Here's a summary: Resurrection finally killed reg.unregister; If you unregister a service worker registration, it's removed fro...
A declarative router for service workers
I'm looking for feedback on this API. It isn't yet supported in any standard or browser. In the very early days of service workers while they were still named "navigation controllers" we had the idea of a declarative router. This provided a high-level API to define the behaviour of particular...
await vs return vs return await
When writing async functions, there are differences between await vs return vs return await, and picking the right one is important. Let's start with this async function: async function waitAndMaybeReject // Wait one second await new Promiser = setTimeoutr, 1000; // Toss a coin const isHeads =...
Using ServiceWorker in Chrome today
The implementation for ServiceWorker has been landing in Chrome Canary over the past few months, and there's now enough of it to do some cool shit! Unnecessary representation of "cool shit" What is ServiceWorker? ServiceWorker is a background worker, it gives us a JavaScript context to add featur...
Drawing a star with DOMMatrix
I recently recorded an episode of HTTP 203 on DOMPoint and DOMMatrix. If you'd rather watch the video version, here it is, but come back here for some bonus details on a silly mistake I made, which I almost got away with. DOMMatrix lets you apply transformations to DOMPoints. I find these APIs...
ECMAScript modules in browsers
ES modules are now available in browsers! They're in… Safari 10.1. Chrome 61. Firefox 60. Edge 16. import addTextToBody from './utils.mjs'; addTextToBody'Modules are pretty cool.'; // utils.mjs export function addTextToBodytext const div = document.createElement'div'; div.textContent = text;...
Combining fonts
&&&& I love the font Just Another Hand, I use it a lot in diagrams during my talks: Here it is! Yay! The thing is, I don't like the positioning of the hyphen & equals glyphs… Cache-Control: max-age=3600 They look awkwardly positioned – they sit too high. Thankfully CSS lets you merge fonts...
SVG & media queries
One of the great things about SVG is you can use media queries to add responsiveness to images: circle fill: green; @media min-width: 100px circle fill: blue; But when should the circle be blue? The specs say min-width should match on the width of the viewport, but… Which viewport? …as above… Whi...
Control CSS loading with custom properties
Last week I wrote about a simple method to load CSS progressively, and on the very same day some scientists taught gravity how to wave. Coincidence? Yes. The pattern in the previous post covers the 90% case of multi-stage CSS loading, and it's really simple to understand. But would you like to he...
2016 - the year of web streams
Yeah, ok, it's a touch bold to talk about something being the thing of the year as early as January, but the potential of the web streams API has gotten me all excited. TL;DR: Streams can be used to do fun things like turn clouds to butts, transcode MPEG to GIF, but most importantly, they can be...
Don't use flexbox for overall page layout
When I was building this blog I tried to use flexbox for the overall page layout because I wanted to look cool and modern in front of my peers. However, like all of my other attempts to look cool and modern, it didn't really work. Why? Well, take my hand and follow me into the next section… Updat...
The Goldilocks customizable select height
I recently gave a talk on customizable as in fully-stylable , and as I was building demos I realised there's a sizing 'pattern' that's almost always the-one-you-want, but it took me a long time to figure out how to do it in CSS. Well, I say I figured it out. I actually failed, and asked a bunch o...
Who has the fastest website in F1?
I was trying to make my predictions for the new Formula One season by studying the aerodynamics of the cars, their cornering speeds, their ability to run with different amounts of fuel. Then it hit me: I have no idea what I'm doing. So, I'm going to make my predictions the only way I know how: By...
await vs return vs return await
When writing async functions, there are differences between await vs return vs return await, and picking the right one is important. Let's start with this async function: async function waitAndMaybeReject // Wait one second await new Promiser = setTimeoutr, 1000; // Toss a coin const isHeads =...
HTTP/2 push is tougher than I thought
"HTTP/2 push will solve that" is something I've heard a lot when it comes to page load performance problems, but I didn't know much about it, so I decided to dig in. HTTP/2 push is more complicated and low-level than I initially thought, but what really caught me off-guard is how inconsistent it ...
The performance benefits of rel=noopener
If you have links to another origin, you should use rel="noopener", especially if they open in a new tab/window. Example site Without this, the new page can access your window object via window.opener. Thankfully the origin security model of the web prevents it reading your page, but no-thankfull...
The future of loading CSS
Chrome is intending to change the behaviour of , which will be noticeable when it appears within . The impact and benefits of this aren't clear from the blink-dev post, so I wanted to go into detail here. Update: This is now in Chrome Canary. The current state of loading CSS …content… CSS blocks...
Minimising font downloads
Optimising fonts is pretty difficult for larger sites. There's an easy solution, although only some browsers support it. Translations Français Fonts can be big Really big. They can be anywhere from 70k to many megabytes compressed of course, because why wouldn't you?. You want bold? Well, you jus...
Animated line drawing in SVG
There's a demo you're missing here because JavaScript or inline SVG isn't available. I like using diagrams as a way of showing information flow or browser behaviour, but large diagrams can be daunting at first glance. When I gave talks about the Application Cache and rendering performance I start...
Importing vs fetching JSON
This year, JSON module imports became baseline 'newly available', meaning they're implemented across browser engines. import data from './data.json' with type: 'json' ; // And… const default: data = await import'./data.json', with: type: 'json' , ; I'm glad JavaScript has this feature, but I can'...
The gotcha of unhandled promise rejections
Let's say you wanted to display a bunch of chapters on the page, and for whatever reason, the API only gives you a chapter at a time. You could do this: async function showChapterschapterURLs for const url of chapterURLs const response = await fetchurl; const chapterData = await response.json;...
Getting the correct HTML codecs parameter for an AV1 video
This post is mostly for my own reference, but I couldn't find a good guide elsewhere, so here we go! I wanted to embed a screencast in a web page, and I wanted it to be as efficient as possible. To achieve this, I created two version of the video, and embedded it like this: The MP4 version uses t...
Tasks, microtasks, queues and schedules
When I told my colleague Matt Gaunt I was thinking of writing a piece on microtask queueing and execution within the browser's event loop, he said "I'll be honest with you Jake, I'm not going to read that". Well, I've written it anyway, so we're all going to sit here and enjoy it, ok? Actually, i...
Improving the URL bar
iOS has hidden the pathname of URLs for some time now, but recently Chrome Canary introduced something similar behind a flag. I'm not involved in the development of Chrome experiment at all, but I've got more than 140 characters worth of opinion on it… We have a real security problem I recently...
visibility: visible undoes visibility: hidden
If you set an element to display: none the browser ignores all of its children, if a child sets itself to display: block it will remain hidden. This isn't true of visibility. Serious? Serious. html.show-only-the-button visibility: hidden; html.show-only-the-button .the-button visibility: visible;...
Progressive enhancement is faster
Progressive enhancement has become a bit of a hot topic recently, most recently with Tom Dale conclusively showing it to be a futile act, but only by misrepresenting what progressive enhancement is and what its benefits are. You shouldn't cater to those who have deliberately disabled JavaScript...
Video with alpha transparency on the web
I've been helping some teams at Shopify improve page load performance, and the issue of 'videos with an alpha channel' kept coming up, where videos of UI mocks needed to be composited on top of inconsistent backgrounds, such as larger CSS backgrounds. Often a good solution here is to create the...
Garbage collection and closures
Me, Surma, and Jason were hacking on a thing, and discovered that garbage collection within a function doesn't quite work how we expected. function demo const bigArrayBuffer = new ArrayBuffer100000000; const id = setTimeout = console.logbigArrayBuffer.byteLength; , 1000; return = clearTimeoutid;...
Garbage collection and closures
Me, Surma, and Jason were hacking on a thing, and discovered that garbage collection within a function doesn't quite work how we expected. function demo const bigArrayBuffer = new ArrayBuffer100000000; const id = setTimeout = console.logbigArrayBuffer.byteLength; , 1000; return = clearTimeoutid;...
View transitions: Handling aspect ratio changes
This post assumes some knowledge of view transitions. If you're looking for a from-scratch intro to the feature, see this article. When folks ask me for help with view transition animations that "don't quite look right", it's usually because the content changes aspect ratio. Here's how to handle...
Arrays, symbols, and realms
On Twitter, Allen Wirfs-Brock asked folks if they knew what Array.isArrayobj did, and the results suggested… no they don't. For what it's worth, I also got the answer wrong. Type-checking arrays function fooobj // … Let's say we wanted to do something specific if obj is an array. JSON.stringify i...
Caching best practices & max-age gotchas
Getting caching right yields huge performance benefits, saves bandwidth, and reduces server costs, but many sites half-arse their caching, creating race conditions resulting in interdependent resources getting out of sync. The vast majority of best-practice caching falls into one of two patterns:...
The anatomy of responsive images
I just had my responsive images epiphany and I'm writing it all down before I forget everything. This is what I know… Fixed size, varying density If your image is a fixed size in pixels, but you want to cater for screens of different density, here's the solution: img alt="A cat" width="320"...
Launching ServiceWorker without breaking the web
Update: Thanks to everyone who read and commented, you influenced the direction of the API. We're going for B, the path-based method, but allowing a header to relax these rules so you can put your worker script wherever you want. Many thanks! With ServiceWorkers you can control requests to any pa...
Service Worker - first draft published
The first draft of the service worker spec was published today! It's been a collaborative effort between Google, Samsung, Mozilla and others, and implementations for Chrome and Firefox are being actively developed. Anyone interesting in the web competing with native apps should be excited by this...
ES7 async functions
They're brilliant. They're brilliant and I want laws changed so I can marry them. Update: This feature is now shipping in browsers. I've written a more up-to-date and in-depth guide. Async with promises In the HTML5Rocks article on promises, the final example show how you'd load some JSON data fo...
How should <selectedoption> work?
We're finally getting a way to fully style & customise elements! But there's a detail I'd like everyone's opinion on. Update: Your feedback was heard, and folks have agreed to change the behaviour here. See the update below. A brief intro to customisable If you want to hear about it in depth, I...
What happens when packages go bad?
I built spritecow.com back in 2011, and I no longer actively maintain it. A few months ago, a user berated me for using a crypto currency miner on the site without their informed consent. And sure enough, the site's JS had a small addition that loaded the mining JS, and sent the result somewhere...
Async iterators and generators
Streaming fetches are supported in Chrome, Edge, and Safari, and they look a little like this: async function getResponseSizeurl const response = await fetchurl; const reader = response.body.getReader; let total = 0; while true const done, value = await reader.read; if done return total; total +=...
Fun hacks for faster content
A few weeks ago I was at Heathrow airport getting a bit of work done before a flight, and I noticed something odd about the performance of GitHub: It was quicker to open links in a new window than simply click them. Here's a video I took at the time: GitHub link click vs new tab Here I click a...
Service worker meeting notes
On July 28th-29th we met up in the Mozilla offices in Toronto to discuss the core service worker spec. I'll try and cover the headlines here. Before I get stuck in to the meaty bits of the meeting, our intent here is to do what's best for developers and the future of the web, so if you disagree...
Having fun with
Did you know that this works in every browser? Look, here's one: An image You might think it's leaking from SVG, but SVG images don't use src, they use xlink:href. Let's all take a moment to laugh at xlink. Done? Ok… In the first age of the web, some people accidentally typed instead of . Browser...
Video with alpha transparency on the web
I've been helping some teams at Shopify improve page load performance, and the issue of 'videos with an alpha channel' kept coming up, where videos of UI mocks needed to be composited on top of inconsistent backgrounds, such as larger CSS backgrounds. Often a good solution here is to create the...
HTML attributes vs DOM properties
Attributes and properties are fundamentally different things. You can have an attribute and property of the same name set to different values. For example: … const div = document.querySelector'divfoo=bar'; console.logdiv.getAttribute'foo'; // 'bar' console.logdiv.foo; // undefined div.foo = 'hell...
Service workers and base URIs
Previously when we've run into a contentious service worker design issue, we've asked web developers what they think. This has worked out pretty well in the past, with developer feedback directly informing spec changes. It's also great because we can blame y'all if you pick the wrong thing. Well,...
What happens when you read a response?
There's a bit of disagreement over the behaviour of requests and responses in the fetch API, curious to know what you think… Setting the scene The new fetch API gives the web proper Request and Response primitives. fetch'/whatever'.thenfunctionresponse return response.body.asJSON; .thenfunctionda...
Progressive enhancement is still important
About 5 years ago it felt like the progressive enhancement battle had been won, but after watching the reactions to Nicholas Zakas' "Enough with the JavaScript already" it seems all the old arguments are back with reinforcements. Well, I'm wearing my angry-pants and I'm ready for a jog down ranty...
I've only gone and done a blog
I've been promising myself I'd start a blog for about 100 years now, but it's finally here! I decided to build everything from scratch to force myself to learn Vagrant, Puppet and other general sysops stuff that was on my "to explore" list. This was dumb in terms of how long it took me to get...