Tools

Undertstanding WebPageTest chart

The impact of third party scripts on the Web

Google H2 auto push - This project is for automating server push and getting rid of the need for manual configurations from service developers. It is meant as a helper library for building middlewares for various Node.js web servers, such as Express, fastify, etc.

Blackhole servers

A blackhole server can be used to route third party traffic through an endpoint that effectively makes requests disappear, recreating the effects of a complete outage. 72.66.115.13 provided by webpagetest

Because these types of assets block rendering, the browser will not paint anything to the screen until they have been downloaded (and executed/parsed). If the service that provides the file is offline, then that’s a lot of time that the browser has to spend_trying_to access the file, and during that period the user is left potentially looking at a blank screen. After a certain period has elapsed, the browser will eventually timeout and display the page without the asset(s) in question. How long is that certain period of time?

It’s1 minute and 20 seconds.

If you have any render-blocking, critical, third party assets hosted on an external domain, you run the risk of showing users a blank page for 1.3 minutes.

Critical path css

Usus - Renders page using Chrome Debugging Protocol (CDP). Extracts CSS used to render the page. Renders HTML with the blocking CSS made asynchronous. Inlines the critical CSS.

inline-critical-css - Stream that inlines critical CSS in HTML. Looks at the used CSS on a page and only inlines the CSS that's used.

Animations

FLIP

will-change - https://github.com/Microsoft/monaco-editor/issues/426

120fps

Bundling

bundle-buddy - Bundle Buddy is a tool to help you find source code duplication across your javascript chunks/splits. This enables you to fine tune code splitting parameters to reduce bundle invalidation rates as well as improve repeat page load performance \o/.

esbench -

Techniques

Use this.Reflektive to feature detect 2015

Skeleton screens - skeleton screens ensure that whenever the user taps any button or link, the page reacts immediately by transitioning the user to that new page and then _loading in content to that page _as the content becomes available.

Measuring Interactivity with TTI: Time To (consistently) Interactive

Perceived performance

Designing for mobile performance

Most of the time it's more important to make the app feel fast, rather than making it fast for real.

Humans overestimate passive waits by 36%, per Richard Larson of MIT

If your app is slow, and you focus on improving objective speed, it'll have to be 20% faster than before for the difference to even be noticeable. Which means around 30% is needed to make it feel like an impactful improvement.

Managing user wait time
  • Respond immediately.
  • Let users know where they are in the waiting process; how much time is elapsed and how much is left to go.
  • Especially with long waits, keeping user attention focused on other things.
  • Render minimum viable layout, to get users out of a passive phase and into an interactive, usable page ASAP

Postulated by business consultant David Maister but confirmed in several studies. If people don't have a sense of how much has elapsed and how much is left, the wait feels longer.

Clicks

Replace click events with mousedown (and touchstart) events. Click events actually fire not when the mouse button goes down, but when it comes back up again. So there's this gap when the user has clicked down, but the click event has yet to fire. We can load things when the mouse button goes down, and only display them when the click event fires as the user releases their mouse button. Gives about a 100-150ms head start.

Progress bars

Chris Harrison, a grad student at Carnegie Mellon found that progress bars with bands that animate in the opposite direction of the progress make the bar seem to fill faster. Same principle of being on a train, and another train is coming by the opposite direction, you look out the window to see the other train whizzing by, and it seems like you're going twice as fast.

In a followup study he found that if those bands accellerate, the bar feels faster still. Can get that accelerating feel just by applying an ease-in to the animation. He found that they feel 12% faster.

  • Any action taking less than 1 or so seconds doesn't need an indicator at all, thought is uninterrupted. By showing an indicator here, you're taking their focus away from the action they just took and forcing them to focus on the fact that they have to wait for the app to respond. So you are in effect making the app feel *slower*.
  • 1-3 seconds displaying a progress bar is preferable. Don't need to include lots of written explanation as to what the app is doing, since this is within the window where most people still have patience.
  • 3-10s? Include an explanation as to what the app is doing. These durations can seem unreasonable if you don't explain to the user what is happening.

Spinners

Spinners have a pretty narrow use case. Don't want to use them if the expected wait time is less than 1s or so, because user flow won't be disrupted. Don't want to use them if the expected wait time is ~2.5s or up, since users need certainty as to where they are in the process. So you're looking at using them for loads between 1 - 2ish seconds.

With long waits, up to and past 10 seconds. Sometimes you just have to distract users and keep them from focusing on how long the wait is. Games frequently give players tips to read during long loading screens. Tips require high levels of mental activity to read them, digest them, and integrate them into the player's existing play style. Thus holding attention. Uber's old screen when it was matching you with a driver was interactive. You could draw little light doodles in this creative play space. If you know the wait is going to be *very* long, give users something interactive to play with, because nothing holds attention like play.

At the end of the day, what matters is how it feels.

