Asset Optimization
Relevant source files
The following files were used as context for generating this wiki page:
Asset optimization in Dreamcats ensures a high-performance, responsive card gaming experience by minimizing image payloads and implementing aggressive caching and preloading strategies. The system focuses on providing high-quality visuals for retina displays while maintaining fast load times through modern image formats and Service Worker integration.
The optimization pipeline spans from build-time script processing to run-time asset delivery and browser-side caching. This ensures that the "dreamy" aesthetic of the game does not compromise technical performance.
Image Processing Pipeline
The project utilizes a dedicated optimization script to transform raw card imagery into web-optimized formats. This script targets specific card files and converts them into WebP and optimized PNG fallbacks.
Optimization Strategy
The optimize-images.ts script uses the sharp library to process assets. It targets a width of 280px, which serves as 2x retina support for a maximum 140px display size. The pipeline generates two versions of every asset:
- WebP Version: High quality (85) with maximum compression effort (6) for modern browsers.
- PNG Fallback: Optimized with palette-based compression and high quality (90).
Sources: scripts/optimize-images.ts:1-74
Data Flow for Image Optimization
The following diagram illustrates how the optimize-images.ts script processes the raw assets into the final public directory.
Sources: scripts/optimize-images.ts:24-64
Runtime Asset Delivery
The cardAssets.ts utility manages how the frontend requests and serves these optimized images. It includes feature detection to prioritize the best available format.
Feature Detection and Path Resolution
The system checks for WebP support at runtime using a canvas-based approach. If the browser supports WebP, it appends the .webp extension; otherwise, it falls back to .png. All asset requests are appended with an ASSET_VERSION (currently v3) to handle cache busting.
| Component | Function | Description |
|---|---|---|
checkWebPSupport | Feature Detection | Detects WebP support via canvas.toDataURL. |
getAssetPath | Path Resolution | Constructs paths with correct extension and versioning. |
preloadCardImages | Performance | Pre-instantiates Image objects for all card variations. |
getCardAsset | Logic | Maps card values and special actions to file names. |
Sources: src/lib/cardAssets.ts:4-60
Caching and PWA Integration
The project uses vite-plugin-pwa and Workbox to manage offline capabilities and persistent caching of assets.
Workbox Caching Strategies
The configuration defines specific behaviors for different asset types to maximize performance.
- Google Fonts:
CacheFirststrategy, persisting for 1 year. - Images:
CacheFirststrategy with a limit of 60 entries, persisting for 30 days. - Convex API:
NetworkFirststrategy with a 10-second timeout to ensure real-time data while allowing for brief connectivity drops.
Sources: vite.config.ts:41-95
Critical Preloading
To prevent "flicker" during the initial game flip or card reveal, the index.html explicitly preloads the card back asset as a high-priority image.
<link rel="preload" as="image" type="image/webp" href="/assets/back.webp?v3" />
Sources: index.html:56, src/lib/cardAssets.ts:54-68
Performance Guardrails in UI Components
The GameCard component implements specific technical strategies to ensure smooth rendering and interaction.
- Static Mode: The component can render without 3D transforms (
staticMode) to avoid GPU glitches in specific environments or for static piles. - Backface Visibility: Uses
backface-hiddenandtransform-style-3dto manage the physical rendering of the two-sided card. - Cheat Prevention: Real card data (front assets) is only rendered into the DOM when
isFaceUpis true, preventing users from inspecting the DOM to see hidden cards.
Sources: src/components/Card.tsx:10-21, src/components/Card.tsx:128-142, src/components/Card.tsx:184-205
Build and Dependencies
The optimization infrastructure relies on specific development dependencies and build scripts defined in the project configuration.
| Dependency | Purpose |
|---|---|
sharp | High-performance image processing (Node.js). |
vite-plugin-pwa | PWA and Service Worker generation. |
gsap | High-performance animations for card movements. |
Sources: package.json:115, package.json:52, vite.config.ts:6-10
The build process is orchestrated to ensure types are checked before the Vite build proceeds, maintaining the integrity of asset references.
Sources: package.json:8
Conclusion
Asset optimization in Dreamcats is a multi-layered system that balances visual fidelity with performance. By combining build-time image compression, runtime format detection, and aggressive Service Worker caching, the application ensures that the card game remains fluid and responsive across varying network conditions and device capabilities.