From capacitor-quality
Optimizes Capacitor app performance covering bundle size reduction, rendering improvements, memory management, native bridge efficiency, and profiling with Chrome DevTools, Xcode, Android Profiler. For slow apps or janky animations.
npx claudepluginhub cap-go/capgo-skills --plugin capacitor-qualityThis skill uses the workspace's default tool permissions.
Make your Capacitor apps fast and responsive.
Provides React Native performance optimization guidelines for FPS, TTI, bundle size, memory leaks, re-renders, and animations. Guides Hermes optimization, JS thread blocking, bridge overhead, FlashList, native modules, and jank debugging.
Provides React Native performance optimization guidelines for FPS, TTI, bundle size, memory leaks, re-renders, animations, Hermes, JS thread blocking, bridge overhead, FlashList, native modules, and jank debugging.
Guides debugging Capacitor apps on iOS/Android: WebView inspection via Safari/Chrome DevTools, native debugging in Xcode/Android Studio, crash logs, network analysis, and common issues.
Share bugs, ideas, or general feedback.
Make your Capacitor apps fast and responsive.
// BAD - All plugins loaded at startup
import { Camera } from '@capacitor/camera';
import { Filesystem } from '@capacitor/filesystem';
import { Geolocation } from '@capacitor/geolocation';
// GOOD - Load when needed
async function takePhoto() {
const { Camera } = await import('@capacitor/camera');
return Camera.getPhoto({ quality: 90 });
}
# Analyze bundle
npx vite-bundle-visualizer
# Tree-shake imports
import { specific } from 'large-library'; // Good
import * as everything from 'large-library'; // Bad
// Use appropriate quality
const photo = await Camera.getPhoto({
quality: 80, // Not 100
width: 1024, // Limit size
resultType: CameraResultType.Uri, // Not Base64
});
// Lazy load images
<img loading="lazy" src={url} />
// BAD - Multiple bridge calls
for (const item of items) {
await Storage.set({ key: item.id, value: item.data });
}
// GOOD - Single call with batch
await Storage.set({
key: 'items',
value: JSON.stringify(items),
});
/* GPU accelerated */
.animated {
transform: translateX(100px);
will-change: transform;
}
/* Avoid - triggers layout */
.animated {
left: 100px;
}
// Use virtual list for long lists
import { VirtualScroller } from 'your-framework';
<VirtualScroller
items={items}
itemHeight={60}
renderItem={(item) => <ListItem item={item} />}
/>
import { debounce } from 'lodash-es';
const handleScroll = debounce((e) => {
// Handle scroll
}, 16); // ~60fps
import { App } from '@capacitor/app';
// Store listener handle
const handle = await App.addListener('appStateChange', callback);
// Cleanup on unmount
onUnmount(() => {
handle.remove();
});
// Clear large data when done
let largeData = await fetchLargeData();
processData(largeData);
largeData = null; // Allow GC
| Metric | Target |
|---|---|
| First Paint | < 1s |
| Time to Interactive | < 3s |
| Frame Rate | 60fps |
| Memory | Stable, no growth |
| Bundle Size | < 500KB gzipped |