vibes-plug 1.0.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/.claude/rules/vibes-plug-core.md +32 -0
  2. package/.cursor/rules/vibes-plug-core.mdc +51 -0
  3. package/.cursorrules +42 -0
  4. package/AGENTS.md +96 -0
  5. package/BLUEPRINT.md +309 -125
  6. package/CHANGELOG.md +183 -1
  7. package/CLAUDE.md +70 -0
  8. package/LICENSE +1 -1
  9. package/README.md +641 -263
  10. package/index.js +19 -0
  11. package/package.json +61 -25
  12. package/plugin.json +24 -7
  13. package/scripts/generate_swarm_gif.py +295 -0
  14. package/scripts/install.js +201 -0
  15. package/skills/accessibility-testing-expert/SKILL.md +116 -0
  16. package/skills/ai-cost-token-optimizer/SKILL.md +82 -0
  17. package/skills/ai-evals-benchmark-expert/SKILL.md +188 -0
  18. package/skills/ai-llm-integration-expert/SKILL.md +147 -122
  19. package/skills/ai-media-generation-expert/SKILL.md +172 -0
  20. package/skills/ai-prompt-engineering-expert/SKILL.md +84 -0
  21. package/skills/angular-expert/SKILL.md +148 -0
  22. package/skills/api-design-expert/SKILL.md +316 -309
  23. package/skills/api-gateway-proxy-expert/SKILL.md +81 -0
  24. package/skills/app-analyzer-optimizer/SKILL.md +195 -188
  25. package/skills/apple-ecosystem-expert/SKILL.md +145 -0
  26. package/skills/{asisten_ramah → asisten-ramah}/SKILL.md +7 -1
  27. package/skills/astro-framework-expert/SKILL.md +200 -0
  28. package/skills/async-queue-temporal-expert/SKILL.md +240 -0
  29. package/skills/authentication-identity-expert/SKILL.md +279 -45
  30. package/skills/auto-doc-updater/SKILL.md +219 -203
  31. package/skills/autonomous-chaos-monkey/SKILL.md +63 -0
  32. package/skills/autonomous-red-teamer/SKILL.md +203 -0
  33. package/skills/autonomous-tdd-debugger/SKILL.md +71 -0
  34. package/skills/background-jobs-queue-expert/SKILL.md +235 -0
  35. package/skills/biome-linter-formatter-expert/SKILL.md +89 -0
  36. package/skills/blockchain-web3-expert/SKILL.md +115 -0
  37. package/skills/bootstrap-to-modern/SKILL.md +93 -86
  38. package/skills/brainstorming/SKILL.md +381 -353
  39. package/skills/browser-automation-expert/SKILL.md +222 -0
  40. package/skills/bun-runtime-expert/SKILL.md +7 -1
  41. package/skills/chatbot-messaging-expert/SKILL.md +114 -0
  42. package/skills/ci-cd-devops-architect/SKILL.md +81 -45
  43. package/skills/cloud-hosting-expert/SKILL.md +249 -243
  44. package/skills/coderabbit/SKILL.md +197 -191
  45. package/skills/compliance-gdpr-privacy-expert/SKILL.md +85 -0
  46. package/skills/cron-scheduler-expert/SKILL.md +304 -0
  47. package/skills/data-pipeline-etl-expert/SKILL.md +84 -0
  48. package/skills/data-telemetry-expert/SKILL.md +218 -212
  49. package/skills/data-visualization-expert/SKILL.md +154 -0
  50. package/skills/database-migration-versioning-expert/SKILL.md +90 -0
  51. package/skills/database-orm-expert/SKILL.md +303 -293
  52. package/skills/dependency-upgrade-migrator/SKILL.md +301 -0
  53. package/skills/design-system-architect/SKILL.md +278 -242
  54. package/skills/desktop-electron-expert/SKILL.md +128 -0
  55. package/skills/documentation-site-expert/SKILL.md +59 -0
  56. package/skills/doku-mcp-server/SKILL.md +257 -0
  57. package/skills/doku-payment-gateway/SKILL.md +233 -0
  58. package/skills/domain-driven-design-expert/SKILL.md +82 -0
  59. package/skills/e2e-testing-expert/SKILL.md +320 -314
  60. package/skills/ecommerce-expert/SKILL.md +87 -0
  61. package/skills/edge-serverless-db-expert/SKILL.md +99 -0
  62. package/skills/email-notification-expert/SKILL.md +368 -0
  63. package/skills/error-resilience-expert/SKILL.md +486 -0
  64. package/skills/event-driven-architect/SKILL.md +86 -80
  65. package/skills/feature-flag-analytics-expert/SKILL.md +66 -0
  66. package/skills/file-upload-media-expert/SKILL.md +437 -0
  67. package/skills/firebase-security-expert/SKILL.md +7 -1
  68. package/skills/form-validation-expert/SKILL.md +407 -0
  69. package/skills/fullstack-expert/SKILL.md +260 -201
  70. package/skills/fullstack-expert/references/api_design_guide.md +466 -466
  71. package/skills/fullstack-expert/references/multi_language_backend.md +528 -528
  72. package/skills/fullstack-expert/scripts/api_contract_validator.py +253 -253
  73. package/skills/fullstack-expert/scripts/architecture_analyzer.py +326 -326
  74. package/skills/gemini-agent-booster/SKILL.md +142 -104
  75. package/skills/geospatial-maps-expert/SKILL.md +80 -0
  76. package/skills/global-a11y-i18n-expert/SKILL.md +86 -80
  77. package/skills/glsl-shader-expert/SKILL.md +107 -0
  78. package/skills/go-programming-expert/SKILL.md +300 -294
  79. package/skills/graph-rag-knowledge-expert/SKILL.md +159 -0
  80. package/skills/graphql-apollo-expert/SKILL.md +114 -0
  81. package/skills/headless-cms-expert/SKILL.md +181 -0
  82. package/skills/hig/SKILL.md +193 -187
  83. package/skills/js-backend-expert/SKILL.md +218 -191
  84. package/skills/legacy-code-translator/SKILL.md +71 -0
  85. package/skills/local-slm-edge-ai-expert/SKILL.md +167 -0
  86. package/skills/logging-error-tracking-expert/SKILL.md +344 -0
  87. package/skills/mcp-client-orchestrator/SKILL.md +76 -0
  88. package/skills/mcp-server-architect/SKILL.md +226 -126
  89. package/skills/micro-frontend-architect/SKILL.md +112 -0
  90. package/skills/mobile-expo-expert/SKILL.md +191 -185
  91. package/skills/mobile-push-notification-expert/SKILL.md +71 -0
  92. package/skills/modern-css-native-expert/SKILL.md +189 -0
  93. package/skills/monday-design-aesthetic/SKILL.md +72 -66
  94. package/skills/monorepo-architect/SKILL.md +232 -226
  95. package/skills/mpa-orchestrator/SKILL.md +120 -101
  96. package/skills/multi-agent-orchestration/SKILL.md +173 -153
  97. package/skills/multiple-entry-points/SKILL.md +91 -55
  98. package/skills/mvc-expert/SKILL.md +237 -231
  99. package/skills/n8n-automation-expert/SKILL.md +89 -0
  100. package/skills/nextjs-app-router-expert/SKILL.md +148 -0
  101. package/skills/openapi-swagger-codegen-expert/SKILL.md +67 -0
  102. package/skills/payment-gateway-expert/SKILL.md +129 -45
  103. package/skills/pdf-document-generation-expert/SKILL.md +91 -0
  104. package/skills/performance-web-vitals/SKILL.md +337 -331
  105. package/skills/post-quantum-crypto-migrator/SKILL.md +57 -0
  106. package/skills/prd-architect/SKILL.md +206 -190
  107. package/skills/proactive-background-watcher/SKILL.md +68 -0
  108. package/skills/production-ready-hardener/PRODUCTION_READINESS_REPORT.md +67 -0
  109. package/skills/production-ready-hardener/SKILL.md +461 -468
  110. package/skills/production-ready-hardener/references/production_checklist.md +161 -161
  111. package/skills/production-ready-hardener/scripts/production_readiness_scanner.py +881 -875
  112. package/skills/project-context-mapper/SKILL.md +85 -0
  113. package/skills/pwa-offline-first-expert/SKILL.md +185 -0
  114. package/skills/python-programming-expert/SKILL.md +407 -270
  115. package/skills/rate-limit-abuse-prevention/SKILL.md +377 -0
  116. package/skills/realtime-collaboration-expert/SKILL.md +99 -45
  117. package/skills/rich-text-editor-expert/SKILL.md +177 -0
  118. package/skills/rust-programming-expert/SKILL.md +240 -234
  119. package/skills/saas-billing/SKILL.md +382 -376
  120. package/skills/saas-multi-tenant/SKILL.md +256 -236
  121. package/skills/saas-mvp-launcher/SKILL.md +30 -1
  122. package/skills/saas-transformer/SKILL.md +499 -445
  123. package/skills/saas-transformer/references/billing_integration_guide.md +401 -401
  124. package/skills/saas-transformer/references/feature_gating_patterns.md +137 -137
  125. package/skills/saas-transformer/references/saas_transformation_checklist.md +121 -121
  126. package/skills/saas-transformer/scripts/saas_transformation_scanner.py +39 -29
  127. package/skills/scalability-clean-code/SKILL.md +234 -228
  128. package/skills/search-engine-expert/SKILL.md +89 -0
  129. package/skills/secure-fuzz-testing/SKILL.md +7 -1
  130. package/skills/self-evolving-memory-graph/SKILL.md +91 -0
  131. package/skills/self-healing-cloud-orchestrator/SKILL.md +57 -0
  132. package/skills/senior-frontend/SKILL.md +85 -105
  133. package/skills/seo/SKILL.md +258 -224
  134. package/skills/session-context-loader/SKILL.md +83 -0
  135. package/skills/session-handoff-resume/SKILL.md +163 -157
  136. package/skills/{skill_baru → skill-baru}/SKILL.md +177 -146
  137. package/skills/solidjs-expert/SKILL.md +80 -0
  138. package/skills/spa-orchestrator/SKILL.md +306 -287
  139. package/skills/sse-websocket-streaming-expert/SKILL.md +93 -0
  140. package/skills/state-management-expert/SKILL.md +277 -271
  141. package/skills/supabase-migration/SKILL.md +47 -1
  142. package/skills/supabase-security-expert/SKILL.md +248 -242
  143. package/skills/svelte-sveltekit-expert/SKILL.md +91 -0
  144. package/skills/svg-animation-motion-expert/SKILL.md +115 -0
  145. package/skills/tailwind-expert/SKILL.md +139 -187
  146. package/skills/tanstack-query-expert/SKILL.md +204 -198
  147. package/skills/tauri-expert/SKILL.md +7 -1
  148. package/skills/token-saver/SKILL.md +118 -110
  149. package/skills/typescript-expert/SKILL.md +329 -278
  150. package/skills/ui-components-expert/SKILL.md +166 -63
  151. package/skills/ui-ux-pro-max/SKILL.md +221 -200
  152. package/skills/vector-db-rag-expert/SKILL.md +208 -0
  153. package/skills/vibe-code-gardener/SKILL.md +180 -172
  154. package/skills/visual-qa-vision-agent/SKILL.md +71 -0
  155. package/skills/voice-ai-realtime-agent/SKILL.md +202 -0
  156. package/skills/vue-frontend-expert/SKILL.md +132 -0
  157. package/skills/wasm-edge-computing-expert/SKILL.md +97 -0
  158. package/skills/web-3d-graphics-expert/SKILL.md +137 -0
  159. package/skills/web-game-engine-expert/SKILL.md +102 -0
  160. package/skills/web-scraper/SKILL.md +98 -146
  161. package/skills/website-design-cloner/SKILL.md +180 -0
  162. package/skills/webxr-ar-vr-expert/SKILL.md +123 -0
  163. package/skills/wordpress-headless-expert/SKILL.md +144 -0
  164. package/skills/zero-to-prod-orchestrator/SKILL.md +231 -180
  165. package/skills/zero-trust-secret-vault/SKILL.md +88 -0
  166. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  167. package/CONTRIBUTING.md +0 -199
  168. package/SECURITY.md +0 -21
  169. package/banner.png +0 -0
  170. package/skills/senior-fullstack/SKILL.md +0 -167
  171. package/skills/senior-fullstack/references/architecture_patterns.md +0 -160
  172. package/skills/senior-fullstack/references/development_workflows.md +0 -222
  173. package/skills/senior-fullstack/references/tech_stack_guide.md +0 -190
  174. package/skills/senior-fullstack/scripts/code_quality_analyzer.py +0 -114
  175. package/skills/senior-fullstack/scripts/fullstack_scaffolder.py +0 -114
  176. package/skills/senior-fullstack/scripts/project_scaffolder.py +0 -114
  177. package/skills/seo-aeo-landing-page-writer/SKILL.md +0 -97
  178. package/skills/seo-geo/SKILL.md +0 -188
  179. package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-310.pyc +0 -0
  180. package/skills/ui-ux-pro-max/scripts/__pycache__/core.cpython-312.pyc +0 -0
  181. package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-310.pyc +0 -0
  182. package/skills/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-312.pyc +0 -0
  183. package/skills/ui_ux_expert/SKILL.md +0 -114
