Improve PageSpeed accessibility, SEO, and performance scores
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 34s

Add alt attributes, width/height for CLS, aria-labels, meta description,
preconnect hints, LCP fetchpriority, and sound/stamp cache headers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-26 02:38:08 +00:00
parent 474f14b1e5
commit 3c9d19d185
12 changed files with 27 additions and 9 deletions

View File

@@ -118,6 +118,13 @@ http {
location = /img/stamps/mine.gif { location = /img/stamps/mine.gif {
add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Origin *;
expires 7d;
add_header Cache-Control "public";
}
location /sound/ {
expires 7d;
add_header Cache-Control "public";
} }
location $BACKEND_ENDPOINT { location $BACKEND_ENDPOINT {

View File

@@ -3,7 +3,10 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Adam French's personal website" />
<title>AF</title> <title>AF</title>
<link rel="preconnect" href="https://i.scdn.co" crossorigin />
<link rel="preconnect" href="https://cdn.akamai.steamstatic.com" crossorigin />
<link rel="icon" type="/img/x-icon" href="/img/favicon.ico" /> <link rel="icon" type="/img/x-icon" href="/img/favicon.ico" />
<link rel="preload" href="/fonts/big_noodle_titling.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/big_noodle_titling.woff2" as="font" type="font/woff2" crossorigin />
<link rel="preload" href="/fonts/CreatoDisplay-Bold.woff2" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="/fonts/CreatoDisplay-Bold.woff2" as="font" type="font/woff2" crossorigin />

View File

@@ -152,6 +152,7 @@ onUnmounted(() => {
<img <img
v-if="isImageUrl(message.fileUrl)" v-if="isImageUrl(message.fileUrl)"
:src="message.fileUrl" :src="message.fileUrl"
alt="Uploaded image"
loading="lazy" loading="lazy"
class="w-full max-w-full max-h-48 rounded block" class="w-full max-w-full max-h-48 rounded block"
/> />
@@ -170,7 +171,7 @@ onUnmounted(() => {
</div> </div>
</div> </div>
<div> <div>
<input v-model="messageInput" @keyup.enter="sendMessage" /> <input v-model="messageInput" @keyup.enter="sendMessage" aria-label="Chat message" />
<input <input
ref="fileInput" ref="fileInput"
type="file" type="file"

View File

@@ -7,7 +7,7 @@ import Button from "@/components/input/Button.vue";
<audio/> <audio/>
<div class="musicPlayerGrid"> <div class="musicPlayerGrid">
<div class="album_cover"> <div class="album_cover">
<img src="/img/Untitled.png"></img> <img src="/img/Untitled.png" alt=""></img>
</div> </div>
<div class="controls"> <div class="controls">
<div class="sliders"> <div class="sliders">

View File

@@ -1,12 +1,12 @@
<template> <template>
<div v-if="streamLive" class="overflow-hidden"> <div v-if="streamLive" class="overflow-hidden">
<Header>Radio</Header> <Header>Radio</Header>
<img src="/img/tmpen31z3pe.PNG" /> <img src="/img/tmpen31z3pe.PNG" alt="Radio" width="176" height="177" />
<audio controls :src="streamUrl" ref="audio"></audio> <audio controls :src="streamUrl" ref="audio"></audio>
</div> </div>
<div v-else> <div v-else>
<Header>Radio</Header> <Header>Radio</Header>
<img src="/img/tmpen31z3pe.PNG" /> <img src="/img/tmpen31z3pe.PNG" alt="Radio" width="176" height="177" />
<div class="m-1 text-center"> <div class="m-1 text-center">
<p>Radio is offline. Message for info!</p> <p>Radio is offline. Message for info!</p>
<Button class="w-full" @click="checkStream()">Check Stream</Button> <Button class="w-full" @click="checkStream()">Check Stream</Button>

View File

@@ -41,7 +41,7 @@ onUnmounted(() => {
<Header v-if="currentComment"> <Header v-if="currentComment">
{{ currentComment }} {{ currentComment }}
</Header> </Header>
<img :src="currentUrl" alt="Image Viewer" loading="lazy" /> <img :src="currentUrl" alt="Image Viewer" fetchpriority="high" />
</div> </div>
</Transition> </Transition>
</div> </div>

View File

@@ -75,6 +75,7 @@ function playFinishedSound() {
type="range" type="range"
min="0" min="0"
max="59" max="59"
aria-label="Minutes"
/> />
<p>{{ minutesInput }}m</p> <p>{{ minutesInput }}m</p>
</div> </div>
@@ -85,6 +86,7 @@ function playFinishedSound() {
type="range" type="range"
min="0" min="0"
max="59" max="59"
aria-label="Seconds"
/> />
<p>{{ secondsInput }}s</p> <p>{{ secondsInput }}s</p>
</div> </div>

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="a4page-portrait bdr-1 flex flex-col relative overflow-scroll"> <div class="a4page-portrait bdr-1 flex flex-col relative overflow-scroll">
<RouterLink to="/" class="bdr-2"> <RouterLink to="/" class="bdr-2">
<img src="/img/memes/epic.jpeg" loading="lazy" /> <img src="/img/memes/epic.jpeg" alt="" loading="lazy" />
</RouterLink> </RouterLink>
<h1>Click her, she will take you home</h1> <h1>Click her, she will take you home</h1>
<span style="height: 100px"></span> <span style="height: 100px"></span>

View File

@@ -68,6 +68,9 @@ import Steam from "./Steam.vue";
<div class="sidebar-image"> <div class="sidebar-image">
<img <img
src="/img/memes/fire-woman.gif" src="/img/memes/fire-woman.gif"
alt=""
width="178"
height="178"
class="border-tertiary border" class="border-tertiary border"
loading="lazy" loading="lazy"
/> />

View File

@@ -37,7 +37,7 @@ onUnmounted(() => {
class="flex flex-col items-center" class="flex flex-col items-center"
> >
<Header>Listening To</Header> <Header>Listening To</Header>
<img :src="song.track.album.images[0].url" /> <img :src="song.track.album.images[0].url" :alt="song.track.album.name + ' album art'" width="217" height="217" />
<p class="text-center"> <p class="text-center">
<strong>Song:</strong> {{ song.track.name }} <strong>Song:</strong> {{ song.track.name }}
</p> </p>

View File

@@ -76,7 +76,7 @@ onUnmounted(() => {
<Touchscreen ref="touchscreen"> <Touchscreen ref="touchscreen">
<div class="flex flex-wrap tst"> <div class="flex flex-wrap tst">
<Link bare href="https://www.adam-french.co.uk"> <Link bare href="https://www.adam-french.co.uk">
<img src="https://www.adam-french.co.uk/img/stamps/mine.gif" /> <img src="https://www.adam-french.co.uk/img/stamps/mine.gif" alt="adam-french.co.uk" />
</Link> </Link>
<Link bare href="https://jacobbarron.xyz"> <Link bare href="https://jacobbarron.xyz">
<img <img
@@ -84,7 +84,7 @@ onUnmounted(() => {
alt="jacobbarron.xyz" alt="jacobbarron.xyz"
/> />
</Link> </Link>
<img v-for="src in srcs" :src="src" loading="lazy" /> <img v-for="src in srcs" :src="src" :alt="src.split('/').pop().split('.')[0]" loading="lazy" />
</div> </div>
</Touchscreen> </Touchscreen>
</template> </template>

View File

@@ -64,6 +64,8 @@ function formatHours(minutes) {
<img <img
:src="game.headerImageUrl" :src="game.headerImageUrl"
:alt="game.name" :alt="game.name"
width="145"
height="68"
class="game-img" class="game-img"
/> />
<p class="text-center"> <p class="text-center">