When the admin panel is implemented (see Phase 5 of Issue #81), every image uploaded through it must be automatically converted to WebP before being stored on the server, regardless of the original format (JPG, PNG, GIF, etc.). This eliminates the risk of heavy unoptimized images accumulating on the server and keeps the portfolio lightweight by default.
Architecture context: Firebase is used only as the data layer (Firestore stores document references like imageUrl: "https://server.com/img/cel.webp"). Images themselves are hosted on the project owner's own server. Firebase never touches image files.
The conversion happens client-side before upload — using the Canvas API or a lightweight library — so no server-side processing is needed. This keeps the pipeline simple, free, and fast.
Scope
Constraints
- Must work entirely in the browser — no server/cloud function processing
- Must handle: JPG, JPEG, PNG, GIF, BMP, TIFF → WebP
- Fallback: if the browser doesn't support WebP encoding (very rare in modern browsers), fall back to compressed JPEG at quality 80
- The original file is never stored — only the optimized version on the server
When the admin panel is implemented (see Phase 5 of Issue #81), every image uploaded through it must be automatically converted to WebP before being stored on the server, regardless of the original format (JPG, PNG, GIF, etc.). This eliminates the risk of heavy unoptimized images accumulating on the server and keeps the portfolio lightweight by default.
Architecture context: Firebase is used only as the data layer (Firestore stores document references like
imageUrl: "https://server.com/img/cel.webp"). Images themselves are hosted on the project owner's own server. Firebase never touches image files.The conversion happens client-side before upload — using the Canvas API or a lightweight library — so no server-side processing is needed. This keeps the pipeline simple, free, and fast.
Scope
browser-image-compression) to convert any uploaded image to WebP format before sending it to the serverthumbnail(400px) andfull(1200px) versions on upload for responsive<img srcset>Constraints