Layout is where the browser figures out the geometric information for elements: their size and location in the page. Each element will have explicit or implicit sizing information based on the CSS that was used, the contents of the element, or a parent element. The process is called Layout in Chrome, Opera, Safari, and Internet Explorer. In Firefox it’s called Reflow, but effectively the process is the same.
Similarly to style calculations, the immediate concerns for layout cost are:
- The number of elements that require layout.
- The complexity of those layouts.
- Layout is normally scoped to the whole document.
- The number of DOM elements will affect performance; you should avoid triggering layout wherever possible.
- Assess layout model performance; new Flexbox is typically faster than older Flexbox or float-based layout models.
- Avoid forced synchronous layouts and layout thrashing; read style values then make style changes.
See the source link for details and solutions.
Generally, all APIs that synchronously provide layout metrics will trigger forced reflow / layout. Read on for additional cases and details.
Weekly Timber is a client of mine that provides logging services in central Wisconsin. For them, a fast website is vital. Their business is located in Waushara County, and like many rural stretches in the United States, network quality and reliability isn’t great.
Wisconsin has farmland for days, but it also has plenty of forests. When you need a company that cuts logs, Google is probably your first stop. How fast a given logging company’s website is might be enough to get you looking elsewhere if you’re left waiting too long on a crappy network connection.
I initially didn’t believe a Service Worker was necessary for Weekly Timber’s website. After all, if things were plenty fast to start with, why complicate things? On the other hand, knowing that my client services not just Waushara County, but much of central Wisconsin, even a barebones Service Worker could be the kind of progressive enhancement that adds resilience in the places it might be needed most.
The first Service Worker I wrote for my client’s website—which I’ll refer to henceforth as the “standard” Service Worker—used three well-documented caching strategies:
- Serve static assets out of
CacheStorageif available. If a static asset isn’t in
CacheStorage, retrieve it from the network, then cache it for future visits.
- For HTML assets, hit the network first and place the HTML response into
CacheStorage. If the network is unavailable the next time the visitor arrives, serve the cached markup from
These are neither new nor special strategies, but they provide two benefits:
- Offline capability, which is handy when network conditions are spotty.
- A performance boost for loading static assets.
A better, faster Service Worker
The web loves itself some “innovation,” which is a word we equally love to throw around. To me, true innovation isn’t when we create new frameworks or patterns solely for the benefit of developers, but whether those inventions benefit people who end up using whatever it is we slap up on the web. The priority of constituencies is a thing we ought to respect. Users above all else, always.
There are certainly other challenges, but it’ll be up to you to weigh the user-facing benefits versus the development costs. In my opinion, this approach has broad applicability in applications such as blogs, marketing websites, news websites, ecommerce, and other typical use cases.
All in all, though, it’s akin to the performance improvements and efficiency gains that you’d get from an SPA. Only the difference is that you’re not replacing time-tested navigation mechanisms and grappling with all the messiness that entails, but enhancing them. That’s the part I think is really important to consider in a world where client-side routing is all the rage.
Before all of this, I’d more or less equated the Same-Origin Policy with CORS errors, and all of the frustration that they’ve caused me over the years. Now, though, the Same-Origin Policy wasn’t just standing between me and handling a
fetch, it was holding up a major work initiative. And I had to explain the situation to bosses who knew even less about security and privacy on the web than I did. Time to learn!
Here’s what I learned:
- The Same-Origin Policy isn’t a single, simple, rule. And it certainly isn’t == CORS errors.
- What it is, is a philosophy which has evolved over time, and has been inconsistently implemented across the web platform.
- In general, what it says is: the fundamental security and privacy boundary of the web is origins. Do you share an origin with something else on the web? You can interact with it however you like. If not, though, you might have to jump through some hoops.
- Why “might?” Well, a lot of cross-origin interactions are allowed, by default! Generally, when you’re making a website, you can write across origins (by sending
- Here’s the thing that blew my mind the most, once I finally understood it: cross-origin reads are forbidden by default because, as end-users, we all see different world-wide webs, and a website shouldn’t be able to see the rest of the web through its visitors’ eyes. Individuals’ varied local browsing contexts – including, but not limited to, cookies — mean that when I go to, say, gmail.com, I’m going to see something different than you, when you enter that same URL into your address bar and hit “return.” If other websites could fire off requests to Gmail from my browser, with my cookies, and read the results, well – that would be very, very bad!
So by default: you can do lots of things with cross-origin resources. But preventing cross-origin reads is kind of the whole ballgame. Those defaults are more-or-less what people are talking about when they talk about the “Same-Origin Policy.”
This is a fascinating deep dive by the people at Discord on their development of a focus ring component and all the problems they had to overcome:
Browsers implement default focus rings that apply to all elements, but the ability to style these is (currently) very limited. These rings, while they have recently improved greatly in Chrome and Edge, are also not very pleasant when integrated with the rest of Discord’s design, and other browsers like Firefox are almost entirely invisible in most cases due to the thinness and low contrast of their styles.
As such, we want to implement a custom focus ring style. At a glance, this seems relatively simple, but when dealing with the variety of use cases Discord has for these rings, the list of requirements quickly grows, and the options for implementations shrink.
Ideally, we want to match the browser’s focus ring behavior exactly. Within Discord, this means that a comprehensive focus ring implementation needs to:
- Perfectly map to the element that has focus (with exceptions listed below).
- Follow elements as they move when containers scroll.
- Follow elements as they animate and transition within the document.
- Not be clipped off when the focused element is bounded by
overflow: hiddenor other bounding techniques.
- Respect occlusion of overlapping elements, but not be occluded by an element’s own z-index.
Additionally, to be able to implement pleasant and overall better focus styles for various elements in the app, we have additional requirements to be able to:
- Apply the focus ring on a different element than the actual focused element
- Provide positional offsets to adjust ring placement around the element.
- Adjust ring styles to match the look and feel of the surrounding context (could include changing border radius, color, shape, and more)
- Specify a style for when focus is within an element, for example to indicate the bounds of a widget.
See the source link for the rest.
Little #a11y tip for you: If you are using a status message bar, you’ll want it to be a live region. But it should aslo be discoverable in case the messages are missed when they’re announced. Good case for an
<aside>:<aside aria-live="polite" aria-label="Status"> ... </aside>