developer-ai 1.0.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.
- package/README.md +241 -0
- package/bin/developer-ai.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +219 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +82 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +115 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +29 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/agent.d.ts +38 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +155 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/system-prompt.d.ts +6 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +44 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/types.d.ts +42 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +13 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +202 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/providers/ollama.d.ts +13 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +60 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai.d.ts +9 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +40 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/skills/loader.d.ts +25 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +93 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/tests/tools.test.d.ts +2 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +170 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +19 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-files.d.ts +3 -0
- package/dist/tools/list-files.d.ts.map +1 -0
- package/dist/tools/list-files.js +60 -0
- package/dist/tools/list-files.js.map +1 -0
- package/dist/tools/read-file.d.ts +3 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +46 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.d.ts +24 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +37 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/run-command.d.ts +3 -0
- package/dist/tools/run-command.d.ts.map +1 -0
- package/dist/tools/run-command.js +114 -0
- package/dist/tools/run-command.js.map +1 -0
- package/dist/tools/search-text.d.ts +3 -0
- package/dist/tools/search-text.d.ts.map +1 -0
- package/dist/tools/search-text.js +103 -0
- package/dist/tools/search-text.js.map +1 -0
- package/dist/tools/utils.d.ts +6 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +14 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/web-search.d.ts +3 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +80 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/write-file.d.ts +3 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +66 -0
- package/dist/tools/write-file.js.map +1 -0
- package/package.json +54 -0
- package/skills/accessibility/SKILL.md +496 -0
- package/skills/api-design/SKILL.md +419 -0
- package/skills/code-review/SKILL.md +267 -0
- package/skills/debugging/SKILL.md +332 -0
- package/skills/documentation/SKILL.md +496 -0
- package/skills/error-handling/SKILL.md +504 -0
- package/skills/git-workflow/SKILL.md +448 -0
- package/skills/human-like-coding/SKILL.md +400 -0
- package/skills/performance-optimization/SKILL.md +412 -0
- package/skills/prompt-engineering/SKILL.md +362 -0
- package/skills/refactoring/SKILL.md +457 -0
- package/skills/security-audit/SKILL.md +453 -0
- package/skills/testing-strategy/SKILL.md +501 -0
- package/skills/webapp-testing/SKILL.md +309 -0
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance-optimization
|
|
3
|
+
description: Guide for optimizing application performance. Use when addressing slow load times, sluggish UI, memory leaks, or inefficient code. Covers frontend performance, database optimization, caching strategies, and profiling techniques.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Performance Optimization Skill
|
|
7
|
+
|
|
8
|
+
This skill provides comprehensive guidance for identifying and fixing performance issues in web applications.
|
|
9
|
+
|
|
10
|
+
## Overview
|
|
11
|
+
|
|
12
|
+
Performance directly impacts user experience and business metrics. This skill covers systematic approaches to measuring and improving application performance.
|
|
13
|
+
|
|
14
|
+
## Performance Metrics
|
|
15
|
+
|
|
16
|
+
### Core Web Vitals
|
|
17
|
+
- **LCP (Largest Contentful Paint)** - Target: < 2.5s
|
|
18
|
+
- **FID (First Input Delay)** - Target: < 100ms
|
|
19
|
+
- **CLS (Cumulative Layout Shift)** - Target: < 0.1
|
|
20
|
+
- **INP (Interaction to Next Paint)** - Target: < 200ms
|
|
21
|
+
|
|
22
|
+
### Other Key Metrics
|
|
23
|
+
- **TTFB (Time to First Byte)** - Target: < 600ms
|
|
24
|
+
- **FCP (First Contentful Paint)** - Target: < 1.8s
|
|
25
|
+
- **TTI (Time to Interactive)** - Target: < 3.8s
|
|
26
|
+
- **Total Bundle Size** - Target: < 200KB gzipped
|
|
27
|
+
|
|
28
|
+
## Frontend Performance
|
|
29
|
+
|
|
30
|
+
### JavaScript Optimization
|
|
31
|
+
|
|
32
|
+
**Code Splitting**
|
|
33
|
+
```javascript
|
|
34
|
+
// Before: Everything in one bundle
|
|
35
|
+
import { HeavyComponent } from './HeavyComponent';
|
|
36
|
+
|
|
37
|
+
// After: Lazy load when needed
|
|
38
|
+
const HeavyComponent = React.lazy(() => import('./HeavyComponent'));
|
|
39
|
+
|
|
40
|
+
function App() {
|
|
41
|
+
return (
|
|
42
|
+
<Suspense fallback={<Loading />}>
|
|
43
|
+
<HeavyComponent />
|
|
44
|
+
</Suspense>
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Tree Shaking**
|
|
50
|
+
```javascript
|
|
51
|
+
// BAD: Imports entire library
|
|
52
|
+
import _ from 'lodash';
|
|
53
|
+
_.debounce(fn, 300);
|
|
54
|
+
|
|
55
|
+
// GOOD: Import only what you need
|
|
56
|
+
import debounce from 'lodash/debounce';
|
|
57
|
+
debounce(fn, 300);
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Debouncing & Throttling**
|
|
61
|
+
```javascript
|
|
62
|
+
// Debounce for search input
|
|
63
|
+
const debouncedSearch = debounce((query) => {
|
|
64
|
+
fetchResults(query);
|
|
65
|
+
}, 300);
|
|
66
|
+
|
|
67
|
+
// Throttle for scroll events
|
|
68
|
+
const throttledScroll = throttle(() => {
|
|
69
|
+
updateScrollPosition();
|
|
70
|
+
}, 100);
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Memoization**
|
|
74
|
+
```javascript
|
|
75
|
+
// React memoization
|
|
76
|
+
const ExpensiveComponent = React.memo(({ data }) => {
|
|
77
|
+
return <div>{/* render */}</div>;
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// useMemo for expensive calculations
|
|
81
|
+
const sortedData = useMemo(() => {
|
|
82
|
+
return data.sort((a, b) => a.name.localeCompare(b.name));
|
|
83
|
+
}, [data]);
|
|
84
|
+
|
|
85
|
+
// useCallback for stable references
|
|
86
|
+
const handleClick = useCallback(() => {
|
|
87
|
+
doSomething(id);
|
|
88
|
+
}, [id]);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### CSS Performance
|
|
92
|
+
|
|
93
|
+
**Critical CSS**
|
|
94
|
+
```html
|
|
95
|
+
<!-- Inline critical CSS -->
|
|
96
|
+
<style>
|
|
97
|
+
/* Above-the-fold styles */
|
|
98
|
+
.hero { /* ... */ }
|
|
99
|
+
</style>
|
|
100
|
+
|
|
101
|
+
<!-- Load rest asynchronously -->
|
|
102
|
+
<link rel="preload" href="styles.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Avoid Layout Thrashing**
|
|
106
|
+
```javascript
|
|
107
|
+
// BAD: Causes multiple reflows
|
|
108
|
+
elements.forEach(el => {
|
|
109
|
+
const height = el.offsetHeight; // Read
|
|
110
|
+
el.style.height = height + 10 + 'px'; // Write
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// GOOD: Batch reads and writes
|
|
114
|
+
const heights = elements.map(el => el.offsetHeight); // All reads
|
|
115
|
+
elements.forEach((el, i) => {
|
|
116
|
+
el.style.height = heights[i] + 10 + 'px'; // All writes
|
|
117
|
+
});
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Use CSS Containment**
|
|
121
|
+
```css
|
|
122
|
+
.card {
|
|
123
|
+
contain: layout style paint;
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Image Optimization
|
|
128
|
+
|
|
129
|
+
**Responsive Images**
|
|
130
|
+
```html
|
|
131
|
+
<img
|
|
132
|
+
srcset="image-300.jpg 300w,
|
|
133
|
+
image-600.jpg 600w,
|
|
134
|
+
image-1200.jpg 1200w"
|
|
135
|
+
sizes="(max-width: 600px) 300px,
|
|
136
|
+
(max-width: 1200px) 600px,
|
|
137
|
+
1200px"
|
|
138
|
+
src="image-600.jpg"
|
|
139
|
+
alt="Description"
|
|
140
|
+
loading="lazy"
|
|
141
|
+
decoding="async"
|
|
142
|
+
>
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Modern Formats**
|
|
146
|
+
```html
|
|
147
|
+
<picture>
|
|
148
|
+
<source srcset="image.avif" type="image/avif">
|
|
149
|
+
<source srcset="image.webp" type="image/webp">
|
|
150
|
+
<img src="image.jpg" alt="Description">
|
|
151
|
+
</picture>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Resource Loading
|
|
155
|
+
|
|
156
|
+
**Preload Critical Resources**
|
|
157
|
+
```html
|
|
158
|
+
<link rel="preload" href="/fonts/main.woff2" as="font" type="font/woff2" crossorigin>
|
|
159
|
+
<link rel="preload" href="/api/critical-data" as="fetch" crossorigin>
|
|
160
|
+
<link rel="preconnect" href="https://api.example.com">
|
|
161
|
+
<link rel="dns-prefetch" href="https://analytics.example.com">
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Defer Non-Critical Scripts**
|
|
165
|
+
```html
|
|
166
|
+
<!-- Critical: blocks rendering -->
|
|
167
|
+
<script src="critical.js"></script>
|
|
168
|
+
|
|
169
|
+
<!-- Defer: executes after parsing -->
|
|
170
|
+
<script defer src="analytics.js"></script>
|
|
171
|
+
|
|
172
|
+
<!-- Async: executes when ready -->
|
|
173
|
+
<script async src="non-critical.js"></script>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## React Performance
|
|
177
|
+
|
|
178
|
+
### Preventing Re-renders
|
|
179
|
+
|
|
180
|
+
```javascript
|
|
181
|
+
// Use React.memo for pure components
|
|
182
|
+
const ListItem = React.memo(({ item, onClick }) => {
|
|
183
|
+
return (
|
|
184
|
+
<li onClick={() => onClick(item.id)}>
|
|
185
|
+
{item.name}
|
|
186
|
+
</li>
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// Use useCallback for stable event handlers
|
|
191
|
+
function Parent() {
|
|
192
|
+
const [items, setItems] = useState([]);
|
|
193
|
+
|
|
194
|
+
const handleClick = useCallback((id) => {
|
|
195
|
+
// handle click
|
|
196
|
+
}, []);
|
|
197
|
+
|
|
198
|
+
return items.map(item => (
|
|
199
|
+
<ListItem key={item.id} item={item} onClick={handleClick} />
|
|
200
|
+
));
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Virtualization for Long Lists
|
|
205
|
+
```javascript
|
|
206
|
+
import { FixedSizeList } from 'react-window';
|
|
207
|
+
|
|
208
|
+
function VirtualList({ items }) {
|
|
209
|
+
return (
|
|
210
|
+
<FixedSizeList
|
|
211
|
+
height={500}
|
|
212
|
+
width="100%"
|
|
213
|
+
itemCount={items.length}
|
|
214
|
+
itemSize={50}
|
|
215
|
+
>
|
|
216
|
+
{({ index, style }) => (
|
|
217
|
+
<div style={style}>
|
|
218
|
+
{items[index].name}
|
|
219
|
+
</div>
|
|
220
|
+
)}
|
|
221
|
+
</FixedSizeList>
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Backend Performance
|
|
227
|
+
|
|
228
|
+
### Database Optimization
|
|
229
|
+
|
|
230
|
+
**Indexing**
|
|
231
|
+
```sql
|
|
232
|
+
-- Add indexes for frequently queried columns
|
|
233
|
+
CREATE INDEX idx_users_email ON users(email);
|
|
234
|
+
CREATE INDEX idx_orders_user_date ON orders(user_id, created_at);
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Avoid N+1 Queries**
|
|
238
|
+
```javascript
|
|
239
|
+
// BAD: N+1 queries
|
|
240
|
+
const users = await User.findAll();
|
|
241
|
+
for (const user of users) {
|
|
242
|
+
user.orders = await Order.findAll({ where: { userId: user.id } });
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// GOOD: Eager loading
|
|
246
|
+
const users = await User.findAll({
|
|
247
|
+
include: [{ model: Order }]
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**Pagination**
|
|
252
|
+
```javascript
|
|
253
|
+
// Use cursor-based pagination for large datasets
|
|
254
|
+
async function getUsers(cursor, limit = 20) {
|
|
255
|
+
const query = {
|
|
256
|
+
limit: limit + 1,
|
|
257
|
+
orderBy: { id: 'asc' },
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
if (cursor) {
|
|
261
|
+
query.where = { id: { gt: cursor } };
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const users = await User.findMany(query);
|
|
265
|
+
const hasMore = users.length > limit;
|
|
266
|
+
|
|
267
|
+
return {
|
|
268
|
+
users: users.slice(0, limit),
|
|
269
|
+
nextCursor: hasMore ? users[limit - 1].id : null,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Caching Strategies
|
|
275
|
+
|
|
276
|
+
**HTTP Caching**
|
|
277
|
+
```javascript
|
|
278
|
+
// Static assets: long cache, hash in filename
|
|
279
|
+
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
|
|
280
|
+
|
|
281
|
+
// API responses: short cache with revalidation
|
|
282
|
+
res.setHeader('Cache-Control', 'public, max-age=60, stale-while-revalidate=300');
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**In-Memory Caching**
|
|
286
|
+
```javascript
|
|
287
|
+
import NodeCache from 'node-cache';
|
|
288
|
+
|
|
289
|
+
const cache = new NodeCache({ stdTTL: 300 });
|
|
290
|
+
|
|
291
|
+
async function getUser(id) {
|
|
292
|
+
const cached = cache.get(`user:${id}`);
|
|
293
|
+
if (cached) return cached;
|
|
294
|
+
|
|
295
|
+
const user = await db.user.findUnique({ where: { id } });
|
|
296
|
+
cache.set(`user:${id}`, user);
|
|
297
|
+
return user;
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
**Redis Caching**
|
|
302
|
+
```javascript
|
|
303
|
+
import Redis from 'ioredis';
|
|
304
|
+
|
|
305
|
+
const redis = new Redis();
|
|
306
|
+
|
|
307
|
+
async function getCachedData(key, fetchFn, ttl = 300) {
|
|
308
|
+
const cached = await redis.get(key);
|
|
309
|
+
if (cached) return JSON.parse(cached);
|
|
310
|
+
|
|
311
|
+
const data = await fetchFn();
|
|
312
|
+
await redis.setex(key, ttl, JSON.stringify(data));
|
|
313
|
+
return data;
|
|
314
|
+
}
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Profiling & Measurement
|
|
318
|
+
|
|
319
|
+
### Browser DevTools
|
|
320
|
+
|
|
321
|
+
**Performance Tab**
|
|
322
|
+
1. Record page load or interaction
|
|
323
|
+
2. Look for long tasks (> 50ms)
|
|
324
|
+
3. Check main thread blocking
|
|
325
|
+
4. Identify layout thrashing
|
|
326
|
+
|
|
327
|
+
**Lighthouse**
|
|
328
|
+
- Run in incognito mode
|
|
329
|
+
- Test on throttled connection
|
|
330
|
+
- Focus on opportunities and diagnostics
|
|
331
|
+
|
|
332
|
+
### Code Profiling
|
|
333
|
+
|
|
334
|
+
```javascript
|
|
335
|
+
// Manual timing
|
|
336
|
+
console.time('operation');
|
|
337
|
+
await expensiveOperation();
|
|
338
|
+
console.timeEnd('operation');
|
|
339
|
+
|
|
340
|
+
// Performance API
|
|
341
|
+
const start = performance.now();
|
|
342
|
+
await expensiveOperation();
|
|
343
|
+
const duration = performance.now() - start;
|
|
344
|
+
console.log(`Operation took ${duration}ms`);
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Real User Monitoring
|
|
348
|
+
|
|
349
|
+
```javascript
|
|
350
|
+
// Web Vitals
|
|
351
|
+
import { onLCP, onFID, onCLS } from 'web-vitals';
|
|
352
|
+
|
|
353
|
+
function sendToAnalytics({ name, value, id }) {
|
|
354
|
+
analytics.send({ metric: name, value, id });
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
onLCP(sendToAnalytics);
|
|
358
|
+
onFID(sendToAnalytics);
|
|
359
|
+
onCLS(sendToAnalytics);
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## Performance Budget
|
|
363
|
+
|
|
364
|
+
```json
|
|
365
|
+
{
|
|
366
|
+
"budgets": [
|
|
367
|
+
{
|
|
368
|
+
"resourceType": "script",
|
|
369
|
+
"budget": 150
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
"resourceType": "total",
|
|
373
|
+
"budget": 300
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
"metric": "first-contentful-paint",
|
|
377
|
+
"budget": 1500
|
|
378
|
+
},
|
|
379
|
+
{
|
|
380
|
+
"metric": "interactive",
|
|
381
|
+
"budget": 3500
|
|
382
|
+
}
|
|
383
|
+
]
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
## Optimization Checklist
|
|
388
|
+
|
|
389
|
+
### Initial Load
|
|
390
|
+
- [ ] Code splitting implemented
|
|
391
|
+
- [ ] Images optimized and lazy-loaded
|
|
392
|
+
- [ ] Critical CSS inlined
|
|
393
|
+
- [ ] Fonts preloaded
|
|
394
|
+
- [ ] Unused code removed
|
|
395
|
+
|
|
396
|
+
### Runtime Performance
|
|
397
|
+
- [ ] Expensive operations memoized
|
|
398
|
+
- [ ] Long lists virtualized
|
|
399
|
+
- [ ] Event handlers debounced/throttled
|
|
400
|
+
- [ ] Memory leaks addressed
|
|
401
|
+
|
|
402
|
+
### Network
|
|
403
|
+
- [ ] HTTP caching configured
|
|
404
|
+
- [ ] API responses cached
|
|
405
|
+
- [ ] Resources compressed (gzip/brotli)
|
|
406
|
+
- [ ] CDN utilized
|
|
407
|
+
|
|
408
|
+
### Database
|
|
409
|
+
- [ ] Indexes on queried columns
|
|
410
|
+
- [ ] No N+1 queries
|
|
411
|
+
- [ ] Pagination implemented
|
|
412
|
+
- [ ] Query results cached
|