Preload, prefetch and other link tags

Ivan Akulov has collected a whole bunch of information and know-how on making things load a bit more quickly with preload and prefetch. That’s great in and of itself, but he also points to something new to me – the as attribute:

<link rel="preload" href="/style.css" as="style" />

Supposedly, this helps browsers prioritize when to download assets and which assets to load.

My favorite part of this post is Ivan’s quick summary at the end which clearly defines what all these different tags can be used for:

<link rel="preload"> – when you’ll need a resource in a few seconds
<link rel="prefetch"> – when you’ll need a resource on a next page
<link rel="preconnect"> – when you know you’ll need a resource soon, but you don’t know its full url yet

Make sure to check out our own post on the matter of prefetching, preloading, and prebrowsing, too. Adding these things to our links can make significant performance improvements and so check it out to add more resources to your performance toolbox.

Direct Link to ArticlePermalink

The post Preload, prefetch and other link tags appeared first on CSS-Tricks.

Who has the fastest website in F1?

Jake Archibald looks at the websites of Formula One race teams and rates their performance, carefully examining their images and digging into the waterfall of assets for each site:

Trying to use a site while on poor connectivity is massively frustrating, so anything sites can do to make it less of a problem is a huge win.

In terms of the device, if you look outside the tech bubble, a lot of users can’t or don’t want to pay for a high-end phone. To get a feel for how a site performs for real users, you have to look at mid-to-lower-end Android devices, which is why I picked the Moto G4.

This reminds me of Tim Kadlec’s post earlier in the year about the ethics of performance:

Poor performance can, and does, lead to exclusion. This point is extremely well documented by now, but warrants repeating. Sites that use an excess of resources, whether on the network or on the device, don’t just cause slow experiences, but can leave entire groups of people out.

Anyway, back to Jake’s post about Formula One websites. I love that Jake writes in such a way that his points aren’t insulting to those who work on these sites, but hones in on what we can learn about the myriad issues that lead to bad web performance. Subsequently, Jake provides us all with a ton of useful ideas for fixing performance issues like annoying layout changes, scripts that block rendering, unused CSS issues that also block rendering, and loading states.

Oh, and this reminds me that Chris noted a while back that the loading experience for most websites can be vastly improved:

Direct Link to ArticlePermalink

The post Who has the fastest website in F1? appeared first on CSS-Tricks.

Planning for Responsive Images

The first time I made an image responsive, it was as simple as coding these four lines:

img { max-width: 100%; height auto; /* default */
}

Though that worked for me as a developer, it wasn’t the best for the audience. What happens if the the image in the src attribute is heavy? On high-end developer devices (like mine with 16GB RAM), few or no performance problems occur. But on low-end devices? It’s another story.

image at multiple screen sizes

The above illustration isn’t detailed enough. I’m from Nigeria and, if your product works in Africa, then you shouldn’t be looking at that. Look at this graph instead:

Nowadays, the lowest-priced iPhone sells for an average of $300. The average African can’t afford it even though iPhone is a threshold for measuring fast devices.

That’s all the business analysis you need to understand that CSS width doesn’t cut it for responsive images. What would, you ask? Let me first explain what images are about.

Nuances of images

Images are appealing to users but are a painstaking challenge for us developers who must consider the following factors:

  • Format
  • Disk size
  • Render dimension (layout width and height in the browser)
  • Original dimension (original width and height)
  • Aspect ratio

So, how do we pick the right parameters and deftly mix and match them to deliver an optimal experience for your audience? The answer, in turn, depends on the answers to these questions:

  • Are the images created dynamically by the user or statically by a design team?
  • If the width and height of the image are changed disproportionately, would that affect the quality?
  • Are all the images rendered at the same width and height? When rendered, must they have a specific aspect ratio or one that’s entirely different?
  • What must be considered when presenting the images on different viewports?

Jot down your answers. They will not only help you understand your images — their sources, technical requirements and such — but also enable you to make the right choices in delivery.

Provisional strategies for image delivery

Image delivery has evolved from a simple addition of URLs to the src attribute to complex scenarios. Before delving into them, let’s talk about the multiple options for presenting images so that you can devise a strategy on how and when to deliver and render yours.

First, identify the sources of the images. That way, the number of obscure edge cases can be reduced and the images can be handled as efficiently as possible.

In general, images are either:

  • Dynamic: Dynamic images are uploaded by the audience, having been generated by other events in the system.
  • Static: A photographer, designer, or you (the developer) create the images for the website.

