[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7EWCGCWRCCDBB3GD750RPRM":3,"skill-same:01M7EWCGCWRCCDBB3GD750RPRM":45},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":21,"frontMatter":22,"refName":23,"commitSha":24,"skillDirectory":25,"forksCount":26,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":29,"ownerDescription":6,"updatedAt":30,"install":31,"resources":44},"01M7EWCGCWRCCDBB3GD750RPRM","ams-web-workers-pro",null,"TanNhatCMS\u002Fjarvis","TanNhatCMS","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F113796420?v=4","01M753MV17KG5CD3152G3WQEQY","KietNT","01M7EKEDYVYQ6PWVJJMZ911VMX",0,"MIT","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Fams-web-workers-pro\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: web-workers-pro\ndescription: Offload work with Web Workers: dedicated\u002Fshared workers, messaging, transferables, and worker-based architectures. Use to keep the main thread responsive.\ncategory: web-development\n---\n\n# Web Workers Pro\n\nA practical guide to Web Workers: moving heavy computation off the main thread — dedicated and shared workers, message passing, transferable objects, and the architectures (comlink, worker pools) that make workers pleasant.\n\n## Overview\n\nJavaScript's main thread does everything: rendering, input, your code. A long task (>50ms) blocks interaction — jank. **Web Workers** run scripts in background threads with no DOM access, communicating via message passing. Use them for: parsing\u002Fprocessing large data, image\u002Fvideo manipulation, encryption, search indexing, heavy calculations. If the main thread is busy, workers are the answer.\n\n## When to use\n\n- Heavy data processing (CSV\u002FJSON parsing, transformations, aggregations).\n- Image\u002Faudio\u002Fvideo processing client-side.\n- Crypto, compression, WASM-adjacent compute.\n- Search indexes (Lunr\u002FFlexSearch) over large corpora.\n- Anything profiling shows blocking the main thread.\n\n## Core concepts\n\n- **Dedicated workers.** `new Worker('worker.js')` — one worker per instance, dies with the page. The common case.\n- **Message passing.** `postMessage` \u002F `onmessage` — structured clone serialization (most types; functions\u002FDOM nodes not clonable). Design message protocols: `{ type, payload }`.\n- **Transferables.** `postMessage(buf, [buf])` — *moves* ArrayBuffers instead of copying (zero-copy). Essential for large binary data; the sender loses access.\n- **Shared workers.** One worker shared across tabs\u002Fframes of an origin — for cross-tab coordination, shared caches, single websocket multiplexed to tabs.\n- **Service workers vs web workers.** Service workers = network proxy + offline (see service-worker-pro). Web workers = computation. Different lifecycles, different purposes.\n- **Module workers.** `new Worker('w.js', { type: 'module' })` — ES imports inside workers. Needs server MIME + CORS correctness.\n- **Comlink.** Library making workers feel like async local objects (`await api.expensiveFn(x)`) — removes message-boilerplate for RPC-style usage.\n- **Worker pools.** For parallelizable chunks: N workers (usually `navigator.hardwareConcurrency`), task queue, distribute — near-linear speedup for CPU-bound work.\n\n## Practical workflow\n\n**1. Basic worker.**\n```js\n\u002F\u002F main.js\nconst worker = new Worker(new URL('.\u002Fcompute.worker.js', import.meta.url), { type: 'module' });\nworker.postMessage({ type: 'process', rows });\nworker.onmessage = (e) => { if (e.data.type === 'done') renderResults(e.data.result); };\nworker.onerror = (e) => showError('Processing failed');\n\n\u002F\u002F compute.worker.js\nself.onmessage = async (e) => {\n  const result = heavyTransform(e.data.rows);\n  self.postMessage({ type: 'done', result });\n};\n```\n\n**2. Zero-copy for big buffers.**\n```js\n\u002F\u002F transfer, don't copy, large ArrayBuffers\nworker.postMessage({ type: 'image', buffer }, [buffer]);\n```\n\n**3. Comlink for RPC style.**\n```js\n\u002F\u002F import * as Comlink from 'comlink';\n\u002F\u002F const api = Comlink.wrap(worker);\n\u002F\u002F const result = await api.expensiveFn(data);\n```\n\n**4. Bundler integration.** Vite\u002Fwebpack support `new Worker(new URL('.\u002Fw.js', import.meta.url))` natively — the worker gets bundled. Don't hand-serve worker files unless you must.\n\n**5. Fallback.** If workers unavailable (rare) or the task is small, run inline. Feature-detect; keep the compute function importable in both contexts.\n\n## Common pitfalls\n\n- **No DOM access.** Workers can't touch the DOM — a frequent surprise. Compute in worker, render on main; pass data, not elements.\n- **Serialization overhead.** Structured cloning large objects costs time — for huge payloads use transferables, or keep data in the worker and query it.\n- **Chatty messaging.** Thousands of tiny messages = overhead dominating. Batch: fewer, larger messages.\n- **Worker startup cost.** Spawning a worker takes ~10–50ms + script parse. Reuse workers (pool) instead of spawning per task.\n- **Uncaught worker errors.** `worker.onerror` — without it, failures are silent. Always handle; surface to UI.\n- **CORS\u002FMIME issues.** Module workers need correct `Content-Type` and same-origin\u002FCORS. Bundler-managed workers avoid this; hand-rolled setups hit it.\n- **Shared worker complexity.** Cross-tab coordination is powerful but subtle (ports, lifecycle). Only reach for shared workers when tabs genuinely must coordinate.\n- **Over-threading.** More workers than cores for non-parallelizable work = overhead. Pool size ≈ `hardwareConcurrency`; profile.\n- **Debugging difficulty.** Worker breakpoints work in DevTools (separate thread context) — learn where to find them instead of `console.log`-only debugging.\n- **Leaving workers running.** Terminate (`worker.terminate()`) when done for one-shot work; long-lived pools get explicit shutdown on page hide\u002Funload where appropriate.\n","# Web Workers Pro\n\nA practical guide to Web Workers: moving heavy computation off the main thread — dedicated and shared workers, message passing, transferable objects, and the architectures (comlink, worker pools) that make workers pleasant.\n\n## Overview\n\nJavaScript's main thread does everything: rendering, input, your code. A long task (>50ms) blocks interaction — jank. **Web Workers** run scripts in background threads with no DOM access, communicating via message passing. Use them for: parsing\u002Fprocessing large data, image\u002Fvideo manipulation, encryption, search indexing, heavy calculations. If the main thread is busy, workers are the answer.\n\n## When to use\n\n- Heavy data processing (CSV\u002FJSON parsing, transformations, aggregations).\n- Image\u002Faudio\u002Fvideo processing client-side.\n- Crypto, compression, WASM-adjacent compute.\n- Search indexes (Lunr\u002FFlexSearch) over large corpora.\n- Anything profiling shows blocking the main thread.\n\n## Core concepts\n\n- **Dedicated workers.** `new Worker('worker.js')` — one worker per instance, dies with the page. The common case.\n- **Message passing.** `postMessage` \u002F `onmessage` — structured clone serialization (most types; functions\u002FDOM nodes not clonable). Design message protocols: `{ type, payload }`.\n- **Transferables.** `postMessage(buf, [buf])` — *moves* ArrayBuffers instead of copying (zero-copy). Essential for large binary data; the sender loses access.\n- **Shared workers.** One worker shared across tabs\u002Fframes of an origin — for cross-tab coordination, shared caches, single websocket multiplexed to tabs.\n- **Service workers vs web workers.** Service workers = network proxy + offline (see service-worker-pro). Web workers = computation. Different lifecycles, different purposes.\n- **Module workers.** `new Worker('w.js', { type: 'module' })` — ES imports inside workers. Needs server MIME + CORS correctness.\n- **Comlink.** Library making workers feel like async local objects (`await api.expensiveFn(x)`) — removes message-boilerplate for RPC-style usage.\n- **Worker pools.** For parallelizable chunks: N workers (usually `navigator.hardwareConcurrency`), task queue, distribute — near-linear speedup for CPU-bound work.\n\n## Practical workflow\n\n**1. Basic worker.**\n```js\n\u002F\u002F main.js\nconst worker = new Worker(new URL('.\u002Fcompute.worker.js', import.meta.url), { type: 'module' });\nworker.postMessage({ type: 'process', rows });\nworker.onmessage = (e) => { if (e.data.type === 'done') renderResults(e.data.result); };\nworker.onerror = (e) => showError('Processing failed');\n\n\u002F\u002F compute.worker.js\nself.onmessage = async (e) => {\n  const result = heavyTransform(e.data.rows);\n  self.postMessage({ type: 'done', result });\n};\n```\n\n**2. Zero-copy for big buffers.**\n```js\n\u002F\u002F transfer, don't copy, large ArrayBuffers\nworker.postMessage({ type: 'image', buffer }, [buffer]);\n```\n\n**3. Comlink for RPC style.**\n```js\n\u002F\u002F import * as Comlink from 'comlink';\n\u002F\u002F const api = Comlink.wrap(worker);\n\u002F\u002F const result = await api.expensiveFn(data);\n```\n\n**4. Bundler integration.** Vite\u002Fwebpack support `new Worker(new URL('.\u002Fw.js', import.meta.url))` natively — the worker gets bundled. Don't hand-serve worker files unless you must.\n\n**5. Fallback.** If workers unavailable (rare) or the task is small, run inline. Feature-detect; keep the compute function importable in both contexts.\n\n## Common pitfalls\n\n- **No DOM access.** Workers can't touch the DOM — a frequent surprise. Compute in worker, render on main; pass data, not elements.\n- **Serialization overhead.** Structured cloning large objects costs time — for huge payloads use transferables, or keep data in the worker and query it.\n- **Chatty messaging.** Thousands of tiny messages = overhead dominating. Batch: fewer, larger messages.\n- **Worker startup cost.** Spawning a worker takes ~10–50ms + script parse. Reuse workers (pool) instead of spawning per task.\n- **Uncaught worker errors.** `worker.onerror` — without it, failures are silent. Always handle; surface to UI.\n- **CORS\u002FMIME issues.** Module workers need correct `Content-Type` and same-origin\u002FCORS. Bundler-managed workers avoid this; hand-rolled setups hit it.\n- **Shared worker complexity.** Cross-tab coordination is powerful but subtle (ports, lifecycle). Only reach for shared workers when tabs genuinely must coordinate.\n- **Over-threading.** More workers than cores for non-parallelizable work = overhead. Pool size ≈ `hardwareConcurrency`; profile.\n- **Debugging difficulty.** Worker breakpoints work in DevTools (separate thread context) — learn where to find them instead of `console.log`-only debugging.\n- **Leaving workers running.** Terminate (`worker.terminate()`) when done for one-shot work; long-lived pools get explicit shutdown on page hide\u002Funload where appropriate.\n",{},"main","af388a77c2fe5e0b4fd879cca4300a0ffa9a6579","skills\u002Fams-web-workers-pro",1,"https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis","https:\u002F\u002Fgithub.com\u002FTanNhatCMS","https:\u002F\u002Fmrkiet.name.vn","2026-11-07 14:23:08",{"source":7,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add TanNhatCMS\u002Fjarvis --skill ams-web-workers-pro",{"tool":37,"command":38},"bunx","bunx skills add TanNhatCMS\u002Fjarvis --skill ams-web-workers-pro",{"tool":40,"command":41},"pnpm","pnpm dlx skills add TanNhatCMS\u002Fjarvis --skill ams-web-workers-pro","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Fams-web-workers-pro\u002FSKILL.md",true,[],[46,53,61,68,75,82],{"skillNo":47,"name":48,"nameZh":6,"description":49,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":50,"categories":51,"keywords":52,"publishedAt":18},"01M7EWYJR0J8DARY7E59Z6Y9MV","web-scrape","Turn web pages into LLM-ready markdown via the Firecrawl API (renders JS, anti-bot handling). Use when browser_open\u002Ffetch fails on JS-heavy pages, or when you need clean markdown\u002Fstructured extraction from a site. Requires FIRECRAWL_API_KEY.","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Fweb-scrape\u002FSKILL.md",[],[],{"skillNo":54,"name":55,"nameZh":6,"description":56,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":57,"sourceHtmlUrl":58,"categories":59,"keywords":60,"publishedAt":18},"01M7EWYBN5P6F2AJG3FR24T9BP","design-taste-frontend","tasteskill v2, the anti-slop frontend skill. Art direction for websites, distilled from a study of 247 curated gallery sites (One Page Love, Awwwards Sites of the Day). Deals researched directions (idea, composition, type, palette, photographs, section blueprints) from a library, enforces a strict no-slop house style with a real-browser inspector, and runs a look-and-fix loop on screenshots. Use this whenever you build, design, redesign, restyle, polish or review a landing page, marketing site, portfolio, product page, one-pager, hero or any public-facing web page, in any stack (HTML\u002FCSS, React, Next.js, Vue, Svelte, Astro, Tailwind) — also when the user says a page looks generic, templated, \"AI-made\", sloppy, or asks to make it look designed, premium, award-level or less like every other site. Not for dashboards or app screens.","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Ftaste-design\u002FLICENSE","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Ftaste-design\u002FSKILL.md",[],[],{"skillNo":62,"name":63,"nameZh":6,"description":64,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":65,"categories":66,"keywords":67,"publishedAt":18},"01M7EWY8FQFNQ2GB7NZZWGSSDX","test-driven-development","Use when implementing any feature or bugfix, before writing implementation code","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-tdd\u002FSKILL.md",[],[],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":74,"publishedAt":18},"01M7EWY5SHBFRH1HDHVWM9K7TV","systematic-debugging","Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-debugging\u002FSKILL.md",[],[],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":18},"01M7EWY3NM0Z0JAKS7HDZ24K66","requesting-code-review","Use when completing tasks, implementing major features, or before merging to verify work meets requirements","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-code-review\u002FSKILL.md",[],[],{"skillNo":83,"name":84,"nameZh":6,"description":85,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":86,"categories":87,"keywords":88,"publishedAt":18},"01M7EWY0WRMWX4M9ZFY0WKC593","brainstorming","You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or planning anything new, in software or out of it (a talk, a business, a renovation).","https:\u002F\u002Fgithub.com\u002FTanNhatCMS\u002Fjarvis\u002Fblob\u002Fmain\u002Fskills\u002Fsuperpowers-brainstorming\u002FSKILL.md",[],[]]