Lazy load the youtube embed to boost homepage loading times (#1205)

This commit is contained in:
Caleb Jasik 2021-08-24 01:18:05 -05:00 committed by GitHub
parent 3835856f2b
commit d0e7fcfc06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 138 additions and 4 deletions

View file

@ -35,5 +35,6 @@ const { title, description, canonicalURL } = Astro.props;
<meta property="twitter:image" content="https://astro.build/social.jpg?v=1" />
<!-- Fonts -->
<link rel="dns-prefetch" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;700&family=IBM+Plex+Sans:wght@400;700&display=swap">

View file

@ -0,0 +1,51 @@
---
const onload = `
const link = (rel, href) => {
document.querySelector(\`[rel='\${rel}'][href='\${href}']\`) || document.head.append(
Object.assign(
document.createElement('link'),
{
rel,
href: href
}
)
)
};
const preconnect = () => {
link('preconnect', 'https://googleads.g.doubleclick.net');
link('preconnect', 'https://static.doubleclick.net');
link('preconnect', 'https://www.google.com');
link('preconnect', 'https://www.youtube-nocookie.com');
};
const host = this.parentNode;
const v = host.getAttribute('v');
const iframe = Object.assign(
document.createElement('iframe'),
{
src: \`https://www.youtube-nocookie.com/embed/\${v}?autoplay=1\`,
allow: 'accelerometer;autoplay;encrypted-media;gyroscope;picture-in-picture',
allowFullscreen: true,
}
);
const button = Object.assign(
document.createElement('button'),
{
style: \`background-image:url('https://i.ytimg.com/vi/\${v}/hqdefault.jpg')\`,
onpointerenter: preconnect,
onfocus: preconnect,
onclick(event) {
event.currentTarget.replaceWith(iframe)
},
}
);
button.setAttribute('aria-label', host.getAttribute('alt'));
host.replaceChildren(button);
`.replace(/[\n\r\t]+/g, '')
---
<lite-youtube {...Astro.props}>
<a href={`https://www.youtube.com/watch?v=${Astro.props.v}`}>
<img src={`https://i.ytimg.com/vi/${Astro.props.v}/hqdefault.jpg`} loading="lazy" alt={Astro.props.alt} />
</a><script type="module" src="data:text/javascript," onload={onload}></script>
</lite-youtube>

View file

@ -0,0 +1,82 @@
lite-youtube {
background: #000;
contain: content;
display: block;
max-width: 720px;
position: relative;
}
/* responsive iframe with a 16:9 aspect ratio (thanks https://css-tricks.com/responsive-iframes/) */
lite-youtube::after {
content: '';
display: block;
padding-bottom: calc(100% / (16 / 9));
}
lite-youtube > iframe {
border: 0;
height: 100%;
inset: 0;
position: absolute;
width: 100%;
}
/* YT's actual play button svg */
lite-youtube > a,
lite-youtube > button {
cursor: pointer;
display: block;
height: 100%;
inset: 0;
position: absolute;
width: 100%;
}
lite-youtube > a > img {
display: block;
height: 100%;
object-fit: cover;
width: 100%;
}
lite-youtube > a::after,
lite-youtube > button::after {
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 68 48'%3E%3Cpath fill='red' fill-opacity='.8' d='M66.5 7.7c-.8-2.9-2.5-5.4-5.4-6.2C55.8.1 34 0 34 0S12.2.1 6.9 1.6c-3 .7-4.6 3.2-5.4 6.1a89.6 89.6 0 000 32.5c.8 3 2.5 5.5 5.4 6.3C12.2 47.9 34 48 34 48s21.8-.1 27.1-1.6c3-.7 4.6-3.2 5.4-6.1C68 35 68 24 68 24s0-11-1.5-16.3z'/%3E%3Cpath fill='%23fff' d='M45 24L27 14v20'/%3E%3C/svg%3E");
display: block;
width: 68px;
height: 48px;
position: absolute;
inset: calc(50% - 68px / 2) calc(50% - 48px / 2) auto auto;
transition: filter 0.1s cubic-bezier(0, 0, 0.2, 1);
}
lite-youtube > button {
background: #000 50% 50% / cover;
border: none;
}
/* gradient */
lite-youtube button::before {
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAQAAAC58SIOAAAAaklEQVR42nWOUQrAMAhD1e7+B9kZ1zqYKAk6yMfLa8Ca3CbbxL+cTJgNNeDhTZmdQXb24/KAPNNFjDf2CQSMJGCVViveAKuy1AZYFaCqcrVkA4NgGeTKYlg/Jvhio/w6LuvQNV1U3sS31wvH7lU36biAMgAAAABJRU5ErkJggg==')
top repeat-x;
content: '';
display: block;
height: 60px;
padding-bottom: 50px;
position: absolute;
top: 0;
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
width: 100%;
}
lite-youtube > button::after {
filter: grayscale(100%);
}
lite-youtube:hover > button::after,
lite-youtube button:focus::after {
filter: none;
}

View file

@ -6,6 +6,8 @@ import Logo from '../components/Logo.astro';
import Article from '../components/Article.astro';
import Tagline from '../components/Tagline.astro';
import MainHeader from '../components/MainHeader.astro';
import YouTube from '../components/YouTube.astro';
import "../components/YouTube.css";
let title = 'Astro';
let description = 'Build faster websites with less client-side JavaScript';
@ -26,9 +28,7 @@ let lang = 'en';
<MainHeader />
<Article>
<div class="videoWrapper">
<iframe width="560" height="315" src="https://www.youtube.com/embed/dsTXcSeAZq8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
<YouTube v="dsTXcSeAZq8" alt="Astro in 100 Seconds" />
<Tagline />
@ -90,7 +90,7 @@ let lang = 'en';
background:rgba(255, 255, 255, 0.1);
margin-bottom: 1rem;
}
.videoWrapper iframe {
.videoWrapper > iframe {
position: absolute;
top: 0;
left: 0;