Analyze and optimize your Odoo PWA for performance, bundle size, and user experience. ## What this command does: - Analyzes bundle size - Identifies performance bottlenecks - Suggests optimizations - Checks caching efficiency - Reviews PWA configuration - Provides actionable recommendations --- ## Quick Performance Check 🚀 ### Run These Commands: ```bash # Build for production npm run build # Analyze bundle size npm run build -- --analyze # Preview production build npm run preview # Run Lighthouse audit # (Chrome DevTools → Lighthouse tab) ``` --- ## Bundle Size Analysis 📦 ### Check Current Size ```bash # Build and see output npm run build # Typical output: # dist/index.html 1.2 kB # dist/assets/index-abc123.js 45.3 kB # dist/assets/vendor-def456.js 120.5 kB ``` ### Analyze Bundle Composition ```bash # Install analyzer npm install -D rollup-plugin-visualizer # Add to vite.config.js import { visualizer } from 'rollup-plugin-visualizer'; export default { plugins: [ // ...other plugins visualizer({ open: true, gzipSize: true, brotliSize: true }) ] }; # Build and open report npm run build # Opens stats.html in browser ``` ### Target Bundle Sizes: - ✅ **Excellent**: < 200 KB (gzipped) - ⚠️ **Good**: 200-500 KB - ❌ **Needs Work**: > 500 KB --- ## Optimization Strategies ### 1. Code Splitting 📂 #### Lazy Load Routes **SvelteKit** (automatic): ```javascript // Routes are auto-split // src/routes/+page.svelte → separate chunk ``` **React**: ```javascript import { lazy, Suspense } from 'react'; const ExpenseList = lazy(() => import('./ExpenseList')); function App() { return ( }> ); } ``` **Vue**: ```javascript const ExpenseList = () => import('./ExpenseList.vue'); const routes = [ { path: '/expenses', component: ExpenseList // Lazy loaded } ]; ``` #### Manual Code Splitting ```javascript // Split heavy utility into separate chunk const heavyUtil = await import('./heavyUtility.js'); heavyUtil.doSomething(); ``` ### 2. Tree Shaking 🌳 #### Remove Unused Code ```javascript // Bad: Imports everything import * as utils from './utils'; // Good: Import only what you need import { formatDate, formatCurrency } from './utils'; ``` #### Check for Unused Dependencies ```bash npm install -g depcheck depcheck # Remove unused packages npm uninstall ``` ### 3. Optimize Dependencies 📚 #### Use Lighter Alternatives ```javascript // Instead of moment.js (heavy) import moment from 'moment'; // 72 KB // Use date-fns (tree-shakeable) import { format } from 'date-fns'; // ~2 KB // Or native Date new Date().toLocaleDateString(); ``` #### Common Heavy Packages & Alternatives: - ❌ **moment** (72 KB) → ✅ **date-fns** (tree-shakeable) - ❌ **lodash** (whole) → ✅ **lodash-es** (individual imports) - ❌ **axios** → ✅ **fetch** (built-in) - ❌ **uuid** → ✅ **crypto.randomUUID()** (built-in) ### 4. Optimize Images 🖼️ #### Compress Images ```bash # Install image optimizer npm install -D vite-plugin-imagemin # Add to vite.config.js import viteImagemin from 'vite-plugin-imagemin'; export default { plugins: [ viteImagemin({ gifsicle: { optimizationLevel: 7 }, optipng: { optimizationLevel: 7 }, mozjpeg: { quality: 80 }, svgo: { plugins: [{ removeViewBox: false }] } }) ] }; ``` #### Lazy Load Images ```javascript // Native lazy loading // Or with IntersectionObserver ``` #### Use Appropriate Formats - **WebP** for photos (smaller than JPEG) - **SVG** for icons/logos - **PNG** only when transparency needed ### 5. Minimize JavaScript ⚡ #### Enable Minification (default in Vite) ```javascript // vite.config.js export default { build: { minify: 'terser', // or 'esbuild' (faster) terserOptions: { compress: { drop_console: true, // Remove console.logs drop_debugger: true } } } }; ``` #### Remove Development Code ```javascript // Use environment variables if (import.meta.env.DEV) { console.log('Debug info'); // Removed in production } ``` --- ## Caching Optimization 💾 ### 1. Optimize Cache Strategy #### Review Cache Settings ```javascript // In cache store const CACHE_VALIDITY = 5 * 60 * 1000; // 5 minutes // Consider your use case: // - Frequently changing data: 1-2 minutes // - Moderate updates: 5-10 minutes // - Rarely changes: 30-60 minutes ``` #### Limit Initial Load ```javascript // Don't fetch everything at once const records = await odoo.searchRecords( model, [], fields, 100 // Limit to 100 records initially ); // Load more on demand (pagination) ``` ### 2. Optimize Sync Frequency ```javascript // Adjust sync interval based on needs const SYNC_INTERVAL = 5 * 60 * 1000; // 5 minutes // Balance: // - More frequent: Better UX, more bandwidth // - Less frequent: Less bandwidth, slightly stale data ``` ### 3. Selective Caching ```javascript // Only cache fields you need const fields = [ 'x_studio_name', 'x_studio_amount', 'x_studio_date' // Don't fetch unnecessary fields ]; ``` --- ## PWA Optimization 📱 ### 1. Service Worker Configuration #### Optimize Caching Strategy ```javascript // In service worker or vite-plugin-pwa config VitePWA({ workbox: { runtimeCaching: [ { urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/, handler: 'CacheFirst', options: { cacheName: 'google-fonts', expiration: { maxEntries: 10, maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year } } }, { urlPattern: /^https:\/\/.*\.odoo\.com\/.*/, handler: 'NetworkFirst', options: { cacheName: 'odoo-api', networkTimeoutSeconds: 3 } } ] } }) ``` ### 2. Optimize Manifest ```json { "name": "Expense Tracker", "short_name": "Expenses", "start_url": "/", "display": "standalone", "background_color": "#ffffff", "theme_color": "#0066cc", "icons": [ { "src": "/icon-192.png", "sizes": "192x192", "type": "image/png", "purpose": "any maskable" }, { "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" } ] } ``` ### 3. Optimize Icons ```bash # Use optimized PNG or WebP # Compress images # Provide multiple sizes ``` --- ## Network Optimization 🌐 ### 1. Reduce API Calls #### Batch Requests ```javascript // Bad: Multiple calls const expenses = await fetchExpenses(); const tasks = await fetchTasks(); const partners = await fetchPartners(); // Good: Single call (if Odoo supports) const data = await fetchAll(['expenses', 'tasks', 'partners']); ``` #### Cache Partner Names ```javascript // Fetch once, reuse const partners = await odoo.fetchPartners(); localStorage.setItem('partnerCache', JSON.stringify(partners)); // Later, use cached data const cached = JSON.parse(localStorage.getItem('partnerCache')); ``` ### 2. Incremental Loading ```javascript // Load initial data const initial = await fetchExpenses({ limit: 20 }); // Load more on scroll function onScroll() { if (nearBottom) { loadMore(); } } ``` ### 3. Optimize Requests ```javascript // Only fetch fields you display const fields = ['id', 'x_studio_name', 'x_studio_amount']; // Use appropriate domain filters const domain = [ ['x_studio_date', '>=', lastMonth], ['x_studio_status', '!=', 'deleted'] ]; ``` --- ## UI Performance 🎨 ### 1. Virtual Scrolling For long lists: ```javascript // SvelteKit import { VirtualList } from 'svelte-virtual-list'; // React import { FixedSizeList } from 'react-window'; // Vue import { RecycleScroller } from 'vue-virtual-scroller'; ``` ### 2. Debounce Search ```javascript import { debounce } from './utils'; const handleSearch = debounce((query) => { searchExpenses(query); }, 300); // Wait 300ms after typing stops ``` ### 3. Optimize Rendering ```javascript // SvelteKit: Use keyed each blocks {#each expenses as expense (expense.id)} {/each} // React: Use keys and memo const ExpenseCard = memo(({ expense }) => { // ... }); expenses.map(expense => ( )); // Vue: Use v-memo ``` --- ## Build Optimization 🔨 ### Vite Config Optimizations ```javascript // vite.config.js export default { build: { // Target modern browsers target: 'es2020', // Optimize chunks rollupOptions: { output: { manualChunks: { vendor: ['svelte', '@sveltejs/kit'], odoo: ['./src/lib/odoo.js', './src/lib/stores'] } } }, // Compression minify: 'esbuild', // Faster than terser // Source maps (only for debugging) sourcemap: false }, // Optimize dependencies optimizeDeps: { include: ['date-fns', 'lodash-es'] } }; ``` --- ## Lighthouse Audit 💡 ### Run Lighthouse 1. Open Chrome DevTools 2. Go to Lighthouse tab 3. Select categories: - ✅ Performance - ✅ Progressive Web App - ✅ Best Practices - ✅ Accessibility - ✅ SEO 4. Click "Analyze page load" ### Target Scores: - **Performance**: > 90 - **PWA**: 100 - **Best Practices**: > 95 - **Accessibility**: > 90 - **SEO**: > 90 ### Common Issues & Fixes: #### Low Performance Score - Reduce bundle size - Optimize images - Enable caching - Lazy load resources #### PWA Issues - Fix manifest.json - Register service worker - Add offline support - Provide app icons #### Accessibility Issues - Add alt text to images - Use semantic HTML - Ensure color contrast - Add ARIA labels --- ## Performance Monitoring 📊 ### Add Performance Tracking ```javascript // Measure initial load window.addEventListener('load', () => { const perfData = performance.getEntriesByType('navigation')[0]; console.log('Load time:', perfData.loadEventEnd - perfData.fetchStart); console.log('DOM ready:', perfData.domContentLoadedEventEnd - perfData.fetchStart); }); // Measure sync time console.time('sync'); await expenseCache.refresh(); console.timeEnd('sync'); ``` ### Use Web Vitals ```bash npm install web-vitals # In app import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals'; getCLS(console.log); getFID(console.log); getFCP(console.log); getLCP(console.log); getTTFB(console.log); ``` --- ## Optimization Checklist ✅ ### Bundle Size: ``` □ Analyzed bundle composition □ Removed unused dependencies □ Lazy loaded routes/components □ Optimized images □ Tree-shaking enabled □ Minification enabled □ Total size < 500 KB (gzipped) ``` ### Caching: ``` □ Optimal cache validity period □ Incremental sync working □ Selective field fetching □ Partner name caching □ Appropriate sync frequency □ IndexedDB optimized ``` ### PWA: ``` □ Service worker registered □ Offline mode works □ App installable □ Icons optimized □ Manifest configured □ Fast load time ``` ### Performance: ``` □ Lighthouse score > 90 □ Initial load < 3s □ Sync time < 2s □ No console errors □ Smooth scrolling □ Fast navigation ``` --- ## Example prompts to use this command: - `/optimize` - Run optimization checks - User: "Make my app faster" - User: "Reduce bundle size" - User: "Optimize performance" ## Related Commands: - `/test-connection` - Test after optimization - `/update-deps` - Update to faster versions - `/troubleshoot` - Fix performance issues - `/help` - More information --- ## Quick Wins 🎯 ### Immediate Optimizations: 1. **Enable compression** (already in Vite) 2. **Remove console.logs** in production 3. **Lazy load routes** (easy with frameworks) 4. **Optimize images** (use WebP) 5. **Limit initial data fetch** (pagination) ### Medium Effort: 1. **Analyze and split bundles** 2. **Replace heavy dependencies** 3. **Implement virtual scrolling** 4. **Optimize service worker** 5. **Add performance monitoring** ### Long Term: 1. **Regular Lighthouse audits** 2. **Monitor real user metrics** 3. **Continuous optimization** 4. **Keep dependencies updated** 5. **Review and refactor regularly**