Files
indee-demo/.cursor/rules/performance-optimization.mdc
Dorian 0bb1bcc5f9 Initial commit: IndeeHub decentralized streaming platform
Built a complete Netflix-style streaming interface for IndeeHub's decentralized media platform with real film content.

Features:
- Vue 3 + TypeScript + Vite setup with hot module reloading
- Netflix-inspired UI with hero section and horizontal scrolling content rows
- Glass morphism design system with custom Tailwind configuration
- 20+ real IndeeHub films organized into 6 categories (Bitcoin, Documentaries, Drama, etc.)
- Full-featured video player component with custom controls
- Mobile-responsive design with bottom navigation
- Nostr integration ready (nostr-tools, relay pool, NIP-71 support)
- Pinia state management for content
- MCP tools configured (Filesystem, Memory, Nostr, Puppeteer)

Components:
- Browse.vue: Main streaming interface with hero and content rows
- ContentRow.vue: Horizontal scrolling film cards with navigation arrows
- VideoPlayer.vue: Custom video player with play/pause, seek, volume, fullscreen
- MobileNav.vue: Bottom tab navigation for mobile devices

Tech Stack:
- Frontend: Vue 3 (Composition API), TypeScript
- Build: Vite 7
- Styling: Tailwind CSS with custom theme
- State: Pinia 3
- Router: Vue Router 4.6
- Protocol: Nostr (nostr-tools 2.22)

Design:
- 4px grid spacing system
- Glass morphism UI components
- Netflix-style hero section with featured content
- Smooth animations and hover effects
- Mobile-first responsive breakpoints
- Dark theme with custom color palette

Content:
- 20+ IndeeHub films with titles, descriptions, categories
- Bitcoin documentaries: God Bless Bitcoin, Dirty Coin, Searching for Satoshi
- Independent films and documentaries
- Working Unsplash CDN images for thumbnails and backdrops

Ready for deployment to Umbrel, Start9, and Archy nodes.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-02 22:19:47 +00:00

225 lines
4.1 KiB
Plaintext

---
description: Performance optimization and bundle size management
alwaysApply: false
globs: **/*.{js,ts,vue,jsx,tsx}
---
# Performance & Optimization
## Performance Targets
- **Bundle Size**: < 200KB gzipped
- **LCP** (Largest Contentful Paint): < 2.5s
- **FID** (First Input Delay): < 100ms
- **Mobile 3G**: Load in under 5s
- **Desktop**: Load in under 2s
- **Animation Frame Rate**: 60fps (16.67ms per frame)
## Bundle Size Optimization
### 1. Code Splitting by Route
```javascript
// Vue Router with lazy loading
const routes = [
{
path: '/',
component: HomePage // Eager loaded
},
{
path: '/projects/:id',
component: () => import('./views/ProjectDetail.vue') // Lazy loaded
}
]
```
### 2. Lazy Load Heavy Components
```javascript
import { defineAsyncComponent } from 'vue'
const HeavyChart = defineAsyncComponent(() =>
import('./components/HeavyChart.vue')
)
```
### 3. Tree Shaking
```javascript
// ✅ Good - Named imports (tree-shakeable)
import { ref, computed } from 'vue'
// ❌ Bad - Default import (not tree-shakeable)
import Vue from 'vue'
```
## Image Optimization
### 1. Use Modern Formats
- **WebP**: 30% smaller than JPEG
- **AVIF**: Even smaller
```html
<picture>
<source srcset="image.avif" type="image/avif">
<source srcset="image.webp" type="image/webp">
<img src="image.jpg" alt="Fallback">
</picture>
```
### 2. Lazy Loading
```html
<img src="image.jpg" loading="lazy" alt="Lazy loaded" />
```
### 3. Responsive Images
```html
<img
srcset="
image-320.jpg 320w,
image-640.jpg 640w,
image-1024.jpg 1024w
"
sizes="(max-width: 640px) 100vw, 50vw"
src="image-640.jpg"
alt="Responsive image"
/>
```
## Font Optimization
### 1. Preload Critical Fonts
```html
<link
rel="preload"
href="/fonts/ProximaNova-Bold.woff2"
as="font"
type="font/woff2"
crossorigin
>
```
### 2. Font Display Strategy
```css
@font-face {
font-family: 'Proxima Nova';
src: url('/fonts/proximanova.woff2') format('woff2');
font-display: swap; /* Show fallback immediately */
}
```
## JavaScript Performance
### 1. Debounce Expensive Operations
```javascript
let timeout
const handleSearch = (event) => {
clearTimeout(timeout)
timeout = setTimeout(() => {
// Perform search
}, 300)
}
```
### 2. Memoization
```javascript
import { computed } from 'vue'
const filteredProjects = computed(() => {
return projects.value.filter(p =>
p.title.includes(searchQuery.value)
)
})
```
## Rendering Performance
### 1. Use CSS Transforms for Animations
```css
/* ❌ Bad - Triggers layout */
.element {
transition: top 0.3s;
}
/* ✅ Good - GPU accelerated */
.element {
transition: transform 0.3s;
}
.element:hover {
transform: translateY(10px);
}
```
### 2. Animate Only Transform and Opacity
- ✅ Animate `transform` and `opacity` only
- ❌ Don't animate `width`, `height`, `top`, `left`
## Vue-Specific Optimizations
### Use `v-once` for Static Content
```vue
<div v-once>
<h1>{{ staticTitle }}</h1>
</div>
```
### Shallow Reactive for Large Objects
```javascript
import { shallowRef } from 'vue'
const projects = shallowRef([...largeArray])
```
### Keep Components Small
Split large components into smaller, focused ones.
## Mobile Performance
### 1. Use Passive Event Listeners
```javascript
element.addEventListener('touchstart', handler, { passive: true })
```
### 2. Test on Real Devices
- Use slow 3G throttling
- Test on mid-range Android devices
- Use Chrome DevTools CPU throttling (4x slowdown)
## Performance Checklist
### Build Time
- ✅ Code split by route
- ✅ Lazy load heavy components
- ✅ Tree shake unused code
- ✅ Minify and compress assets
- ✅ Optimize images (WebP, compression)
### Runtime
- ✅ Debounce expensive operations
- ✅ Memoize computed values
- ✅ Use CSS transforms for animations
- ✅ Avoid layout thrashing
### Network
- ✅ Enable compression (gzip/brotli)
- ✅ Set appropriate cache headers
- ✅ Preload/prefetch resources
### Fonts
- ✅ Preload critical fonts
- ✅ Use font-display: swap
**Remember: Performance is not a one-time task—it's an ongoing practice.**