Lazy load the youtube embed to boost homepage loading times (#1205)
This commit is contained in:
parent
3835856f2b
commit
d0e7fcfc06
4 changed files with 138 additions and 4 deletions
|
@ -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">
|
||||
|
|
51
www/src/components/YouTube.astro
Normal file
51
www/src/components/YouTube.astro
Normal 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>
|
82
www/src/components/YouTube.css
Normal file
82
www/src/components/YouTube.css
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue