enhanced lighthouse report

This commit is contained in:
2026-08-21 19:40:20 -07:00
parent acf97ae05d
commit 6e4074bf95
9 changed files with 103 additions and 50 deletions

View File

@@ -44,6 +44,7 @@
<link rel="dns-prefetch" href="https://videos.pexels.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preconnect" href="https://discord.com" crossorigin>
<meta http-equiv="Content-Security-Policy" content="default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';">
<meta property="og:title" content="Vyla Home - Self-Hosted Desktop Media Center | Serverless Streaming">
@@ -84,34 +85,38 @@
<link rel="apple-touch-icon" href="assets/images/icon.png">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap">
<!-- Critical CSS - Load immediately for above-the-fold content -->
<link rel="stylesheet" href="src/styles/base/tokens.css">
<link rel="stylesheet" href="src/styles/base/reset.css">
<link rel="stylesheet" href="src/styles/base/typography.css">
<link rel="stylesheet" href="src/styles/utilities/layout.css">
<link rel="stylesheet" href="src/styles/utilities/reveal.css">
<link rel="stylesheet" href="src/styles/layout/nav.css">
<link rel="stylesheet" href="src/styles/layout/footer.css">
<link rel="stylesheet" href="src/styles/components/buttons.css">
<link rel="stylesheet" href="src/styles/components/pills.css">
<link rel="stylesheet" href="src/styles/components/stats.css">
<link rel="stylesheet" href="src/styles/components/script-card.css">
<link rel="stylesheet" href="src/styles/components/marquee.css">
<link rel="stylesheet" href="src/styles/components/testimonial-card.css">
<link rel="stylesheet" href="src/styles/components/executors.css">
<link rel="stylesheet" href="src/styles/components/showcase.css">
<link rel="stylesheet" href="src/styles/components/modal.css">
<link rel="stylesheet" href="src/styles/components/partners.css">
<link rel="stylesheet" href="src/styles/components/faq.css">
<link rel="stylesheet" href="src/styles/sections/hero-atmosphere.css">
<link rel="stylesheet" href="src/styles/sections/hero-content.css">
<link rel="stylesheet" href="src/styles/sections/section-base.css">
<link rel="stylesheet" href="src/styles/sections/testimonials.css">
<link rel="stylesheet" href="src/styles/sections/executors.css">
<link rel="stylesheet" href="src/styles/sections/features.css">
<link rel="stylesheet" href="src/styles/sections/showcases.css">
<link rel="stylesheet" href="src/styles/sections/faq-section.css">
<link rel="stylesheet" href="src/styles/sections/cta-banner.css">
<link rel="stylesheet" href="src/styles/utilities/responsive.css">
<!-- Non-critical CSS - Deferred loading for below-the-fold content -->
<link rel="stylesheet" href="src/styles/layout/footer.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/buttons.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/pills.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/stats.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/script-card.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/marquee.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/testimonial-card.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/executors.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/showcase.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/modal.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/partners.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/components/faq.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/sections/section-base.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/sections/testimonials.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/sections/executors.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/sections/features.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/sections/showcases.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/sections/faq-section.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/sections/cta-banner.css" media="print" onload="this.media='all'">
<link rel="stylesheet" href="src/styles/utilities/responsive.css" media="print" onload="this.media='all'">
<script type="application/ld+json">
{
@@ -278,7 +283,8 @@
<div class="logo-image">
<img src="assets/images/header_logo.png" alt="Vyla Home Logo" width="100" height="100"
fetchpriority="high">
fetchpriority="high"
srcset="assets/images/header_logo.png 100w, assets/images/header_logo.png 200w" sizes="100px">
</div>
<h1 id="hero-title" class="hero-title">The Local-First Desktop Media Center</h1>
@@ -392,7 +398,9 @@
<figure class="feature-media">
<img src="assets/images/features/1.png"
alt="Diagram showing datacenter IP throttling bypass with residential network connection"
width="800" height="450" loading="lazy" decoding="async">
width="800" height="450" loading="lazy" decoding="async"
srcset="assets/images/features/1.png 800w, assets/images/features/1.png 400w"
sizes="(max-width: 768px) 400px, 800px">
</figure>
<div class="feature-copy">
<h3 class="section-title-lg feature-title">No Datacenter Throttling</h3>
@@ -407,7 +415,9 @@
<figure class="feature-media">
<img src="assets/images/features/2.png"
alt="Diagram showing decentralized architecture eliminating single point of failure"
width="800" height="450" loading="lazy" decoding="async">
width="800" height="450" loading="lazy" decoding="async"
srcset="assets/images/features/2.png 800w, assets/images/features/2.png 400w"
sizes="(max-width: 768px) 400px, 800px">
</figure>
<div class="feature-copy">
<h3 class="section-title-lg feature-title">No Single Point of Failure</h3>
@@ -422,7 +432,9 @@
<figure class="feature-media">
<img src="assets/images/features/3.png"
alt="Illustration of encrypted local vault with hardware profile key" width="800"
height="450" loading="lazy" decoding="async">
height="450" loading="lazy" decoding="async"
srcset="assets/images/features/3.png 800w, assets/images/features/3.png 400w"
sizes="(max-width: 768px) 400px, 800px">
</figure>
<div class="feature-copy">
<h3 class="section-title-lg feature-title">Encrypted Local Vault</h3>
@@ -437,7 +449,9 @@
<figure class="feature-media">
<img src="assets/images/features/4.png"
alt="Interface showing automated over-the-air update process" width="800" height="450"
loading="lazy" decoding="async">
loading="lazy" decoding="async"
srcset="assets/images/features/4.png 800w, assets/images/features/4.png 400w"
sizes="(max-width: 768px) 400px, 800px">
</figure>
<div class="feature-copy">
<h3 class="section-title-lg feature-title">Automated OTA Updates</h3>
@@ -452,7 +466,9 @@
<figure class="feature-media">
<img src="assets/images/features/5.png"
alt="Interface showing rich media discovery with curated collections and 4K content"
width="800" height="450" loading="lazy" decoding="async">
width="800" height="450" loading="lazy" decoding="async"
srcset="assets/images/features/5.png 800w, assets/images/features/5.png 400w"
sizes="(max-width: 768px) 400px, 800px">
</figure>
<div class="feature-copy">
<h3 class="section-title-lg feature-title">Rich Discovery & Curated Media</h3>
@@ -467,7 +483,9 @@
<figure class="feature-media">
<img src="assets/images/features/6.png"
alt="Interface showing customizable theme and layout options" width="800" height="450"
loading="lazy" decoding="async">
loading="lazy" decoding="async"
srcset="assets/images/features/6.png 800w, assets/images/features/6.png 400w"
sizes="(max-width: 768px) 400px, 800px">
</figure>
<div class="feature-copy">
<h3 class="section-title-lg feature-title">Customizable Interface</h3>
@@ -545,12 +563,12 @@
<footer class="footer" role="contentinfo">
<div class="footer-content">
<div class="footer-section">
<h4>Vyla Home</h4>
<h3>Vyla Home</h3>
<p>A solo passion project built for resilient, serverless, personal entertainment playback. Run locally,
own your experience.</p>
</div>
<div class="footer-section">
<h4>Join our Discord</h4>
<h3>Join our Discord</h3>
<nav class="social-links" aria-label="Social media links">
<a href="https://discord.gg/5eqRhKeywG" target="_blank" rel="noopener noreferrer"
aria-label="Join our Discord community">
@@ -559,7 +577,7 @@
</nav>
</div>
<div class="footer-section">
<h4>Our Gitlab</h4>
<h3>Our Gitlab</h3>
<p><a href="https://gitlab.com/vyla-entertainment/home" target="_blank" rel="noopener noreferrer">Vyla
Entertainment</a>
</p>

View File

@@ -1,3 +1,5 @@
# Vyla Home
Vyla Home is a self-hosted desktop media center that bypasses datacenter blocking, ISP throttling, and cloud downtime. Experience self-hosted streaming, 4K movies, TV shows, and anime with complete privacy and zero server dependencies.
[Home](https://vyla.cc/)

View File

@@ -2,11 +2,13 @@
{
"name": "FMHY",
"logo": "assets/images/partners/fmhy.png",
"logoSmall": "assets/images/partners/fmhy.png",
"link": "https://fmhy.net"
},
{
"name": "r/Piracy",
"logo": "assets/images/partners/piracy.png",
"logoSmall": "assets/images/partners/piracy.png",
"link": "https://reddit.com/r/Piracy"
}
]

View File

@@ -3,36 +3,42 @@
"name": "ZENITH The Great (Ash Fan)",
"handle": "@zenithrifle",
"text": "oh god the ui is so goood",
"avatar": "/assets/images/testimonials/zenithrifle.png"
"avatar": "/assets/images/testimonials/zenithrifle.png",
"avatarSmall": "/assets/images/testimonials/zenithrifle.png"
},
{
"name": "Light",
"handle": "@acideetdeforme",
"text": "Youre highk a goat for doing ts without ads",
"avatar": "/assets/images/testimonials/acideetdeforme.png"
"avatar": "/assets/images/testimonials/acideetdeforme.png",
"avatarSmall": "/assets/images/testimonials/acideetdeforme.png"
},
{
"name": "char",
"handle": "@chariachtus",
"text": "I find Vyla as the best by far",
"avatar": "/assets/images/testimonials/chariachtus.png"
"avatar": "/assets/images/testimonials/chariachtus.png",
"avatarSmall": "/assets/images/testimonials/chariachtus.png"
},
{
"name": "amri",
"handle": "@snorer",
"text": "who is the owner of such greatness",
"avatar": "/assets/images/testimonials/snorer.png"
"avatar": "/assets/images/testimonials/snorer.png",
"avatarSmall": "/assets/images/testimonials/snorer.png"
},
{
"name": "Bee",
"handle": "@block.tale.adict",
"text": "this is sickk",
"avatar": "/assets/images/testimonials/block.tale.adict.png"
"avatar": "/assets/images/testimonials/block.tale.adict.png",
"avatarSmall": "/assets/images/testimonials/block.tale.adict.png"
},
{
"name": "lucky-mucky",
"handle": "@lucky_mucky_",
"text": "ur like the best owner ever❤️",
"avatar": "/assets/images/testimonials/lucky_mucky_.png"
"avatar": "/assets/images/testimonials/lucky_mucky_.png",
"avatarSmall": "/assets/images/testimonials/lucky_mucky_.png"
}
]