Let’s dig into strategy for each of this types of images.

Strategy for dynamic images

Static images are fairly easy to work with. On the other hand, dynamic images are tricky and prone to problems. What can be done to mitigate their dynamic nature and make them more predictable like static images? Two things: validation and intelligent cropping.

Validation

Set out a few rules for the audience on what is acceptable and what is not. Nowadays, we can validate all the properties of an image, namely:

  • Format
  • Disk size
  • Dimension
  • Aspect ratio

Note: An image’s render size is determined during rendering, hence no validation on our part.

After validation, a predictable set of images would emerge, which are easier to consume.

Intelligent Cropping

Another strategy for handling dynamic images is to crop them intelligently to avoid deleting important content and refocus on (or re-center) the primary content. That’s hard to do. However, you can take advantage of the artificial intelligence offered by open-source tools or SaaS companies that specialize in image management. An example is in the upcoming sections.


Once a strategy has been nailed down for dynamic images, create a rule table with all the layout options for the images. Below is an example. It’s even worth looking into analytics to determine the most important devices and viewport sizes.

Browser Viewport HP Laptop PS4 Slim Camera Lens / Aspect Ratio
< 300 100 vw 100 vw 100 vw/1:2
300 – 699 100 vw 100 vw 100 vw/1:1
700 – 999 50 vw 50 vw 50 vw/1:1
> 999 33 vw 33 vw 100 vw/1:2

The bare (sub-optimal) minimum

Now set aside the complexities of responsiveness and just do what we do best — simple HTML markup with maximum-width CSS.

The following code renders a few images:

<main> <figure> <img src="https://res.cloudinary.com/...w700/ps4-slim.jpg" alt="PS4 Slim"> </figure> <figure> <img src="https://res.cloudinary.com/...w700/x-box-one-s.jpg" alt="X Box One S"> </figure> <!-- More images --> <figure> <img src="https://res.cloudinary.com/...w700/tv.jpg" alt="Tv"> </figure>
</main>

Note: The ellipsis (…) in the image URL specifies the folder, dimension, and cropping strategy, which are too much detail to include, hence the truncation to focus on what matters now. For the complete version, see the CodePen example down below.

This is the shortest CSS example on the Internet that makes images responsive:

/* The parent container */
main { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
} img { max-width: 100%;
}

If the images do not have a uniform width and height, replace max-width with object-fit and set the value to cover.

Jo Franchetti’s blog post on common responsive layouts with CSS Grid explains how the value of grid-template-columns makes the entire layout adaptive (responsive).

See the Pen
Grid Gallery
by Chris Nwamba (@codebeast)
on CodePen.

The above is not what we are looking for, however, because…

  • the image size and weight are the same on both high-end and low-end devices, and
  • we might want to be stricter with the image width instead of setting it to 250 and letting it grow.

Well, this section covers “the bare minimum” so that’s it.

Layout variations

The worst thing that can happen to an image layout is mismanagement of expectations. Because images might have varying dimensions (width and height), we must specify how to render the images.

Should we intelligently crop all the images to a uniform dimension? Should we retain the aspect ratio for a viewport and alter the ratio for a different one? The ball is in our court.

In case of images in a grid, such as those in the example above with different aspect ratios, we can apply the technique of art direction to render the images. Art direction can help achieve something like this:

For details on resolution switching and art direction in responsive images, read Jason Grigsby’s series. Another informative reference is Eric Portis’s Responsive Images Guide, parts 1, 2, and 3.

See the code example below.

<main> <figure> <picture> <source media="(min-width: 900px)" srcset="https://res.cloudinary.com/.../c_fill,g_auto,h_1400,w_700/camera-lens.jpg"> <img src="https://res.cloudinary.com/.../c_fill,g_auto,h_700,w_700/camera-lens.jpg" alt="Camera lens"> </picture> </figure> <figure> <picture> <source media="(min-width: 700px)" srcset="https://res.cloudinary.com/.../c_fill,g_auto,h_1000,w_1000/ps4-pro.jpg"></source> </picture> <img src="https://res.cloudinary.com/.../c_fill,g_auto,h_700,w_700/ps4-pro.jpg" alt="PS4 Pro"> </figure>
</main>

Instead of rendering only one 700px wide image, we render 700px x 700px only if the viewport width exceeds 700px. If the viewport is larger, then the following rendering occurs:

  • Camera lens images are rendered as a portrait image of 700px in width and 1000px. in height (700px x 1000px).
  • PS4 Pro images are rendered at 1000px x 1000px.