If you have sufficient low hanging fruit to effect a 30% speedup in your app then by all means, do it. But many team don't have that luxury, and for them it makes a great deal of sense to focus on subjective performance measures before dedicating significant resources on physically making their product faster.

Above the fold size

Due to how TCP estimates the capacity of a connection (i.e. TCP Slow Start), a new TCP connection cannot immediately use the full available bandwidth between the client and the server. Because of this, the server can send up to 10 TCP packets on a new connection (~14KB) in first roundtrip, and then it must wait for client to acknowledge this data before it can grow its congestion window and proceed to deliver more data.

Also, it is important to note that the 10 packet (IW10) limit is a recent update to the TCP standard: you should ensure that your server is upgraded to latest version to take advantage of this change. Otherwise, the limit will likely be 3-4 packets!

Due to this TCP behavior, it is important to optimize your content to minimize the number of roundtrips required to deliver the necessary data to perform the first render of the page. Ideally, the ATF content should fit under 98KB - this allows the browser to paint the page after just three roundtrips to have plenty time budget for server response latency and client rendering.

Frameworks

React performance

Using should component update

Benchmarking server side applications

Preact performance

Parial hydration with Preact - may apply to React too

Ember

Glimmer binary

Images

Images guide - long ass book about image optimization.

Image decoding

Using SVG as image placeholders

Cloudflare progressive image streaming

<!-- the decode for this image may be deferred -->
<img decoding="async" src="..." />

<!-- if possible the decode for this image should not be deferred -->
<img decoding="sync" src="..." />

<!-- the browser is free to do what it feels is best for the user -->
<img decoding="auto" src="..." />

Chrome proposal for lazyloading images and iframes

Sending data in a comment might be the fastest way to do it, need to benchmark parsers.

GIF

Safari TL ships an image tag that let's you load mp4 as images. A superb alternative to gifs.

Metrics

How Wiki Media foundation tracks performance regressions

Client-side Performance Monitoring with InfluxDB

A step by step guide to monitoring the competition with the Chrome UX Report

Layout instability API

How Google Pagespeed works: Improve Your Score and Search Engine Ranking

Browsers

Fastdom - Batch dom read/writes

Using the cache api to switch between inline and cached files

Don't block the page unload event by using Beacon API

An analysis of Chromium's paint timing metrics

Resource timing

Code caching for JavaScript developers

Use chrome://tracing Look for v8.compile or v8.compileModule.

cacheProduceOptions, producedCacheSize, cacheConsumeOptions, consumedCacheSize

Hacks

Messing with the priority queue

Chrome

Loading priority in Chrome

JavaScript startup performance

User experience report - big query data set for getting performance metrics for certain websites.

The cost of JS - points out some common performance problems that browsers have when loading up js files.

Case studies

Treebo - great study of a fast web app.

Can you afford a performance budget

Pinterest

Tinder

Start Performance Budgeting

How to make a performance budget

Performance budgets that stick

CSS

Reducing the size of css class names

Using the Cache API to cache inlines styles

Loading fonts using JS

Gotchas of using preload on fonts

Variable fonts

Split css files by media queries

<link rel="stylesheet" href="all.css" media="all" />
<link rel="stylesheet" href="small.css" media="(min-width: 20em)" />
<link rel="stylesheet" href="medium.css" media="(min-width: 64em)" />
<link rel="stylesheet" href="large.css" media="(min-width: 90em)" />
<link rel="stylesheet" href="extra-large.css" media="(min-width: 120em)" />
<link rel="stylesheet" href="print.css" media="print" />

More about loading css files

A browser will not execute a <script> if there is any currently-in flight CSS.

<link rel="stylesheet" href="slow-loading-stylesheet.css" />
<script>
  console.log(
    "I will not run until slow-loading-stylesheet.css is downloaded."
  );
</script>
<!-- This JavaScript executes as soon as it has arrived. -->
<script src="i-need-to-block-dom-but-DONT-need-to-query-cssom.js"></script>

<link rel="stylesheet" href="app.css" />

<!-- This JavaScript executes as soon as the CSSOM is built. -->
<script src="i-need-to-block-dom-but-DO-need-to-query-cssom.js"></script>

Networking

Server timing API

Use the network information api to figure out what kind of an connection the user has

HTTP2 - what no one is telling you

Using HAR for performance benchmarking

Better HTTP/2 Prioritization for a Faster Web

As described above, early in the page load cycle before the browser can render any content it is blocked on the CSS and blocking JavaScript in the section of the HTML. During that part of the loading cycle it is best for 100% of the connection bandwidth to be used to download the blocking resources and for them to be downloaded one at a time in the order they are defined in the HTML. That lets the browser parse and execute each item while it is downloading the next blocking resource, allowing the download and execution to be pipelined.

Service workers

Bringing service workers to Google Search Using service workers to cache a part of the html

Tracking statistics

How a decrease in bundle size increased the response times

results matching ""

    No results matching ""