Skip to main content

javascript-high-performance

Specialist in JavaScript Performance based on Hands-On JavaScript High Performance (Justin Scherer). Covers profiling and observability with DevTools tools (Chrome Performance/Memory/Rendering tabs, jsPerf, and correct benchmarking), immutability versus mutability trade-offs (Redux, Immutable.js, RAII, lazy evaluation, tail-call, and currying), modern vanilla JavaScript (Collections, Proxies, Typed Arrays, DOM APIs, Fetch/Promises), Svelte as a framework compiled to vanilla, Node.js without a DOM (fs, net, http, streams, and non-blocking I/O), message passing (pipes, sockets, TCP/UDP, HTTP/2, QUIC), data formats alternative to JSON (MessagePack, schema-based Protocol Buffers), Web Workers (dedicated/shared, transferrables, SharedArrayBuffer), Service Workers (offline cache), build and deploy with Rollup/CircleCI, and WebAssembly in the browser.

معلومات المصدر

المستودع
dandgabr/Coacus
آخر نشاط في المصدر
٢٨ سبتمبر ٢٠٢٦ في ١٤:٠٣
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٦
التفرعات
٥

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
7 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
javascript-high-performance
description
Specialist in JavaScript Performance based on Hands-On JavaScript High Performance (Justin Scherer). Covers profiling and observability with DevTools tools (Chrome Performance/Memory/Rendering tabs, jsPerf, and correct benchmarking), immutability versus mutability trade-offs (Redux, Immutable.js, RAII, lazy evaluation, tail-call, and currying), modern vanilla JavaScript (Collections, Proxies, Typed Arrays, DOM APIs, Fetch/Promises), Svelte as a framework compiled to vanilla, Node.js without a DOM (fs, net, http, streams, and non-blocking I/O), message passing (pipes, sockets, TCP/UDP, HTTP/2, QUIC), data formats alternative to JSON (MessagePack, schema-based Protocol Buffers), Web Workers (dedicated/shared, transferrables, SharedArrayBuffer), Service Workers (offline cache), build and deploy with Rollup/CircleCI, and WebAssembly in the browser.
# AI Skill: JavaScript High Performance This skill guides the AI to act as a specialist in **JavaScript performance**, covering everything from profiling with browser tools to code architecture (mutability, streams, workers, data formats, and WASM), based on *Hands-On JavaScript High Performance* (Justin Scherer, Packt). > 📖 **Canonical reference**: see [references/js-high-performance-book-guide.md](references/js-high-performance-book-guide.md) for the chapter-by-chapter summary of the book and [examples/performance-patterns.md](examples/performance-patterns.md) for the practical patterns. --- ## 🧭 General Guideline - **Measure before optimizing**: use the Performance tab of Chrome DevTools to locate the real bottleneck (scripting, rendering, painting) — never optimize based on assumptions. - **Everything is a trade-off**: immutability buys safety at the cost of speed/memory; native collections beat libraries; MessagePack may be neither smaller nor faster than native JSON. Make a conscious choice, not dogma. - **Prefer the runtime's primitives**: the engine (V8 etc.) optimizes built-ins better than libraries; avoid abstraction layers on hot paths. - **Keep the main thread free**: any processing > ~16 ms should be offloaded to Workers, streams, or WASM. --- ## 🔍 1. Profiling and Observability ### Chrome DevTools Tabs - **Performance**: runtime timeline recording (Scripting/Rendering/Painting, call stack flame chart, event log). Use it to find long-running functions, forced reflows, and GC pauses. - **Memory**: heap snapshots (comparison between snapshots to detect memory leaks — objects retained between captures), allocation instrumentation, and allocation timeline. - **Rendering**: FPS meter and paint flashing to detect excessive layouts/paints in real time. - Other engines: Safari (Web Inspector with Timeline), Firefox (Performance tools), and Edge (a Chromium fork) — different engines optimize differently, so validate across multiple browsers. ### Correct Benchmarking (jsPerf and the like) - Beware of **engine optimizations** that distort results (dead code elimination) — consume the results of the test functions. - Compare across **multiple browsers/engines**; no single-engine result is definitive. - Remove stray code from the test cases — any extra work skews the measurements. --- ## ⚖️ 2. Immutability versus Mutability - **Immutability** (Redux, Immutable.js) brings predictability, undo/redo, and cheap change detection (same reference = same data), but in high-performance applications you pay for it with increased time and memory: every change copies structures. - **Immutable.js** (List, Map, Set with structural tries) yields cleaner code and a functional architecture, but for large datasets native operations (`for` loops, arrays, mutable objects) are faster and less memory hungry. - **Hybrid strategy**: immutability in the state/UI layer (a reference change triggers re-render), disciplined mutability on computational hot paths (parsers, data transformations, in-memory joins). - **Safe mutable writing**: encapsulate mutation in small modules (the RAII / scope-bound resource management pattern — release/close resources in the same scope that created them, inspired by C++/Rust); avoid mutating objects shared across modules. ### Functional Techniques with a Conscious Cost - **Lazy evaluation**: generate collections on demand (generators/iterators) instead of materializing giant arrays. - **Tail recursion**: prefer turning recursion into iteration (loops) — engines do not guarantee TCO, and stack overflow is a real risk. - **Currying**: powerful for composition, but it creates closures and intermediate functions — avoid it in extremely high-frequency code. --- ## 🌐 2. Modern Vanilla JavaScript - **Block-scoped let/const**, arrow functions, and modules — modern code is also code the engine optimizes predictably. - **Collections**: `Map`/`Set`/`WeakMap`/`WeakSet` — `WeakMap`/`WeakSet` allow key GC (metadata without leaks); `Map` beats objects as a dictionary for dynamic keys. - **Typed Arrays** (`Int32Array`, `Float64Array`, `ArrayBuffer`): contiguous, typed memory, essential for large numeric data, binary data, and transfer with Workers. - **Proxies and getters/setters**: enable reactivity (the basis of frameworks such as Svelte/Vue), but every access intercepts — do not use them in hot loops. - **Efficient DOM**: centralized `querySelector`/`querySelectorAll`; **Document Fragments** for batch insertions (a single reflow); Shadow DOM and Web Components for encapsulation; `<template>` for cheap markup cloning. - **Fetch + Promises**: Promises are lazy-friendly; `AbortController` support to cancel requests (avoids unnecessary network and parsing work). --- ## 🧩 3. Svelte and the "Compiled to Vanilla" Paradigm - Svelte compiles components into imperative vanilla JS — no virtual DOM, no runtime in production; each state mutation generates minimal, precise DOM update code. - The performance lesson: **less runtime = more speed**. When a framework library is the bottleneck, consider alternatives that push work to build time (compilers, aggressive tree shaking). - Practical applications (Todo, weather app) show that small components with local state avoid cascading re-renders. --- ## 🟩 4. Node.js without a DOM - `package.json` as the configuration hub (scripts, dependencies, type module). - **Native modules**: `fs` (file I/O), `net` (TCP sockets), `http` (server/services) — no libraries for the basics; the standard lib is the fastest. - **Streams and non-blocking I/O**: never read large files entirely into memory — a pipeline with Readable/Writable/Duplex/Transform streams processes in chunks, keeping memory constant and the event loop free. - **Custom streams**: implement `Readable`/`Writable`/`Transform` (with `highWaterMark` for backpressure) and use generators to simplify pipelines. --- ## 📬 5. Message Passing and Protocols (Node.js) - Local/process communication: `net` with Unix domain sockets / TCP, IPC between processes (cluster). - `cluster` module: multiply processes per CPU core to saturate the hardware (Node is single-threaded per process). - **TCP/UDP**: TCP for ordering and reliability; UDP for minimal latency without a handshake. - **HTTP/2**: stream multiplexing on one connection (eliminates HTTP/1.1 head-of-line blocking), header compression. - **HTTP/3/QUIC**: UDP-based, 0-RTT handshake, no TCP head-of-line blocking — the future direction of web transport. --- ## 📦 6. Data Formats - **JSON**: ubiquitous, but verbose and with encode/decode cost on large payloads. - **Schema-less formats**: JSON, XML — self-describing, larger on the wire. - **MessagePack** (e.g., the `what-the-pack` lib): compact binary with buffer pre-allocation; it may be neither smaller nor faster than native `JSON.parse`/`stringify` — always measure. - **Protocol Buffers (proto3)**: a schema shared up front, very compact and fast encoding — the standard for enterprise systems; numeric field IDs make encoding and indexing cheap. - **Custom format**: for extreme cases, a custom binary encoder/decoder (e.g., schema in front of the data) gives the maximum control over size and speed. --- ## 👷 7. Web Workers and Browser Parallelism - **Dedicated Workers**: move heavy work (parsing, transformation, data joins, computation) off the main thread; communicate via `postMessage`. - **Structured clone has a real cost**: sending thousands of objects serializes/deserializes everything — the book's example: 100,000 objects took from 800 ms to 1.7 s and 80–100 MB of heap. Use `Date.now()` + Profiler to visualize the cost. - **Transferrables**: send the `ArrayBuffer` (`postMessage(view, [view.buffer])`) — **zero copy**; the sender loses access, the receiver gains it. For large binary data this is orders of magnitude faster. - **Shared Workers**: one worker shared across multiple pages/tabs (e.g., a shared in-memory cache, a single connection). - **SharedArrayBuffer + Atomics**: true shared memory with synchronization; requires correct COOP/COEP. --- ## 🔁 8. Service Workers and Caching - ServiceWorker lifecycle: install → waiting → activate; intercept requests with the `fetch` event. - **Page/template caching for offline** (Cache Storage API), enabling PWA behavior. - **Save requests for later**: queue offline mutations and replay them when the network returns (a queue pattern in the SW). - A well-done cache is the cheapest optimization: zero network and processing cost on subsequent requests (TTL/LRU to cap growth, as in the static server chapter). --- ## 🏗️ 9. Build, Deploy, and CI/CD - **Rollup**: a bundler optimized for ES modules (ESM) — effective tree shaking, smaller bundles; use it to distribute the application (server + assets) in a single distributable. - Integrate the build into npm scripts (`npm run build`) and the **CircleCI** pipeline (build → tests → security checks → deploy). - Fewer bytes = less main-thread parsing/compiling; tree shaking is a first-order optimization. --- ## ⚙️ 10. WebAssembly in the Browser - For hot paths that even optimized JS cannot satisfy (corrective code generators such as Hamming, heavy parsing, numeric math). - Direct authoring of WAT modules, compiling **C/C++ for the browser**, and shared memory between WASM and JavaScript (Linear Memory over `WebAssembly.Memory`). - A real case from the book: **SQLite compiled to WASM** running in the browser — a complete client-side database. - Sandbox: WASM code does not leak memory across modules; load it via a static server with the MIME type `application/wasm`. --- ## 🧪 Recommended Code Patterns ### Native loop on a hot path (vs. abstraction) ```javascript // ❌ chain of high-order functions on large data: multiple intermediate arrays const positive = data.filter((x) => x > 0).map((x) => x * 2); // ✅ a single loop, no intermediate allocations const result = new Array(data.length); let count = 0; for (let i = 0; i < data.length; i++) { if (data[i] > 0) { result[count++] = data[i] * 2; } } ``` ### Binary Transfer to Workers (zero-copy) ```javascript const view = new Int32Array(1_000_000); // ... populate ... worker.postMessage(view, [view.buffer]); // transfers, does not copy // ⚠️ view is now neutered/detached on the sender ``` ### Fragment for batch DOM insertion ```javascript const frag = document.createDocumentFragment(); for (const item of items) { frag.appendChild(createRow(item)); } container.appendChild(frag); // a single reflow/layout ``` ### Simple LRU/TTL Cache ```javascript const cache = new Map(); const TTL = 5 * 60 * 1000; function getCached(key) { const hit = cache.get(key); if (!hit) return null; if (Date.now() - hit.ts > TTL) { cache.delete(key); // evita crescimento infinito return null; } return hit.value; } ``` --- ## ⚠️ Pitfalls - **Non-deterministic GC**: massive allocation on hot paths (every user event generating objects) causes GC pauses that are hard to predict; reduce the allocation rate, do not trust that "the GC will handle it". - **Layout thrashing / forced synchronous layout**: interleaving reads and writes of layout properties (`offsetHeight` ↔ `style.height`) forces a reflow on every iteration — separate reads from writes (or use requestAnimationFrame batching). - **postMessage with giant objects**: structured clone duplicates memory and freezes the thread — transfer `ArrayBuffer`s or use `SharedArrayBuffer`. - **Misleading benchmarks**: a single engine, eliminated dead code, or stray code skew the results; test across several browsers and make sure to consume the results. - **Runtime dependencies**: immutability/functional helper libraries on large datasets cost more than native — "everything is a trade-off". --- ## 🔗 Integration with Other Skills - [latency-engineering](../../engineering/practices/latency-engineering/SKILL.md): latency laws, tail latency, and elimination of unnecessary work applied to the web. - [code-optimizer](../../roles/code-optimizer/SKILL.md): the algorithm → structure → runtime → parallelism hierarchy applied to JS applications. - [webassembly](../webassembly/SKILL.md): Wasm as the ultimate destination for hot paths (Emscripten, wasm-pack, SharedArrayBuffer/Atomics). - [framework-react](../../frameworks/framework-react/SKILL.md): state immutability, memoization, and re-renders in the React ecosystem. - [framework-vue](../../frameworks/framework-vue/SKILL.md): reactivity based on getters/setters and Proxies (the same fundamentals as the vanilla chapter). - [frontend-developer](../../roles/frontend-developer/SKILL.md): integrating performance optimizations into the UI construction cycle.
عرض على GitHub