Art direction

By cropping images to make them responsive, we might inadvertently delete the primary content, like the face of the subject. As mentioned previously, AI open-source tools can help crop intelligently and refocus on the primary objects of images. In addition, Nadav Soferman’s post on smart cropping is a useful start guide.

Strict grid and spanning

The first example on responsive images in this post is a flexible one. At a minimum of 300px width, grid items automagically flow into place according to the viewport width. Terrific.

On the other hand, we might want to apply a stricter rule to the grid items based on the design specifications. In that case, media queries come in handy.

Alternatively, we can leverage the grid-span capability to create grid items of varied widths and lengths:

@media(min-width: 700px) { main { display: grid; grid-template-columns: repeat(2, 1fr); }
} @media(min-width: 900px) { main { display: grid; grid-template-columns: repeat(3, 1fr) } figure:nth-child(3) { grid-row: span 2; } figure:nth-child(4) { grid-column: span 2; grid-row: span 2; }
}

For an image that is 1000px x 1000px square on a wide viewport, we can span it to take two grid cells on both row and column. The image that changes to a portrait orientation (700px x 1000px) on a wider viewport can take two cells on a row.

See the Pen
Grid Gallery [Art Direction]
by Chris Nwamba (@codebeast)
on CodePen.

Progressive optimization

Blind optimization is as lame as no optimization. Don’t focus on optimization without predefining the appropriate measurements. And don’t optimize if the optimization is not backed by data.

Nonetheless, ample room exists for optimization in the above examples. We started with the bare minimum, showed you some cool tricks, and now we have a working, responsive grid. The next question to ask is, “If the page contains 20-100 images, how good will the user experience be?”

Here’s the answer: We must ensure that in the case of numerous images for rendering, their size fits the device that renders them. To accomplish that, we need to specify the URLs of several images instead of one. The browser would pick the right (most optimal) one according to the criteria. This technique is called resolution switching in responsive images. See this code example:

<img srcset="https://res.cloudinary.com/.../h_300,w_300/v1548054527/ps4.jpg 300w, https://res.cloudinary.com/.../h_700,w_700/v1548054527/ps4.jpg 700w, https://res.cloudinary.com/.../h_1000,w_1000/v1548054527/ps4.jpg 1000w" sizes="(max-width: 700px) 100vw, (max-width: 900px) 50vw, 33vw" src="https://res.cloudinary.com/.../h_700,w_700/v1548054527/ps4.jpg 700w" alt="PS4 Slim">

Harry Roberts’s tweet intuitively explains what happens:

When I first tried resolution switching, I got confused and tweeted:

Hats off to Jason Grigsby for the clarification in his replies.

Thanks to resolution switching, if the browser is resized, then it downloads the right image for the right viewport; hence small images for small phones (good on CPU and RAM) and larger images for larger viewports.

The above table shows that the browser downloads the same image (blue rectangle) with different disk sizes (red rectangle).

See the Pen
Grid Gallery [Optimized]
by Chris Nwamba (@codebeast)
on CodePen.

Cloudinary’s open-source and free Responsive Image Breakpoints Generator is extremely useful for adapting website images to multiple screen sizes. However, in many cases, setting srcset and sizes alone would suffice.

Conclusion

This article aims at affording simple yet effective guidelines for setting up responsive images and layouts in light of the many—and potentially confusing—options available. Do familiarize yourself with CSS grid, art direction, and resolution switching and you’ll be a ninja in short order. Keep practicing!

The post Planning for Responsive Images appeared first on CSS-Tricks.

The Client/Server Rendering Spectrum

I’ve definitely been guilty of thinking about rendering on the web as a two-horse race. There is Server-Side Rendering (SSR, like this WordPress site is doing) and Client-Side Rendering (CSR, like a typical React app). Both are full of advantages and disadvantages. But, of course, the conversation is more nuanced. Just because an app is SSR doesn’t mean it doesn’t do dynamic JavaScript-powered things. And just because an app is CSR doesn’t mean it can’t leverage any SSR at all.

It’s a spectrum! Jason Miller and Addy Osmani paint that picture nicely in Rendering on the Web.

My favorite part of the article is the infographic table they post at the end of it. Unfortunately, it’s a PNG. So I took a few minutes and <table>-ized it, in case that’s useful to anyone.

