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>
This commit is contained in:
224
.cursor/rules/performance-optimization.mdc
Normal file
224
.cursor/rules/performance-optimization.mdc
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
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.**
|
||||
Reference in New Issue
Block a user