🚀⚡ Awesome lists about performance related patches/PRs.
The purpose of this awesome list is to allow others to learn from performance improvements of the past 📝, so that you can submit your performance improvement sooner or later here as well 🤝.
The list also includes blog posts without PRs, if they contain enough code to make them useful for this purpose.
⭐ marks blog posts or articles covering a lot of areas with in-depth explanations.
For Web Performance, there are a few more lists of curated links of talks, newsletters, blogs and more:
➡️ fabkrum/web-performance-resources
➡️ imteekay/web-performance-research
➡️ nucliweb/webperf-snippets
Hint: What improves performance might change over time; always re-validate assumptions by using a reliable benchmarking tool such as bench-node or Tachometer.
Follow me on Twitter for updates.
Patches focused on JavaScript performance improvements. Guides:
- nodejs-bench-operations might be a good starting point to get an idea of what's fast.
- MythBusters JS - A JavaScript Handbook exploring performance & readability.
- v8-perf - Notes and resources related to v8 and thus Node.js performance.
- Optimizing Javascript for fun and for profit📖 - Excellent post about micro-performance in JavaScript.
- V8's strings: implementation and optimizations📖 - Sliced strings, how to reduce memory consumption of strings.
- pnpm - cache results | blog post📖
- Speeding up the JavaScript ecosystem by Marvin Hagemeister📖 | ⭐
- postcss-plugins - avoid expensive RegExps
- svgo - avoid casting
- svgo - avoid double RegExps calls
- and other topics, such as avoiding inline functions in functions, downtranspilation
- esquery - replace
String.prototype.split
, avoid downtranspilation offor..of
, hoist constants. | blog post📖 - joypixels/emoji-toolkit - cache expensive RegExps result | blog post📖
- lucagez/slow-json-stringify - hoist RegExpses & functions, replace
Array.prototype.map
withfor
loops, use?.
instead of||{}
- jshttp/cookie - cache
length
of string inwhile
loop - recharts - avoid expensive DOM calculations by using an early-exit math calculation | blog post📖
- microsoft/node-jsonc-parser - cache frequently used characters in conditions to save memory and make runtime faster
- fabian-hiller/valibot - convert
Set
toArray
- pnpm - convert objects to
Set
andMap
- preact/signals - convert
Set
to Linked Lists, adds lazy value evaluation - TanStack/table - replace immutable spread calls with mutable arrays | blog post
- rollup - replace
Set
withBigInt
| Mastodon explainer - parcel-bundler/parcel - convert graph to array of BitSets, avoid
new
calls,Uint32Array
+ Wasm instead ofBigInt
, array instead of hash map to avoid hashing cost, fast path stack-based depth-first search to avoid recursion | Twitter explainer - parcel-bundler/parcel - AdjacencyList tuning
- xpl/ansicolor - avoid
delete
, optimize for v8 hidden classes, use JS generators to allow more frequent GC collection - Fast JavaScript with Data-oriented Design📖 - converts
Map
to typed arrays, uses "parallel arrays" for more efficient CPU cache usage | Video - A 400% faster Performance panel through perf-ception📖 - replace
Set
with array to reduce memory consumption if uniqueness is guaranteed, discusses downsides ofMap
for frequent and large data sets, because of rehashing | ⭐ - kikobeats/superlock - switches a large array to a linked list to make
shift
anO(1)
operation - microsoft/typescript - makes objects monomorphic by splitting them into 2 objects: one with common properties, one with the rest
- node-semver - bit flags instead of string manipulation
- node-semver -
Object#freeze
for lower memory consumption at around equal perf - typescript -
var
is faster thanlet/const
in the specific use case of TypeScript - three.js - prevent memory leak from sliced strings
- graphql-js -
for..of
downtranspilation & destructuring optimization - preact/signals - convert ES6 classes to ES5 classes for higher performance
- fabianhiller/valibot - lazy evaluation, "is object" check via
var?.constructor !== Object
, array tuples to flat array - nodejs/node - replace N boolean props with one bitmap
- fabianhiller/valibot - avoid (negative) look-aheads for faster regexp execution
- ai/nanoid - re-ordered alphabet for smaller brotli compression
- astro -
AsyncIterable
instead of aReadableStream
- TanStack/query - avoid too frequent
setTimeout
&cancelTimeout
- react - maintain the same object key across the code to avoid causing de-opts
- typescript (PR #2) - ensure objects have a consistent set of properties with a consistent initialization order ("monomorphism"), related to hidden classes
- microsoft/vscode-js-debug - faster stream splitting
- fastify -
indexOf
->slice
to reduce worst-case runtime duration - vitejs/vite - caches repeated
import()
calls (see also, tweet) - nodejs/undici - converts object argument to plain arguments (see also DevTools & Preact hotpath, Fastify, Hermes)
- unjs/unhead - reduces
Promise
use, optimizes arrays toSet
, replacesstring.split
withstring.indexOf()
+string.substring()
and more - vuejs/core - avoid
Promise
use
- Adventures in the land of substrings and RegExps - replaces regex with manual parsing, lazy getter to avoid string allocation
- Don’t attach tooltips to document.body
- Bluebird - minimize function object allocation, use bit flags
- Maybe you don't need Rust and WASM to speed up your JS - post covering insights into various JavaScript engines and low level optimizations | ⭐
- Confluence Whiteboards - DOM event delegation, Finite State Machines, Entity Component System, WebGL optimization | ⭐
- That time I 10x'd a TI-84 emulator's speed by replacing a switch-case - avoid really big
switch..case
statements, replace by manual instruction tables (using arrays) - Understanding why our build got 15x slower with Webpack 5 - avoid
Symbol.isConcatSpreadable
- A Tale of a JavaScript Memory Leak - when working with global RegExp's (
/g
) and very large strings, make sure to check for memory leaks in V8/Chromium (possibly also includes other string functions likesubstring
,slice
,trim
due to v8/2869 - High-performance input handling on the web - avoid layout trashing by splitting
requestAnimationFrame
into one for DOM reads and one for DOM writes - [Typia] Hidden Class Optimization of v8 Engine | ⭐
- npm scripts - lazy module load, prefer
Intl.Collator
overString.prototype.localeCompare
- How to optimize Date format operations - prefer
Intl.DateTimeFormat
overDate.toLocaleDateString
- My Node.js is a bit Rusty - replaces a JS based file parser with a Rust napi implementation for faster execution speed and less memory usage
- Dragging React performance forward & Introducing Pragmatic drag and drop 🎥
- Template engine with streaming capability - avoid creating too many promises, avoid creating too many
ReadableStream
's - The story of a V8 performance cliff in React - initialize
Double
s viaNumber.NaN
instead of0
ornull
, initialize numeric fields with0
instead ofnull
- Sneaky React Memory Leaks II: Closures Vs. React Query - avoid memory leaks in React by using custom hooks
- Promise chaining memory leak - avoid creating too long promise chains; as those cannot be garbage collected
- Canvas optimization & guide to chrome performance devtools tab
- High Performance Text Parsing Using Finite State Machines - replace RegExps with Finite State Machines
- How to Compare Arrays in JavaScript Efficiently - use Frequency Counter Objects to reduce the Big O complexity from
O(n²)
toO(n)
- Web performance case study: Wikipedia page previews - avoid layout trashing
- npm install is slower with a progress bar - the curious case where a progress bar made
npm i
significantly slower, due to expensive CLI/draw calls - solved by throttling - CNet, Times, Wikipedia, Google Play perf audits - 2015
- NYTimes perf audit - 2017
- Notion perf audit - defer JS, Babel tweaks, code splitting, caching and more
- Walmart perf audit - remove old polyfills, CSS & font tweaks
- Causal perf audit - React performance tweaks
- Uber Eats - avoid too many frequent calls to
DOMParser
Patches focused on CSS performance improvements.
- nuka-carousel - removes huge layers by fixing negative
z-index
- mui/mui-x - collection of MUI improvements:
- recalculate style - avoiding updating CSS variables on parents for shorter "recalculate style" tasks
- layerize - make "layerize" tasks shorter by avoiding creating many layers
- scroll direction - emphasize scroll direction for optimistic updates
- nolanlawson/emoji-picker-element (#2) - Improving rendering performance with CSS content-visibility📖
- Selector performance - guidelines for performant CSS selectors
- Need cheap paint? Use getComputedStyle().opacity - replace double
requestAnimationFrame
callbacks for higher perf - Style performance and concurrent rendering - analyzes frequent style inserts with React concurrent rendering
- Style scoping versus shadow DOM: which is fastest? - shadow DOM styles are slightly faster than class-prefixes
- CSS runtime performance🎥 - summary presentation of the 2 links above
- Benchmarking the performance of CSS
@property
- registering@property
's has a cost, but once done is faster than regular props
- Animation performance - guidelines for performant CSS/JS animations
- Animating a blur - animating blur's the performant way
- CSS Box Shadows and Optimize Performance - animating box shadows the performant way
Patches focused on HTML & Core Web Vitals performance improvements.
- sentry - replaces React's
autofocus
implementation with manual focus in the next task for improved INP - radix-ui/primitives - sets CSS inline style on
<body>
after giving the browser a chance to paint for improved INP - nkzw-tech/athena-crisis - moves rendering of 1000 images from
<img>
to canvas to drastically reduce memory footprint
Guides:
- SVG icon stress test📖 - benchmarks the best way to embed
<svg>
s - Avoid an excessive DOM size📖
- Redirect Liquidation📖 - remove redirects using the Edge
- Fastest Way of Passing State to JavaScript, Re-visited📖 - use
JSON.parse
and fake script tags for passing states from server to client - Techniques for bypassing CORS Preflight Requests to improve performance📖 - optimize CORS requests by avoiding
OPTIONS
requests - Use text-wrap: balance; to improve design and INP📖 - replace JS based text balancers with the CSS prop
- INP on HTTPArchive📖 - defer offscreen components to improve early-load INP
- How PubTech reduced INP by up to 64%📖 - "lazy de-rendering", by setting
display:none
first and then remove DOM nodes usingrequestIdleCallback
; yield functions for high and background priority - Optiming INP: Deep Dive 🎥 - yield to main thread, avoid layout trashing, avoid expensive polyfills and css props
- Speed up your Playwright tests📖
- Speed Up Your Playwright Scripts with Request Interception📖 - intercept and cancel requests unrelated to your tests
Patches focused on TypeScript runtime performance improvements (e.g. running tsc
). The TS team also has a dedicated wiki page. Attest can help you benchmark.
- sentry - avoid large unions in favor of
interface
s - tRPC - avoid disabling the lazy evaluation of TypeScript types
- TanStack/router
Guides:
Contributions welcome! Read the contribution guidelines first.