See the Pen
The Client/Server Rendering Spectrum
by Chris Coyier (@chriscoyier)
on CodePen.

Direct Link to ArticlePermalink

The post The Client/Server Rendering Spectrum appeared first on CSS-Tricks.

The Bottleneck of the Web

Steve Souders, “JavaScript Dominates Browser CPU”:

Ten years ago the network was the main bottleneck. Today, the main bottleneck is JavaScript. The amount of JavaScript on pages is growing rapidly (nearly 5x in the last 7 years). In order to keep pages rendering and feeling fast, we need to focus on JavaScript CPU time to reduce blocking the browser main thread.

Alex Russell, describing a prototype of “Never-Slow Mode” in Chrome:

… blocks large scripts, sets budgets for certain resource types (script, font, css, images), turns off document.write(), clobbers sync XHR, enables client-hints pervasively, and buffers resources without Content-Length set.

Craig Hockenberry, posting an idea to the WebKit bug tracker:

Without limits, there is no incentive for a JavaScript developer to keep their codebase small and dependencies minimal. It’s easy to add another framework, and that framework adds another framework, and the next thing you know you’re loading tens of megabytes of data just to display a couple hundred kilobytes of content. …

The situation I’m envisioning is that a site can show me any advertising they want as long as they keep the overall size under a fixed amount, say one megabyte per page. If they work hard to make their site efficient, I’m happy to provide my eyeballs.

It’s easy to point a finger at frameworks and third-party scripts for large amounts of JavaScript. If you’re interested in hearing more about the size of frameworks, you might enjoy me and Dave discussing it with Jason Miller.

And speaking of third-parties, Patrick Hulce created Third Party Web: “This document is a summary of which third-party scripts are most responsible for excessive JavaScript execution on the web today.”

Sometimes name-and-shame is an effective tactic to spark change.

Addy Osmani writes about an ESLint rule that prohibits particular packages, of which you could use to prevent usage of known-to-be-huge packages. So if someone tries to load the entirety of lodash or moment.js, it can be stopped at the linting level.

Tim Kadlec ties the threads together very well in “Limiting JavaScript?” If your gut reaction on this is that JavaScript is being unfairly targeted as a villain, Tim acknowledges that:

One common worry I saw voiced was “if JavaScript, why not other resources too?”. It’s true; JavaScript does get picked on a lot though it’s not without reason. Byte for byte, JavaScript is the most significant detriment to performance on the web, so it does make sense to put some focus on reducing the amount we use.

However, the point is valid. JavaScript may be the biggest culprit more often than not, but it’s not the only one.

The post The Bottleneck of the Web appeared first on CSS-Tricks.

“the closest thing web standards have to a golden rule”

The internet’s own Mat Marquis plucks this choice quote from the HTML Design Principals spec:

In case of conflict, consider users over authors over implementors over specifiers over theoretical purity.

And then he applies the idea to putting images on websites in 2019.

Direct Link to ArticlePermalink

The post “the closest thing web standards have to a golden rule” appeared first on CSS-Tricks.

The Ethics of Web Performance

Tim Kadlec on the issues surrounding poor web performance and why it’s so important for us to care about making our sites as fast as possible:

Poor performance can, and does, lead to exclusion. This point is extremely well documented by now, but warrants repeating. Sites that use an excess of resources, whether on the network or on the device, don’t just cause slow experiences, but can leave entire groups of people out.

There is a growing gap between what a high-end device can handle and what a middle to low-end device can handle. When we build sites and applications that include a lot of CPU-bound tasks (hi there JavaScript), at best, those sites and applications become painfully slow on people using those more affordable, more constrained devices. At worst, we ensure that our site will not work for them at all.

Forget about comparing this year’s device to a device a couple of years old. Exclusion can happen on devices that are brand-new as well. The web’s growth is being pushed forward primarily by low-cost, underpowered Android devices that frequently struggle with today’s web.

As Tim mentions at the end of that piece though, it’s easy to forget web performance and it’s sometimes hard to make the case for making a website fast. It’s often seen as a nice-to-have instead of as a core feature in and of itself, like semantic markup and accessibility compliance.

I’m optimistic that the conversation surrounding this topic is improving things though. Having tools like Lighthouse built straight into the browser makes things easier and the abundance of testing tools such as Calibre gives us insights into exactly what and where issues might be. But we also need to remember that this isn’t solely a technical problem — it’s an ethical one, too.

Direct Link to ArticlePermalink

