Add performance optimizations: gzip, cache headers, WOFF2 fonts, lazy loading
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 38s

Enable gzip compression in nginx, add cache-control headers for static assets,
convert fonts to WOFF2 with font-display swap, preload fonts, add lazy loading
to below-fold images, and remove unused font files.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-26 02:29:37 +00:00
parent 7798b54391
commit 474f14b1e5
17 changed files with 64 additions and 8 deletions

View File

@@ -24,6 +24,22 @@ http {
text/javascript mjs; text/javascript mjs;
} }
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff2
application/font-woff2;
server { server {
listen 80; listen 80;
server_name $DOMAIN www.$DOMAIN; server_name $DOMAIN www.$DOMAIN;
@@ -61,6 +77,24 @@ http {
ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;
# Vite hashed assets - immutable, cache 1 year
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Fonts - cache 30 days
location /fonts/ {
expires 30d;
add_header Cache-Control "public";
}
# Images - cache 7 days
location /img/ {
expires 7d;
add_header Cache-Control "public";
}
location /uploads/ { location /uploads/ {
alias /uploads/; alias /uploads/;
add_header X-Content-Type-Options nosniff always; add_header X-Content-Type-Options nosniff always;

View File

@@ -24,6 +24,22 @@ http {
text/javascript mjs; text/javascript mjs;
} }
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 256;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml
font/woff2
application/font-woff2;
server { server {
listen 80; listen 80;
server_name $DOMAIN www.$DOMAIN; server_name $DOMAIN www.$DOMAIN;

View File

@@ -5,6 +5,8 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>AF</title> <title>AF</title>
<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/CreatoDisplay-Bold.woff2" as="font" type="font/woff2" crossorigin />
</head> </head>
<body id="app"> <body id="app">
<script type="module" src="/src/main.js"></script> <script type="module" src="/src/main.js"></script>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -33,16 +33,18 @@
/* FONTS */ /* FONTS */
@font-face { @font-face {
font-family: "big_noodle_titling"; font-family: "big_noodle_titling";
src: url("/fonts/big_noodle_titling.ttf") format("truetype"); src: url("/fonts/big_noodle_titling.woff2") format("woff2");
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face { @font-face {
font-family: "CreatoDisplay"; font-family: "CreatoDisplay";
src: url("/fonts/CreatoDisplay-Bold.otf") format("opentype"); src: url("/fonts/CreatoDisplay-Bold.woff2") format("woff2");
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: swap;
} }
/* END OF FONTS */ /* END OF FONTS */

View File

@@ -21,7 +21,7 @@ const { gitFeed: feed, loaded } = storeToRefs(homeData);
class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden" class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden"
> >
<h3>Last git activity</h3> <h3>Last git activity</h3>
<img :src="feed.avatarUrl" alt="User avatar" class="avatar" /> <img :src="feed.avatarUrl" alt="User avatar" class="avatar" loading="lazy" />
<Link :href="feed.repoUrl"> <Link :href="feed.repoUrl">
<h3>repo: {{ feed.repoName }}</h3> <h3>repo: {{ feed.repoName }}</h3>
</Link> </Link>

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" /> <img src="/img/memes/epic.jpeg" 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

@@ -5,7 +5,7 @@
> >
<h1>404</h1> <h1>404</h1>
<RouterLink to="/" class="bdr-2"> <RouterLink to="/" class="bdr-2">
<img src="/img/memes/epic.jpeg" /> <img src="/img/memes/epic.jpeg" loading="lazy" />
</RouterLink> </RouterLink>
<h1>Click her, she will take you home</h1> <h1>Click her, she will take you home</h1>
</div> </div>

View File

@@ -226,16 +226,18 @@ import Project from "./Project.vue";
/* Fonts */ /* Fonts */
@font-face { @font-face {
font-family: "big_noodle_titling"; font-family: "big_noodle_titling";
src: url("/fonts/big_noodle_titling.ttf") format("truetype"); src: url("/fonts/big_noodle_titling.woff2") format("woff2");
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: swap;
} }
@font-face { @font-face {
font-family: "CreatoDisplay"; font-family: "CreatoDisplay";
src: url("/fonts/CreatoDisplay-Bold.otf") format("opentype"); src: url("/fonts/CreatoDisplay-Bold.woff2") format("woff2");
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: swap;
} }
/* Variables */ /* Variables */

View File

@@ -84,7 +84,7 @@ onUnmounted(() => {
alt="jacobbarron.xyz" alt="jacobbarron.xyz"
/> />
</Link> </Link>
<img v-for="src in srcs" :src="src" /> <img v-for="src in srcs" :src="src" loading="lazy" />
</div> </div>
</Touchscreen> </Touchscreen>
</template> </template>