perf: gzip compression, browser caching, font preloading, and eliminate css import waterfall
This commit is contained in:
parent
cde87db064
commit
1aaf656612
4 changed files with 82 additions and 10 deletions
66
.htaccess
66
.htaccess
|
|
@ -9,6 +9,72 @@ RewriteEngine On
|
||||||
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
||||||
</IfModule>
|
</IfModule>
|
||||||
|
|
||||||
|
# MIME-Types für moderne Web-Assets
|
||||||
|
<IfModule mod_mime.c>
|
||||||
|
AddType font/woff2 .woff2
|
||||||
|
AddType font/woff .woff
|
||||||
|
AddType image/webp .webp
|
||||||
|
AddType image/svg+xml .svg .svgz
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Performance: Gzip-Kompression (mod_deflate)
|
||||||
|
<IfModule mod_deflate.c>
|
||||||
|
AddOutputFilterByType DEFLATE text/plain
|
||||||
|
AddOutputFilterByType DEFLATE text/html
|
||||||
|
AddOutputFilterByType DEFLATE text/xml
|
||||||
|
AddOutputFilterByType DEFLATE text/css
|
||||||
|
AddOutputFilterByType DEFLATE text/javascript
|
||||||
|
AddOutputFilterByType DEFLATE application/xml
|
||||||
|
AddOutputFilterByType DEFLATE application/xhtml+xml
|
||||||
|
AddOutputFilterByType DEFLATE application/rss+xml
|
||||||
|
AddOutputFilterByType DEFLATE application/javascript
|
||||||
|
AddOutputFilterByType DEFLATE application/x-javascript
|
||||||
|
AddOutputFilterByType DEFLATE application/json
|
||||||
|
AddOutputFilterByType DEFLATE image/svg+xml
|
||||||
|
AddOutputFilterByType DEFLATE font/opentype
|
||||||
|
AddOutputFilterByType DEFLATE font/otf
|
||||||
|
AddOutputFilterByType DEFLATE font/ttf
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
# Performance: Browser-Caching (mod_expires & mod_headers)
|
||||||
|
<IfModule mod_expires.c>
|
||||||
|
ExpiresActive On
|
||||||
|
ExpiresDefault "access plus 1 month"
|
||||||
|
|
||||||
|
# Webfonts (1 Jahr)
|
||||||
|
ExpiresByType font/woff2 "access plus 1 year"
|
||||||
|
ExpiresByType font/woff "access plus 1 year"
|
||||||
|
ExpiresByType font/ttf "access plus 1 year"
|
||||||
|
ExpiresByType font/otf "access plus 1 year"
|
||||||
|
ExpiresByType application/font-woff2 "access plus 1 year"
|
||||||
|
|
||||||
|
# Bilder & Icons (1 Monat bis 1 Jahr)
|
||||||
|
ExpiresByType image/x-icon "access plus 1 year"
|
||||||
|
ExpiresByType image/vnd.microsoft.icon "access plus 1 year"
|
||||||
|
ExpiresByType image/webp "access plus 1 month"
|
||||||
|
ExpiresByType image/png "access plus 1 month"
|
||||||
|
ExpiresByType image/jpeg "access plus 1 month"
|
||||||
|
ExpiresByType image/gif "access plus 1 month"
|
||||||
|
ExpiresByType image/svg+xml "access plus 1 month"
|
||||||
|
|
||||||
|
# CSS & JavaScript (1 Woche)
|
||||||
|
ExpiresByType text/css "access plus 1 week"
|
||||||
|
ExpiresByType application/javascript "access plus 1 week"
|
||||||
|
ExpiresByType text/javascript "access plus 1 week"
|
||||||
|
|
||||||
|
# HTML & dynamische Daten nicht aggressiv cachen
|
||||||
|
ExpiresByType text/html "access plus 0 seconds"
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
|
<IfModule mod_headers.c>
|
||||||
|
<FilesMatch "\.(ico|jpe?g|png|gif|webp|svg|woff2?|ttf|otf)$">
|
||||||
|
Header set Cache-Control "public, max-age=31536000, immutable"
|
||||||
|
</FilesMatch>
|
||||||
|
<FilesMatch "\.(css|js)$">
|
||||||
|
Header set Cache-Control "public, max-age=604800, stale-while-revalidate=86400"
|
||||||
|
</FilesMatch>
|
||||||
|
</IfModule>
|
||||||
|
|
||||||
# Interne PHP-, Vendor- und Template-Verzeichnisse vor direktem Webzugriff sperren
|
# Interne PHP-, Vendor- und Template-Verzeichnisse vor direktem Webzugriff sperren
|
||||||
RewriteRule ^(home|philcore)/(app|core|views|src)/ - [F,L]
|
RewriteRule ^(home|philcore)/(app|core|views|src)/ - [F,L]
|
||||||
RewriteRule ^(.*/)?vendor/ - [F,L]
|
RewriteRule ^(.*/)?vendor/ - [F,L]
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
@import "app.css";
|
|
||||||
:root {
|
:root {
|
||||||
--bg-base: #020617;
|
--bg-base: #020617;
|
||||||
}
|
}
|
||||||
|
|
@ -43,27 +42,30 @@ body {
|
||||||
background: #f43f5e;
|
background: #f43f5e;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
/* Animations */
|
/* Animations (GPU Accelerated) */
|
||||||
@keyframes blob-bounce {
|
@keyframes blob-bounce {
|
||||||
0%, 100% { transform: translate(0, 0) scale(1); }
|
0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
|
||||||
33% { transform: translate(30px, -50px) scale(1.1); }
|
33% { transform: translate3d(30px, -50px, 0) scale(1.1); }
|
||||||
66% { transform: translate(-20px, 20px) scale(0.9); }
|
66% { transform: translate3d(-20px, 20px, 0) scale(0.9); }
|
||||||
}
|
}
|
||||||
@keyframes particle-drift {
|
@keyframes particle-drift {
|
||||||
0% { transform: translateY(0) rotate(0deg); opacity: 0; }
|
0% { transform: translate3d(0, 0, 0) rotate(0deg); opacity: 0; }
|
||||||
50% { opacity: 0.5; }
|
50% { opacity: 0.5; }
|
||||||
100% { transform: translateY(-100vh) rotate(360deg); opacity: 0; }
|
100% { transform: translate3d(0, -100vh, 0) rotate(360deg); opacity: 0; }
|
||||||
}
|
}
|
||||||
@keyframes invader-patrol {
|
@keyframes invader-patrol {
|
||||||
0%, 100% { transform: translateX(-12px); }
|
0%, 100% { transform: translate3d(-12px, 0, 0); }
|
||||||
50% { transform: translateX(12px); }
|
50% { transform: translate3d(12px, 0, 0); }
|
||||||
}
|
}
|
||||||
.animate-blob {
|
.animate-blob {
|
||||||
animation: blob-bounce 25s infinite alternate ease-in-out;
|
animation: blob-bounce 25s infinite alternate ease-in-out;
|
||||||
filter: blur(80px);
|
filter: blur(80px);
|
||||||
|
will-change: transform;
|
||||||
|
backface-visibility: hidden;
|
||||||
}
|
}
|
||||||
.animate-invader {
|
.animate-invader {
|
||||||
animation: invader-patrol 4s infinite ease-in-out;
|
animation: invader-patrol 4s infinite ease-in-out;
|
||||||
|
will-change: transform;
|
||||||
}
|
}
|
||||||
.particle {
|
.particle {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
|
@ -73,6 +75,7 @@ body {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
animation: particle-drift var(--p-duration) infinite linear;
|
animation: particle-drift var(--p-duration) infinite linear;
|
||||||
animation-delay: var(--p-delay);
|
animation-delay: var(--p-delay);
|
||||||
|
will-change: transform, opacity;
|
||||||
}
|
}
|
||||||
/* UI Components */
|
/* UI Components */
|
||||||
.bullshit-terminal {
|
.bullshit-terminal {
|
||||||
|
|
|
||||||
|
|
@ -96,5 +96,5 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="/js/main.js"></script>
|
<script src="/js/main.js" defer></script>
|
||||||
<?php require_once __DIR__ . '/inc/footer.php'; ?>
|
<?php require_once __DIR__ . '/inc/footer.php'; ?>
|
||||||
|
|
@ -22,6 +22,9 @@ $_SESSION['particles_initialized'] = true;
|
||||||
<meta property="og:title" content="<?= htmlspecialchars($pageTitle) ?>">
|
<meta property="og:title" content="<?= htmlspecialchars($pageTitle) ?>">
|
||||||
<meta property="og:description" content="Developer, Designer, Punkrocker, Problem Solver.">
|
<meta property="og:description" content="Developer, Designer, Punkrocker, Problem Solver.">
|
||||||
<link rel="canonical" href="<?= htmlspecialchars($canonicalUrl) ?>">
|
<link rel="canonical" href="<?= htmlspecialchars($canonicalUrl) ?>">
|
||||||
|
<link rel="preload" href="/fonts/outfit-v15-latin-regular.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
<link rel="preload" href="/fonts/jetbrains-mono-v24-latin-regular.woff2" as="font" type="font/woff2" crossorigin>
|
||||||
|
<link rel="stylesheet" href="/css/app.css">
|
||||||
<link rel="stylesheet" href="/css/style.css">
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue