feat: implement automatic image optimization with Astro Assets

- Configure content collections to use image() helper for type-safe image references
- Replace all <img> tags with <Image> component from astro:assets
- Migrate images from /public to /src/assets for automatic optimization
- Update blog posts to use relative paths in frontmatter (../../assets/photos/)
- Remove unused images and duplicates from /public folder
- Update Footer component to use optimized SVG icons
- Clean up manifest.json to use favicon.ico instead of deleted photos

Performance improvements:
- remote.jpg: 1.8MB → 128KB (93% reduction)
- me.png: 71KB → 12KB (83% reduction)
- Automatic WebP conversion
- Tree-shaking: only used images are optimized

/public folder reduced from 2.3MB to 32KB (only essential files)
Build output: 2.2MB with fully optimized images ready for S3 deployment
This commit is contained in:
Lorenzo Iovino 2026-01-08 17:40:19 +01:00
parent e3f7a631eb
commit 049c20a4b2
47 changed files with 632 additions and 419 deletions

View file

@ -1,10 +1,13 @@
---
import type { CollectionEntry } from "astro:content";
import { getEntry } from "astro:content";
import { Image } from "astro:assets";
import Footer from "../components/Footer.astro";
import Navbar from "../components/Navbar.astro";
import BaseLayout from "../layouts/BaseLayout.astro";
import "../styles/prose.css";
import linkedinIcon from "../assets/linkedin.svg";
import githubIcon from "../assets/github.svg";
type BioEntry = CollectionEntry<"bio">;
@ -20,7 +23,6 @@ const { Content } = await bioEntry.render();
<BaseLayout
title="Lorenzo Iovino >> Bio"
description="Biography and life story of Lorenzo Iovino"
canonicalUrl="https://www.lorenzoiovino.com/bio"
>
<Navbar />
<div class="min-h-screen pt-16 bg-secondary">
@ -56,12 +58,12 @@ const { Content } = await bioEntry.render();
rel="noopener noreferrer"
class="inline-flex items-center px-10 py-5 bg-white hover:bg-gray-50 text-gray-700 font-semibold text-lg rounded-xl transition-all duration-200 shadow-lg hover:shadow-xl border-2 border-gray-200 hover:border-gray-300 transform hover:-translate-y-1 hover:scale-105"
>
<img
src="/linkedin.svg"
<Image
src={linkedinIcon}
alt="LinkedIn"
class="h-6 w-6 mr-3 opacity-80"
width="24"
height="24"
width={24}
height={24}
/>
LinkedIn
</a>
@ -71,12 +73,12 @@ const { Content } = await bioEntry.render();
rel="noopener noreferrer"
class="inline-flex items-center px-10 py-5 bg-white hover:bg-gray-50 text-gray-700 font-semibold text-lg rounded-xl transition-all duration-200 shadow-lg hover:shadow-xl border-2 border-gray-200 hover:border-gray-300 transform hover:-translate-y-1 hover:scale-105"
>
<img
src="/github.svg"
<Image
src={githubIcon}
alt="GitHub"
class="h-6 w-6 mr-3 opacity-80"
width="24"
height="24"
width={24}
height={24}
/>
GitHub
</a>