The post The Ethics of Web Performance appeared first on CSS-Tricks.

Fighting FOIT and FOUT Together

Lots from Divya with the setup:

There are 2 kinds of problems that can arise when using webfonts; Flash of invisible text (FOIT) and Flash of Unstyled Text (FOUT) … If we were to compare them, FOUT is of course the lesser of the two evils

If you wanna fight FOIT, the easiest tool is the font-display CSS property. I like the optional value because I generally dislike the look of fonts swapping.

If you want to fight them both, one option is to preload the fonts:

<link rel="preload" href="/fonts/awesome-l.woff2" as="font" />

But…

Preload is your friend, but not like your best friend … preloading in excess can significantly worsen performance, since preloads block initial render.

Just like CSS does.

In a conversation with Scott Jehl, he pointed out to me that “preloads block initial render” isn’t quite true, and he put together a test case. A <link rel="preload" ...> resource doesn’t block rendering in and of itself.

Even huge sites aren’t doing much about font loading perf. Roel Nieskens:

I expected major news sites to be really conscious about the fonts they use, and making sure everything is heavily optimised. Turns out a simple Sunday afternoon of hacking could save a lot of data: we could easily save roughly 200KB

Fonts are such big part of web perf, so let’s get better at it! Here’s Zach Leatherman at the Performance.now() conference:

Part of the story is that we might just have lean on JavaScript to do the things we need to do. Divya again:

Web fonts are primarily CSS oriented. It can therefore feel like bad practice to reach for JavaScript to solve a CSS issue, especially since JavaScript is a culprit for an ever increasing page weight.

But sometimes you just have to do it in order to get what you need done. Perhaps you’d like to handle page visibility yourself? Here’s Divya’s demonstration snippet:

const font = new fontFace("My Awesome Font", "url(/fonts/my-awesome-font.woff2)" format('woff2')") font.load().then (() => { document.fonts.add(font); document.body.style.fontFamily = "My Awesome Font, serif"; // we can also control visibility of the page based on a font loading // var content = document.getElementById("content"); content.style.visibility = "visible"; })

But there are a bunch of other reasons. Zach has documented them:

  • Because, as you load in fonts, each of them can cause repaints and you want to group them.
  • Because the user has indicated they want to use less data or reduce motion.
  • Because you’d like to be kind to slow networks.
  • Because you’re using a third-party that can’t handle font-display.

The post Fighting FOIT and FOUT Together appeared first on CSS-Tricks.

CSS and Network Performance

JavaScript and images tend to get the bulk of the blame for slow websites, but Harry explains very clearly why CSS is equally to blame and harder to deal with:

  1. A browser can’t render a page until it has built the Render Tree;
  2. the Render Tree is the combined result of the DOM and the CSSOM;
  3. the DOM is HTML plus any blocking JavaScript that needs to act upon it;
  4. the CSSOM is all CSS rules applied against the DOM;
  5. it’s easy to make JavaScript non-blocking with async and defer
    attributes;
  6. making CSS asynchronous is much more difficult;
  7. so a good rule of thumb to remember is that your page will only render as quickly as your slowest stylesheet.

There are lots of options to do better with this, including some interesting things that HTTP/2 unlocks.

Check out Šime Vidas’s takeaways as well. It’s all fascinating, but the progressive rendering stuff is particularly cool. I suspect many CSS-in-JS libraries could/should help with doing things this way.

Direct Link to ArticlePermalink

The post CSS and Network Performance appeared first on CSS-Tricks.

Why Browsers Download Stylesheets with Non-Matching Media Queries

Say you have a stylesheet linked up like this:

<link href="mobile.css" rel="stylesheet" media="screen and (max-width: 600px)">

But as the page loads, you’re on a desktop browser where the screen is 1753px wide. The browser should just skip loading that stylesheet entirely, right? It doesn’t. Thomas Steiner explains:

it turns out that the CSS spec writers and browser implementors are actually pretty darn smart about this:

The thing is, the user could always decide to resize their window (impacting width, height, aspect ratio), to print the document, etc., and even things that at first sight seem static (like the resolution) can change when a user with a multi-screen setup moves a window from say a Retina laptop screen to a bigger desktop monitor, or the user can unplug their mouse, and so on.

What browsers do do (heh, 💩) is apply a Lowest download priority.

Direct Link to ArticlePermalink

The post Why Browsers Download Stylesheets with Non-Matching Media Queries appeared first on CSS-Tricks.