-
CORS OPTIONS preflight optimization
tl;dr: Cross-Origin Resource Sharing (CORS), a good practice enforced by browsers for security purposes is a performance slowdown. Thus, the next best thing you can do starting with the 2nd request, is to cache your CORS OPTIONS preflight responses, but there’s a catch.
-
adoptedStyleSheets as a performance optimization
tl;dr: Use
document.adoptedStyleSheets
to attach one constructable stylesheet to many shadow roots. This offloads style changes to the browser and updates all web components that have adopted these style sheets. Otherwise, you’ll have to use JavaScript to “manually” update each shadow root which means it’s likely going to be slower. -
Server-Timing HTTP header
tl;dr: Use
Server-Timing
HTTP header to help debug internal latencies. While this is useful for debugging, it does potentially expose how your services are connected to each other. Even so, the debugging benefits outway the privacy risk. -
JPEG minification with mozjpeg
tl;dr: Use
mozjpeg
to minify JPEGs. -
PNG minification with pngquant
tl;dr: Use
pngquant
to minify PNGs. -
GIF minification with gifsicle
tl;dr: Use
gifsicle
to minify GIFs. -
preload relationship
tl;dr: Use
<link rel="preload" href="/assets/atkinson-hyperlegible-regular-102a.woff2" />
to tell the browser it needs to schedule the asset to be downloaded and cached with higher priority. -
sticky position
tl;dr: Use
position: sticky;
to create parallax effects. Avoid any JavaScript as much as possible and use native CSS to handle the logic because it’s much more performant. -
bind memoization
tl;dr: Calling
bind
on a function is expensive because each call creates a net new function. Memoize bindings outside of loops and just call the bound functions inside the loops. -
preconnect relationship
tl;dr: Use
<link rel="preconnect" href="https://api.example.com" />
if you know your website will make requests to your API, thumbnail, CDN endpoints etc. -
merge chained filters
tl;dr: Refactor sample code like
[].filter((v) => v >= 0.4).filter((v) => v <= 0.6)
to[].filter((v) => v >= 0.4 && v <= 0.6)
. This way, code will iterate on the array just once, rather than n times (once for eachfilter
call). -
ApacheBench
tl;dr: If you need a quick way to test any API or server-side rendered (SSR) web page, use
ab -c 10 -n 100 "https://example.com/"
which says issue 10 concurrent out of 100 total requsts. This Apache benchmarking tools then displays performance statistics. -
HTTP/3
tl;dr: HTTP/3 is UDP-based, rather than TCP-based, thus connections are established faster. It’s based on Google’s QUIC protocol. Use HTTP/3 if available.
-
will-change
tl;dr: Use the
will-change
CSS property to hint the rendering engine to optimize animations. Avoid thetransform: translate3d(0, 0, 0);
trick. -
addEventListener + removeEventListener
tl;dr: Avoid memory leaks by ensuring that if you register a callback to
addEventListener
you also unregister it withremoveEventListener
later on. -
structuredClone instead of JSON.parse + JSON.stringify
tl;dr: To deep clone objects, Use
structuredClone(value)
rather than theJSON.parse(JSON.stringify(value))
trick. Also, avoid Lodash’s_.cloneDeep(value)
due to import cost. -
requestAnimationFrame + setTimeout
tl;dr: This is how you correctly measure performance after style, layout, and paint operations.
-
V8 flags
tl;dr: A printout of all Chromium V8 flags. Some are useful for debugging.
-
HTTP/2
tl;dr: Avoid HTTP/1.1 because browsers limit the number of concurrent requests going to HTTP/1.1 origins. Use HTTP/2.
-
performance
tl;dr: Avoid using
Date
to measure durations. Use theperformance
interface to measure durations because of its high precision. -
Intl
tl;dr: Use
Intl
to compute relative dates, rather than rely on Luxon or Moment which are huge size-wise. -
lazy loading
tl;dr: Use
loading="lazy"
to defer loading images that are off-screen until the user scrolls near them. -
SVG minification with svgo
tl;dr: Use
svgo
to minify SVGs. -
Brotli compression
tl;dr: Compress assets such as JavaScript and CSS using Brotli rather than gzip.