View File

@@ -11,14 +11,23 @@ function initials(name) {
export function createTestimonialCard(testimonial) {
const card = createElement('div', 'testimonial-card');
const avatar = testimonial.avatar
? `<img src="${testimonial.avatar}" alt="" width="34" height="34" loading="lazy" decoding="async">`
: initials(testimonial.name || '?');
let avatarHTML;
if (testimonial.avatar) {
if (testimonial.avatarSmall) {
avatarHTML = `<img src="${testimonial.avatarSmall}" alt="" width="34" height="34" loading="lazy" decoding="async"
srcset="${testimonial.avatarSmall} 60w, ${testimonial.avatar} 120w" sizes="60px">`;
} else {
avatarHTML = `<img src="${testimonial.avatar}" alt="" width="34" height="34" loading="lazy" decoding="async">`;
}
} else {
avatarHTML = initials(testimonial.name || '?');
}
card.innerHTML = `
<div class="testimonial-top">
<div class="testimonial-user">
<div class="testimonial-avatar">${avatar}</div>
<div class="testimonial-avatar">${avatarHTML}</div>
<div class="testimonial-names">
<span class="testimonial-name">${testimonial.name}</span>
<span class="testimonial-handle">${testimonial.handle || ''}</span>

View File

@@ -4,9 +4,22 @@ import { observeReveals } from '../animations/reveal-observer.js';
function createPartnerItem(partner) {
const item = createElement('div', 'partner-item reveal');
let imgHTML;
if (partner.logo) {
if (partner.logoSmall) {
imgHTML = `<img src="${partner.logoSmall}" alt="${partner.name}" width="128" height="128" loading="lazy" decoding="async"
srcset="${partner.logoSmall} 64w, ${partner.logo} 128w" sizes="64px">`;
} else {
imgHTML = `<img src="${partner.logo}" alt="${partner.name}" width="128" height="128" loading="lazy" decoding="async">`;
}
} else {
imgHTML = '';
}
const inner = partner.link
? `<a href="${partner.link}" target="_blank" rel="noopener noreferrer"><img src="${partner.logo}" alt="${partner.name}" width="128" height="128" loading="lazy" decoding="async"></a>`
: `<img src="${partner.logo}" alt="${partner.name}" width="128" height="128" loading="lazy" decoding="async">`;
? `<a href="${partner.link}" target="_blank" rel="noopener noreferrer">${imgHTML}</a>`
: imgHTML;
item.innerHTML = inner;
return item;
}

View File

@@ -22,15 +22,14 @@ body {
line-height: 1.5;
overflow-x: hidden;
position: relative;
scrollbar-width: none;
-ms-overflow-style: none;
min-height: 100%;
min-height: 100dvh;
background: var(--color-bg);
}
body::-webkit-scrollbar {
display: none;
width: 0;
background: transparent;
}
a {
@@ -66,4 +65,4 @@ ol {
::selection {
background: var(--color-fg);
color: var(--color-bg);
}
}

View File

@@ -51,6 +51,10 @@
touch-action: manipulation;
}
.hero-cta:hover {
transform: scale(0.97);
}
.hero-cta:active {
transform: scale(0.97);
}

View File

@@ -20,8 +20,7 @@
}
.hero-title {
font-size: clamp(2rem, calc(2rem + 2 * ((100vw - 23.4375rem) / 66.5625)), 4rem);
line-height: clamp(2.28rem, calc(2.28rem + 1.72 * ((100vw - 23.4375rem) / 66.5625)), 4rem);
font-size: 2.3rem;
letter-spacing: -.03em;
font-weight: 500;
text-wrap: balance;
@@ -41,7 +40,7 @@
font-size: 0.8rem;
margin: 1rem auto 0;
line-height: 1.5;
width: 80%;
width: 50%;
}
.hero-description a {
@@ -66,13 +65,14 @@
@media (max-width: 768px) {
.hero-description {
margin-top: 0rem;
width: 80%;
}
}
@media (orientation: landscape) and (max-height: 600px) {
.hero-title {
margin-bottom: 0rem;
font-size: 2.7rem;
font-size: 2rem;
}
.hero-container {