Performance

Using SVG as image placeholders

I’m passionate about image performance optimisation and making images load fast on the web. One of the most interesting areas of exploration is placeholders: what to show when the image hasn’t loaded yet.

During the last days I have come across some loading techniques that use SVG, and I would like to describe them in this post.

The whole web at maximum FPS: How WebRender gets rid of jank

Do you want a deep and nerdy dive into the web browser rendering and how the upcoming WebRender rendering engine for Firefox will use the GPU more like games currently do?

[T]here’s another big piece of Servo technology that’s not in Firefox Quantum quite yet, though it’s coming soon. That’s WebRender, which is being added to Firefox as part of the Quantum Render project.

Intersection Observer

What do infinite scrolling, lazy loading, and online advertisements all have in common?

They need to know about—and react to—the visibility of elements on a page!

Unfortunately, knowing whether or not an element is visible has traditionally been difficult on the Web. Most solutions listen for scroll and resize events, then use DOM APIs like getBoundingClientRect() to manually calculate where elements are relative to the viewport. This usually works, but it’s inefficient and doesn’t take into account other ways in which an element’s visibility can change, such as a large image finally loading higher up on the page, which pushes everything else downward.

Things get worse for advertisements, since real money is involved. As Malte Ubl explained in his presentation at JSConf Iceland, advertisers don’t want to pay for ads that never get displayed. To make sure they know when ads are visible, they cover them in dozens of tiny, single-pixel Flash movies whose visibility can be inferred from their framerate. On platforms without Flash, like smartphones, advertisers set up timers to force browsers to recalculate the position of each ad every few milliseconds.

These techniques kill performance, drain batteries, and would be completely unnecessary if the browser could just notify us whenever an element’s visibility changed.

That’s what IntersectionObserver does.

Musings on HTTP/2 and Bundling

In the nooks and crannies of the web performance discipline there are no simple answers, except “do your research”. Rely on analytics to decide if bundling is a good idea for your HTTP/2-driven site. Do you have a lot of users that only go to one or two pages and leave? Maybe don’t waste your time bundling stuff. Do your users navigate deeply throughout your site and spend significant time there? Maybe bundle.

This much is clear to me: If you move your HTTP/1-optimized site to an HTTP/2 host and change nothing in your client-side architecture, it’s not going to be a big deal. So don’t trust blanket statements some web developer writing blog posts (i.e., me). Figure out how your users behave, what optimizations makes the best sense for your situation, and adjust your code accordingly. Good luck!

How to determine which, if any CSS rules are unused on a site

So this is a really interesting way to determine which, if any CSS rules are unused in a stylesheet, site-wide:

Part of this story could certainly be about deleting CSS that is determined to be “unused” in a project. I know there is incredible demand for this kind of tooling. I feel like there are some developers damn near frothing at the mouth to blast their CSS through some kind of fancy tool to strip away anything unneeded.

[…]

Here’s how one company I heard from was doing it:

  1. They injected a script onto the page for some subset of users.
  2. The script would look at the CSSOM and find every single selector in the CSS for that page.
  3. It would also run a querySelectorAll(“*”) and find every single DOM node on that page.
  4. It would compare those two sets and find all selectors that seemed to be unused.
  5. In order to get the best results, it would fire this script after a random amount of seconds, on a random set of users, in a random set of conditions. Even with this, it needed a lot of data over a long period of time.
  6. After that had run for long enough, there was a set of CSS selectors that seemed likely to be unused.
  7. To be sure, unique background images were applied to all those selectors.
  8. After applying those and waiting for another length of time, the server logs were checked to make sure those images were never accessed. If they were, that selector was used, and would have to stay.
    Ultimately, the unused selectors could safely be deleted from the CSS.

Whew! That’s an awful lot of work to remove some CSS.

But as you can imagine, it’s fairly safe. Imagine just checking one page’s CSS coverage. You’ll definitely find a bunch of unused CSS. One page, in one specific state, is not representative of your entire website.

Disqus is a performance and privacy nightmare

Relevant points [of disabling Disqus] are:

  • Load-time goes from 6 seconds to 2 seconds.
  • There are 105 network requests vs. 16.
  • There are a lot of non-relevant requests going through to networks that will be tracking your movements.

Among the networks you can find:

  • disqus.com - Obviously!
  • google-analytics.com - Multiple requests; no idea who’s capturing your movements.
  • connect.facebook.net - If you’re logged into Facebook, they know you visit this site.
  • accounts.google.com - Google will also map your visits to this site with any of your Google accounts.
  • pippio.com - LiveRamp identify mapping for harvesting your details for commercial gain.
  • bluekai.com - Identity tracking for marketing campaigns.
  • crwdcntrl.net - Pretty suspect site listed as referenced by viruses and spyware.
  • exelator.com - More identity and movement tracking site which even has a virus named after it!
  • doubleclick.net - We all know this one: ad services and movement tracking, owned by Google.
  • tag.apxlv.net - Very shady and tricky to pin-point an owner as they obsfuscate their domain (I didn’t even know this was a thing!). Adds a tracking pixel to your site.
  • adnxs.com - More tracking garbage, albeit slightly more prolific.
  • adsymptotic.com - Advertising and tracking that suppposedly uses machine learning.
  • rlcdn.com - Obsfuscated advertising/tracking from Rapleaf.
  • adbrn.com - “Deliver a personalized customer journey across devices, channels and platforms with Adbrain customer ID mapping technology.”
  • nexac.com - Oracle’s Datalogix, their own tracking and behavioural pattern rubbish.
  • tapad.com - OK, I cant’t be bothered to search to look this up anymore.
  • liadm.com - More? Oh, ok, then…
  • sohern.com - Yup. Tracking.
  • demdex.net - Tracking. From Adobe.
  • bidswitch.net - I’ll give you one guess…
  • agkn.com - …
  • mathtag.com - Curious name, maybe it’s… no. It’s tracking you.

I can’t visit many of these sites because I have them blocked in uBlock Origin so information was gleaned from google crawl results of the webpages and 3rd parties. Needless to say, it’s a pretty disgusting insight into how certain free products turn you into the product. What’s more worrying are the services that go to lengths to hide who they are and what their purposes are for tracking your movements.

Building performant expand & collapse animations

Use scale transforms when animating clips. You can prevent the children from being stretched and skewed during the animation by counter-scaling them.

[…]

In this post we’re going to look over what’s involved if you want performant clip animations. If you want to see a demo, check out the Sample UI Elements GitHub repo.

Scrolling on the web: A primer

This is a fascinating and thorough dive into scrolling, and should be required reading for anyone writing JavaScript today:

Today, scrolling is still the most fundamental interaction on the web, and perhaps the most misunderstood. For instance, do you know the difference between the following scenarios?

  • User scrolls with two fingers on a touch pad
  • User scrolls with one finger on a touch screen
  • User scrolls with a mouse wheel on a physical mouse
  • User clicks the sidebar and drags it up and down
  • User presses up, down, PageUp, PageDown, or spacebar keys on a keyboard

If you ask the average web user (or even the average web developer!) they might tell you that these interactions are all equivalent. The truth is far more interesting.

CSS Containment

When making a web app, or even a complex site, a key performance challenge is limiting the effects of styles, layout and paint. Oftentimes the entirety of the DOM is considered “in scope” for computation work, which can mean that attempting a self-contained “view” in a web app can prove tricky: changes in one part of the DOM can affect other parts, and there’s no way to tell the browser what should be in or out of scope.

[…]

The good news is that modern browsers are getting really smart about limiting the scope of styles, layout, and paint work automatically, meaning that things are getting faster without you having to do anything.

But the even better news is that there’s a new CSS property that hands scope controls over to developers: Containment.

The contain property

CSS Containment is a new property, with the keyword contain, which supports four values:

  • layout
  • paint
  • size
  • style

Each of these values allows you to limit how much rendering work the browser needs to do.

Note that this is currently only supported in Blink browsers. Firefox has a partial implementation behind a flag, and Edge is under consideration.