@@ -1,332 +1,338 @@
1
- ---
2
- name: performance-web-vitals
3
- description: "Expert guide for Web Performance optimization: Core Web Vitals (LCP, INP, CLS), bundle analysis, image optimization, rendering strategies, and Lighthouse score improvement / Panduan ahli untuk optimasi performa web: Core Web Vitals (LCP, INP, CLS), analisis bundle, optimasi gambar, strategi rendering, dan peningkatan skor Lighthouse."
1
+ ---
2
+ name: performance-web-vitals
3
+ description: "Expert guide for Web Performance optimization: Core Web Vitals (LCP, INP, CLS), bundle analysis, image optimization, rendering strategies, and Lighthouse score improvement / Panduan ahli untuk optimasi performa web: Core Web Vitals (LCP, INP, CLS), analisis bundle, optimasi gambar, strategi rendering, dan peningkatan skor Lighthouse."
4
4
  author: "Roedy Rustam"
5
- ---
6
-
7
- # Web Performance & Core Web Vitals Expert
8
-
9
- [English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
10
-
11
- ---
12
-
13
- <a name="english"></a>
14
- ## English
15
-
16
- ### Description
17
- Expert guide for measuring, diagnosing, and optimizing web application performance with a focus on **Core Web Vitals** (LCP, INP, CLS), JavaScript bundle optimization, image and font loading strategies, rendering performance, and achieving high Lighthouse scores. Covers Next.js 15, React 19, and modern browser APIs.
18
-
19
- ### Trigger Conditions
20
- - Improving Lighthouse performance score below 90.
21
- - Diagnosing poor LCP, INP, or CLS metrics.
22
- - Reducing JavaScript bundle size or eliminating render-blocking resources.
23
- - Optimizing image loading, lazy loading, or font delivery.
24
- - Implementing React performance patterns (memo, useDeferredValue, Suspense).
25
- - Setting up Real User Monitoring (RUM) for Core Web Vitals.
26
- - Optimizing server response times (TTFB).
27
-
28
- ---
29
-
30
- ### Core Web Vitals Targets (2024+)
31
-
32
- | Metric | Good | Needs Improvement | Poor | Measures |
33
- |---|---|---|---|---|
34
- | **LCP** (Largest Contentful Paint) | ≤ 2.5s | 2.5–4.0s | > 4.0s | Loading performance |
35
- | **INP** (Interaction to Next Paint) | 200ms | 200–500ms | > 500ms | Interactivity (replaced FID) |
36
- | **CLS** (Cumulative Layout Shift) | ≤ 0.1 | 0.1–0.25 | > 0.25 | Visual stability |
37
- | **FCP** (First Contentful Paint) | ≤ 1.8s | 1.83.0s | > 3.0s | Perceived loading |
38
- | **TTFB** (Time to First Byte) | ≤ 800ms | 8001800ms | > 1800ms | Server responsiveness |
39
-
40
- ---
41
-
42
- ### LCP Optimization Strategies
43
-
44
- #### 1. Identify and Optimize the LCP Element
45
- ```typescript
46
- // Measure LCP with web-vitals library
47
- import { onLCP, onINP, onCLS } from 'web-vitals';
48
-
49
- onLCP((metric) => {
50
- console.log('LCP:', metric.value, 'element:', metric.attribution.lcpEntry?.element);
51
- // Send to analytics
52
- sendToAnalytics({ name: metric.name, value: metric.value });
53
- });
54
- ```
55
-
56
- #### 2. Preload LCP Image (Hero Image)
57
- ```html
58
- <!-- In <head> — preload the hero image before CSS blocks it -->
59
- <link rel="preload" as="image" href="/hero.webp"
60
- imagesrcset="/hero-480.webp 480w, /hero-800.webp 800w"
61
- imagesizes="(max-width: 600px) 480px, 800px"
62
- fetchpriority="high">
63
- ```
64
-
65
- #### 3. Next.js Image Component (LCP Hero)
66
- ```tsx
67
- import Image from 'next/image';
68
-
69
- // LCP image: priority=true + fill or explicit size
70
- <Image
71
- src="/hero.webp"
72
- alt="Hero banner"
73
- width={1200}
74
- height={600}
75
- priority // disables lazy loading, adds preload link
76
- fetchPriority="high"
77
- quality={85}
78
- sizes="(max-width: 768px) 100vw, 1200px"
79
- />
80
-
81
- // Below-the-fold images: lazy load (default)
82
- <Image
83
- src="/product.webp"
84
- alt="Product"
85
- width={400}
86
- height={300}
87
- // loading="lazy" is the default — no need to specify
88
- />
89
- ```
90
-
91
- ---
92
-
93
- ### INP Optimization Strategies
94
-
95
- #### 1. Break Up Long Tasks
96
- ```typescript
97
- // BAD: Long synchronous task blocks the main thread
98
- function processLargeList(items: Item[]) {
99
- return items.map(expensiveTransform); // blocks for 500ms
100
- }
101
-
102
- // GOOD: Yield control back to browser between chunks
103
- async function processLargeListAsync(items: Item[]) {
104
- const results: Result[] = [];
105
- for (let i = 0; i < items.length; i++) {
106
- results.push(expensiveTransform(items[i]));
107
- if (i % 50 === 0) await scheduler.yield(); // yield every 50 items
108
- }
109
- return results;
110
- }
111
- ```
112
-
113
- #### 2. React 19 — Concurrent Features for INP
114
- ```tsx
115
- import { useTransition, useDeferredValue, startTransition } from 'react';
116
-
117
- // Non-urgent state updates — mark as transitions
118
- function SearchResults() {
119
- const [query, setQuery] = useState('');
120
- const [isPending, startTransition] = useTransition();
121
- const deferredQuery = useDeferredValue(query);
122
-
123
- return (
124
- <>
125
- <input
126
- value={query}
127
- onChange={(e) => {
128
- setQuery(e.target.value); // urgent: update input immediately
129
- startTransition(() => {
130
- // non-urgent: defer expensive filtering
131
- });
132
- }}
133
- />
134
- {isPending && <Spinner />}
135
- {/* deferredQuery triggers re-render without blocking input */}
136
- <ResultsList query={deferredQuery} />
137
- </>
138
- );
139
- }
140
- ```
141
-
142
- #### 3. Virtualize Long Lists
143
- ```tsx
144
- // Use TanStack Virtual for large lists (1000+ items)
145
- import { useVirtualizer } from '@tanstack/react-virtual';
146
-
147
- function VirtualList({ items }: { items: Item[] }) {
148
- const parentRef = useRef<HTMLDivElement>(null);
149
- const virtualizer = useVirtualizer({
150
- count: items.length,
151
- getScrollElement: () => parentRef.current,
152
- estimateSize: () => 60, // estimated row height in px
153
- overscan: 5,
154
- });
155
-
156
- return (
157
- <div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
158
- <div style={{ height: virtualizer.getTotalSize() }}>
159
- {virtualizer.getVirtualItems().map((vItem) => (
160
- <div
161
- key={vItem.key}
162
- style={{ position: 'absolute', top: vItem.start, height: vItem.size }}
163
- >
164
- <ItemRow item={items[vItem.index]} />
165
- </div>
166
- ))}
167
- </div>
168
- </div>
169
- );
170
- }
171
- ```
172
-
173
- ---
174
-
175
- ### CLS Optimization Strategies
176
-
177
- ```css
178
- /* 1. Reserve space for images with aspect-ratio */
179
- img, video {
180
- width: 100%;
181
- height: auto;
182
- aspect-ratio: 16 / 9; /* prevents layout shift before load */
183
- }
184
-
185
- /* 2. Reserve space for dynamic content */
186
- .ad-container {
187
- min-height: 250px; /* reserve ad slot height */
188
- }
189
-
190
- /* 3. Use font-display: optional or swap */
191
- @font-face {
192
- font-family: 'Inter';
193
- src: url('/fonts/inter.woff2') format('woff2');
194
- font-display: optional; /* no invisible text, no layout shift */
195
- }
196
- ```
197
-
198
- ```tsx
199
- // 4. Avoid inserting content above existing content
200
- // BAD: inserting notification banner at top pushes content down
201
- setShowBanner(true); // causes CLS
202
-
203
- // GOOD: use position:fixed or reserve space at the top
204
- <div className="h-12">{showBanner && <Banner />}</div>
205
- ```
206
-
207
- ---
208
-
209
- ### Bundle Optimization
210
-
211
- #### Next.js Bundle Analysis
212
- ```bash
213
- # Analyze bundle composition
214
- ANALYZE=true npm run build
215
- # Or use @next/bundle-analyzer
216
- ```
217
-
218
- #### Code Splitting Patterns
219
- ```tsx
220
- import dynamic from 'next/dynamic';
221
-
222
- // Dynamic import — code splits automatically
223
- const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
224
- loading: () => <ChartSkeleton />,
225
- ssr: false, // disable SSR for client-only components
226
- });
227
-
228
- // Lazy load with React.lazy (non-Next.js)
229
- const Modal = React.lazy(() => import('./Modal'));
230
- ```
231
-
232
- #### Tree-shaking Checklist
233
- - Use named imports: `import { debounce } from 'lodash-es'` (not `import _ from 'lodash'`)
234
- - Set `"sideEffects": false` in `package.json` for libraries.
235
- - Avoid `import *` from large libraries.
236
- - Replace `moment.js` with `date-fns` or `dayjs`.
237
- - Use `sharp` for server-side image processing.
238
-
239
- ---
240
-
241
- ### React Performance Patterns
242
-
243
- ```tsx
244
- // memo skip re-render if props didn't change
245
- const ExpensiveList = memo(({ items }: { items: Item[] }) => (
246
- <ul>{items.map((i) => <li key={i.id}>{i.name}</li>)}</ul>
247
- ));
248
-
249
- // useCallback stable function reference for memo children
250
- const handleDelete = useCallback((id: string) => {
251
- setItems((prev) => prev.filter((i) => i.id !== id));
252
- }, []); // empty deps = stable reference
253
-
254
- // useMemo memoize expensive calculations
255
- const sortedItems = useMemo(
256
- () => [...items].sort((a, b) => a.name.localeCompare(b.name)),
257
- [items]
258
- );
259
- ```
260
-
261
- ---
262
-
263
- ### Performance Monitoring Setup
264
-
265
- ```typescript
266
- // report-vitals.ts send Core Web Vitals to analytics
267
- import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';
268
-
269
- function sendToAnalytics({ name, value, id, navigationType }: Metric) {
270
- // Send to PostHog, Google Analytics, or your own endpoint
271
- fetch('/api/analytics/vitals', {
272
- method: 'POST',
273
- body: JSON.stringify({ name, value: Math.round(value), id, navigationType }),
274
- keepalive: true, // ensures request completes even if page unloads
275
- });
276
- }
277
-
278
- onCLS(sendToAnalytics);
279
- onINP(sendToAnalytics);
280
- onLCP(sendToAnalytics);
281
- onFCP(sendToAnalytics);
282
- onTTFB(sendToAnalytics);
283
- ```
284
-
285
- ---
286
-
287
- ### Lighthouse Score Improvement Checklist
288
-
289
- - [ ] LCP image has `priority` or `fetchpriority="high"` + preload link.
290
- - [ ] All non-LCP images use `loading="lazy"`.
291
- - [ ] Fonts loaded with `font-display: optional` or preloaded with `rel="preload"`.
292
- - [ ] No render-blocking `<script>` tags without `defer` or `async`.
293
- - [ ] Bundle size < 200KB gzipped for initial JS.
294
- - [ ] Images served in WebP/AVIF format with `srcset`.
295
- - [ ] Server response time (TTFB) < 600ms use CDN edge caching.
296
- - [ ] Long tasks (> 50ms) are broken up or deferred.
297
- - [ ] Virtual lists used for > 100 items.
298
- - [ ] Unused CSS removed (PurgeCSS / Tailwind purge).
299
- - [ ] HTTP/2 or HTTP/3 enabled on server.
300
- - [ ] Resource hints: `dns-prefetch`, `preconnect` for third-party origins.
301
-
302
- ---
303
-
304
- <a name="bahasa-indonesia"></a>
305
- ## Bahasa Indonesia
306
-
307
- ### Deskripsi
308
- Panduan ahli untuk mengukur, mendiagnosis, dan mengoptimalkan performa aplikasi web dengan fokus pada **Core Web Vitals** (LCP, INP, CLS), optimasi JavaScript bundle, strategi loading gambar dan font, performa rendering, dan mencapai skor Lighthouse yang tinggi.
309
-
310
- ### Kondisi Pemicu
311
- - Meningkatkan skor Lighthouse di bawah 90.
312
- - Mendiagnosis metrik LCP, INP, atau CLS yang buruk.
313
- - Mengurangi ukuran JavaScript bundle atau menghilangkan resource yang memblokir render.
314
- - Mengoptimalkan loading gambar, lazy loading, atau pengiriman font.
315
- - Mengimplementasikan pola performa React (memo, useDeferredValue, Suspense).
316
- - Menyiapkan Real User Monitoring (RUM) untuk Core Web Vitals.
317
-
318
- ### Target Core Web Vitals
319
-
320
- | Metrik | Baik | Perlu Perbaikan | Buruk |
321
- |---|---|---|---|
322
- | **LCP** | 2,5 detik | 2,5–4,0 detik | > 4,0 detik |
323
- | **INP** | ≤ 200ms | 200–500ms | > 500ms |
324
- | **CLS** | 0,1 | 0,1–0,25 | > 0,25 |
325
-
326
- ### Ringkasan Strategi Optimasi
327
-
328
- - **LCP**: Preload hero image, gunakan `priority` di Next.js Image, optimalkan TTFB dengan CDN.
329
- - **INP**: Pecah long task dengan `scheduler.yield()`, gunakan `useTransition` React 19, virtualisasi list panjang.
330
- - **CLS**: Reservasi ruang untuk gambar dengan `aspect-ratio`, hindari penyisipan konten di atas konten yang sudah ada.
331
- - **Bundle**: Analisis bundle, gunakan dynamic import, tree-shaking, dan named imports.
332
- - **Monitoring**: Implementasikan `web-vitals` library untuk melaporkan metrik ke analytics secara real-time.
5
+ ---
6
+
7
+ # Web Performance & Core Web Vitals Expert
8
+
9
+ [English](#english) | [Bahasa Indonesia](#bahasa-indonesia)
10
+
11
+ ---
12
+
13
+ <a name="english"></a>
14
+ ## English
15
+
16
+ ### Orchestration & Integration
17
+ Connects and orchestrates with relevant domain skills like `brainstorming`, `zero-to-prod-orchestrator`, and `project-context-mapper` to ensure cohesive execution.
18
+
19
+ ### Description
20
+ Expert guide for measuring, diagnosing, and optimizing web application performance with a focus on **Core Web Vitals** (LCP, INP, CLS), JavaScript bundle optimization, image and font loading strategies, rendering performance, and achieving high Lighthouse scores. Covers Next.js 15, React 19, and modern browser APIs.
21
+
22
+ ### Trigger Conditions
23
+ - Improving Lighthouse performance score below 90.
24
+ - Diagnosing poor LCP, INP, or CLS metrics.
25
+ - Reducing JavaScript bundle size or eliminating render-blocking resources.
26
+ - Optimizing image loading, lazy loading, or font delivery.
27
+ - Implementing React performance patterns (memo, useDeferredValue, Suspense).
28
+ - Setting up Real User Monitoring (RUM) for Core Web Vitals.
29
+ - Optimizing server response times (TTFB).
30
+
31
+ ---
32
+
33
+ ### Core Web Vitals Targets (2024+)
34
+
35
+ | Metric | Good | Needs Improvement | Poor | Measures |
36
+ |---|---|---|---|---|
37
+ | **LCP** (Largest Contentful Paint) | ≤ 2.5s | 2.54.0s | > 4.0s | Loading performance |
38
+ | **INP** (Interaction to Next Paint) | ≤ 200ms | 200500ms | > 500ms | Interactivity (replaced FID) |
39
+ | **CLS** (Cumulative Layout Shift) | ≤ 0.1 | 0.1–0.25 | > 0.25 | Visual stability |
40
+ | **FCP** (First Contentful Paint) | ≤ 1.8s | 1.8–3.0s | > 3.0s | Perceived loading |
41
+ | **TTFB** (Time to First Byte) | ≤ 800ms | 800–1800ms | > 1800ms | Server responsiveness |
42
+
43
+ ---
44
+
45
+ ### LCP Optimization Strategies
46
+
47
+ #### 1. Identify and Optimize the LCP Element
48
+ ```typescript
49
+ // Measure LCP with web-vitals library
50
+ import { onLCP, onINP, onCLS } from 'web-vitals';
51
+
52
+ onLCP((metric) => {
53
+ console.log('LCP:', metric.value, 'element:', metric.attribution.lcpEntry?.element);
54
+ // Send to analytics
55
+ sendToAnalytics({ name: metric.name, value: metric.value });
56
+ });
57
+ ```
58
+
59
+ #### 2. Preload LCP Image (Hero Image)
60
+ ```html
61
+ <!-- In <head> — preload the hero image before CSS blocks it -->
62
+ <link rel="preload" as="image" href="/hero.webp"
63
+ imagesrcset="/hero-480.webp 480w, /hero-800.webp 800w"
64
+ imagesizes="(max-width: 600px) 480px, 800px"
65
+ fetchpriority="high">
66
+ ```
67
+
68
+ #### 3. Next.js Image Component (LCP Hero)
69
+ ```tsx
70
+ import Image from 'next/image';
71
+
72
+ // LCP image: priority=true + fill or explicit size
73
+ <Image
74
+ src="/hero.webp"
75
+ alt="Hero banner"
76
+ width={1200}
77
+ height={600}
78
+ priority // disables lazy loading, adds preload link
79
+ fetchPriority="high"
80
+ quality={85}
81
+ sizes="(max-width: 768px) 100vw, 1200px"
82
+ />
83
+
84
+ // Below-the-fold images: lazy load (default)
85
+ <Image
86
+ src="/product.webp"
87
+ alt="Product"
88
+ width={400}
89
+ height={300}
90
+ // loading="lazy" is the default — no need to specify
91
+ />
92
+ ```
93
+
94
+ ---
95
+
96
+ ### INP Optimization Strategies
97
+
98
+ #### 1. Break Up Long Tasks
99
+ ```typescript
100
+ // BAD: Long synchronous task blocks the main thread
101
+ function processLargeList(items: Item[]) {
102
+ return items.map(expensiveTransform); // blocks for 500ms
103
+ }
104
+
105
+ // GOOD: Yield control back to browser between chunks
106
+ async function processLargeListAsync(items: Item[]) {
107
+ const results: Result[] = [];
108
+ for (let i = 0; i < items.length; i++) {
109
+ results.push(expensiveTransform(items[i]));
110
+ if (i % 50 === 0) await scheduler.yield(); // yield every 50 items
111
+ }
112
+ return results;
113
+ }
114
+ ```
115
+
116
+ #### 2. React 19 — Concurrent Features for INP
117
+ ```tsx
118
+ import { useTransition, useDeferredValue, startTransition } from 'react';
119
+
120
+ // Non-urgent state updates — mark as transitions
121
+ function SearchResults() {
122
+ const [query, setQuery] = useState('');
123
+ const [isPending, startTransition] = useTransition();
124
+ const deferredQuery = useDeferredValue(query);
125
+
126
+ return (
127
+ <>
128
+ <input
129
+ value={query}
130
+ onChange={(e) => {
131
+ setQuery(e.target.value); // urgent: update input immediately
132
+ startTransition(() => {
133
+ // non-urgent: defer expensive filtering
134
+ });
135
+ }}
136
+ />
137
+ {isPending && <Spinner />}
138
+ {/* deferredQuery triggers re-render without blocking input */}
139
+ <ResultsList query={deferredQuery} />
140
+ </>
141
+ );
142
+ }
143
+ ```
144
+
145
+ #### 3. Virtualize Long Lists
146
+ ```tsx
147
+ // Use TanStack Virtual for large lists (1000+ items)
148
+ import { useVirtualizer } from '@tanstack/react-virtual';
149
+
150
+ function VirtualList({ items }: { items: Item[] }) {
151
+ const parentRef = useRef<HTMLDivElement>(null);
152
+ const virtualizer = useVirtualizer({
153
+ count: items.length,
154
+ getScrollElement: () => parentRef.current,
155
+ estimateSize: () => 60, // estimated row height in px
156
+ overscan: 5,
157
+ });
158
+
159
+ return (
160
+ <div ref={parentRef} style={{ height: '600px', overflow: 'auto' }}>
161
+ <div style={{ height: virtualizer.getTotalSize() }}>
162
+ {virtualizer.getVirtualItems().map((vItem) => (
163
+ <div
164
+ key={vItem.key}
165
+ style={{ position: 'absolute', top: vItem.start, height: vItem.size }}
166
+ >
167
+ <ItemRow item={items[vItem.index]} />
168
+ </div>
169
+ ))}
170
+ </div>
171
+ </div>
172
+ );
173
+ }
174
+ ```
175
+
176
+ ---
177
+
178
+ ### CLS Optimization Strategies
179
+
180
+ ```css
181
+ /* 1. Reserve space for images with aspect-ratio */
182
+ img, video {
183
+ width: 100%;
184
+ height: auto;
185
+ aspect-ratio: 16 / 9; /* prevents layout shift before load */
186
+ }
187
+
188
+ /* 2. Reserve space for dynamic content */
189
+ .ad-container {
190
+ min-height: 250px; /* reserve ad slot height */
191
+ }
192
+
193
+ /* 3. Use font-display: optional or swap */
194
+ @font-face {
195
+ font-family: 'Inter';
196
+ src: url('/fonts/inter.woff2') format('woff2');
197
+ font-display: optional; /* no invisible text, no layout shift */
198
+ }
199
+ ```
200
+
201
+ ```tsx
202
+ // 4. Avoid inserting content above existing content
203
+ // BAD: inserting notification banner at top pushes content down
204
+ setShowBanner(true); // causes CLS
205
+
206
+ // GOOD: use position:fixed or reserve space at the top
207
+ <div className="h-12">{showBanner && <Banner />}</div>
208
+ ```
209
+
210
+ ---
211
+
212
+ ### Bundle Optimization
213
+
214
+ #### Next.js Bundle Analysis
215
+ ```bash
216
+ # Analyze bundle composition
217
+ ANALYZE=true npm run build
218
+ # Or use @next/bundle-analyzer
219
+ ```
220
+
221
+ #### Code Splitting Patterns
222
+ ```tsx
223
+ import dynamic from 'next/dynamic';
224
+
225
+ // Dynamic import code splits automatically
226
+ const HeavyChart = dynamic(() => import('@/components/HeavyChart'), {
227
+ loading: () => <ChartSkeleton />,
228
+ ssr: false, // disable SSR for client-only components
229
+ });
230
+
231
+ // Lazy load with React.lazy (non-Next.js)
232
+ const Modal = React.lazy(() => import('./Modal'));
233
+ ```
234
+
235
+ #### Tree-shaking Checklist
236
+ - Use named imports: `import { debounce } from 'lodash-es'` (not `import _ from 'lodash'`)
237
+ - Set `"sideEffects": false` in `package.json` for libraries.
238
+ - Avoid `import *` from large libraries.
239
+ - Replace `moment.js` with `date-fns` or `dayjs`.
240
+ - Use `sharp` for server-side image processing.
241
+
242
+ ---
243
+
244
+ ### React Performance Patterns
245
+
246
+ ```tsx
247
+ // memo — skip re-render if props didn't change
248
+ const ExpensiveList = memo(({ items }: { items: Item[] }) => (
249
+ <ul>{items.map((i) => <li key={i.id}>{i.name}</li>)}</ul>
250
+ ));
251
+
252
+ // useCallback stable function reference for memo children
253
+ const handleDelete = useCallback((id: string) => {
254
+ setItems((prev) => prev.filter((i) => i.id !== id));
255
+ }, []); // empty deps = stable reference
256
+
257
+ // useMemo — memoize expensive calculations
258
+ const sortedItems = useMemo(
259
+ () => [...items].sort((a, b) => a.name.localeCompare(b.name)),
260
+ [items]
261
+ );
262
+ ```
263
+
264
+ ---
265
+
266
+ ### Performance Monitoring Setup
267
+
268
+ ```typescript
269
+ // report-vitals.ts send Core Web Vitals to analytics
270
+ import { onCLS, onINP, onLCP, onFCP, onTTFB } from 'web-vitals';
271
+
272
+ function sendToAnalytics({ name, value, id, navigationType }: Metric) {
273
+ // Send to PostHog, Google Analytics, or your own endpoint
274
+ fetch('/api/analytics/vitals', {
275
+ method: 'POST',
276
+ body: JSON.stringify({ name, value: Math.round(value), id, navigationType }),
277
+ keepalive: true, // ensures request completes even if page unloads
278
+ });
279
+ }
280
+
281
+ onCLS(sendToAnalytics);
282
+ onINP(sendToAnalytics);
283
+ onLCP(sendToAnalytics);
284
+ onFCP(sendToAnalytics);
285
+ onTTFB(sendToAnalytics);
286
+ ```
287
+
288
+ ---
289
+
290
+ ### Lighthouse Score Improvement Checklist
291
+
292
+ - [ ] LCP image has `priority` or `fetchpriority="high"` + preload link.
293
+ - [ ] All non-LCP images use `loading="lazy"`.
294
+ - [ ] Fonts loaded with `font-display: optional` or preloaded with `rel="preload"`.
295
+ - [ ] No render-blocking `<script>` tags without `defer` or `async`.
296
+ - [ ] Bundle size < 200KB gzipped for initial JS.
297
+ - [ ] Images served in WebP/AVIF format with `srcset`.
298
+ - [ ] Server response time (TTFB) < 600ms — use CDN edge caching.
299
+ - [ ] Long tasks (> 50ms) are broken up or deferred.
300
+ - [ ] Virtual lists used for > 100 items.
301
+ - [ ] Unused CSS removed (PurgeCSS / Tailwind purge).
302
+ - [ ] HTTP/2 or HTTP/3 enabled on server.
303
+ - [ ] Resource hints: `dns-prefetch`, `preconnect` for third-party origins.
304
+
305
+ ---
306
+
307
+ <a name="bahasa-indonesia"></a>
308
+ ## Bahasa Indonesia
309
+
310
+ ### Integrasi Orkestrasi
311
+ Terhubung dan mengorkestrasi skill domain yang relevan seperti `brainstorming`, `zero-to-prod-orchestrator`, dan `project-context-mapper` untuk memastikan eksekusi yang kohesif.
312
+
313
+ ### Deskripsi
314
+ Panduan ahli untuk mengukur, mendiagnosis, dan mengoptimalkan performa aplikasi web dengan fokus pada **Core Web Vitals** (LCP, INP, CLS), optimasi JavaScript bundle, strategi loading gambar dan font, performa rendering, dan mencapai skor Lighthouse yang tinggi.
315
+
316
+ ### Kondisi Pemicu
317
+ - Meningkatkan skor Lighthouse di bawah 90.
318
+ - Mendiagnosis metrik LCP, INP, atau CLS yang buruk.
319
+ - Mengurangi ukuran JavaScript bundle atau menghilangkan resource yang memblokir render.
320
+ - Mengoptimalkan loading gambar, lazy loading, atau pengiriman font.
321
+ - Mengimplementasikan pola performa React (memo, useDeferredValue, Suspense).
322
+ - Menyiapkan Real User Monitoring (RUM) untuk Core Web Vitals.
323
+
324
+ ### Target Core Web Vitals
325
+
326
+ | Metrik | Baik | Perlu Perbaikan | Buruk |
327
+ |---|---|---|---|
328
+ | **LCP** | 2,5 detik | 2,5–4,0 detik | > 4,0 detik |
329
+ | **INP** | 200ms | 200–500ms | > 500ms |
330
+ | **CLS** | 0,1 | 0,1–0,25 | > 0,25 |
331
+
332
+ ### Ringkasan Strategi Optimasi
333
+
334
+ - **LCP**: Preload hero image, gunakan `priority` di Next.js Image, optimalkan TTFB dengan CDN.
335
+ - **INP**: Pecah long task dengan `scheduler.yield()`, gunakan `useTransition` React 19, virtualisasi list panjang.
336
+ - **CLS**: Reservasi ruang untuk gambar dengan `aspect-ratio`, hindari penyisipan konten di atas konten yang sudah ada.
337
+ - **Bundle**: Analisis bundle, gunakan dynamic import, tree-shaking, dan named imports.
338
+ - **Monitoring**: Implementasikan `web-vitals` library untuk melaporkan metrik ke analytics secara real-time.