@justinribeiro/lite-youtube
Advanced tools
Comparing version 1.3.0 to 1.3.1
@@ -1,17 +0,1 @@ | ||
/** | ||
* | ||
* The shadowDom / Intersection Observer version of Paul's concept: | ||
* https://github.com/paulirish/lite-youtube-embed | ||
* | ||
* A lightweight YouTube embed. Still should feel the same to the user, just | ||
* MUCH faster to initialize and paint. | ||
* | ||
* Thx to these as the inspiration | ||
* https://storage.googleapis.com/amp-vs-non-amp/youtube-lazy.html | ||
* https://autoplay-youtube-player.glitch.me/ | ||
* | ||
* Once built it, I also found these (👍👍): | ||
* https://github.com/ampproject/amphtml/blob/master/extensions/amp-youtube | ||
* https://github.com/Daugilas/lazyYT https://github.com/vb/lazyframe | ||
*/ | ||
export declare class LiteYTEmbed extends HTMLElement { | ||
@@ -42,47 +26,9 @@ shadowRoot: ShadowRoot; | ||
get params(): string; | ||
/** | ||
* Define our shadowDOM for the component | ||
*/ | ||
private setupDom; | ||
/** | ||
* Parse our attributes and fire up some placeholders | ||
*/ | ||
private setupComponent; | ||
/** | ||
* Lifecycle method that we use to listen for attribute changes to period | ||
* @param {*} name | ||
* @param {*} oldVal | ||
* @param {*} newVal | ||
*/ | ||
attributeChangedCallback(name: string, oldVal: unknown, newVal: unknown): void; | ||
/** | ||
* Inject the iframe into the component body | ||
* @param {boolean} isIntersectionObserver | ||
*/ | ||
private addIframe; | ||
/** | ||
* Setup the placeholder image for the component | ||
*/ | ||
private initImagePlaceholder; | ||
/** | ||
* Setup the Intersection Observer to load the iframe when scrolled into view | ||
*/ | ||
private initIntersectionObserver; | ||
/** | ||
* Add a <link rel={preload | preconnect} ...> to the head | ||
* @param {string} kind | ||
* @param {string} url | ||
* @param {string} as | ||
*/ | ||
private static addPrefetch; | ||
/** | ||
* Begin preconnecting to warm up the iframe load Since the embed's network | ||
* requests load within its iframe, preload/prefetch'ing them outside the | ||
* iframe will only cause double-downloads. So, the best we can do is warm up | ||
* a few connections to origins that are in the critical path. | ||
* | ||
* Maybe `<link rel=preload as=document>` would work, but it's unsupported: | ||
* http://crbug.com/593267 But TBH, I don't think it'll happen soon with Site | ||
* Isolation and split caches adding serious complexity. | ||
*/ | ||
private static warmConnections; | ||
@@ -89,0 +35,0 @@ } |
@@ -1,17 +0,1 @@ | ||
/** | ||
* | ||
* The shadowDom / Intersection Observer version of Paul's concept: | ||
* https://github.com/paulirish/lite-youtube-embed | ||
* | ||
* A lightweight YouTube embed. Still should feel the same to the user, just | ||
* MUCH faster to initialize and paint. | ||
* | ||
* Thx to these as the inspiration | ||
* https://storage.googleapis.com/amp-vs-non-amp/youtube-lazy.html | ||
* https://autoplay-youtube-player.glitch.me/ | ||
* | ||
* Once built it, I also found these (👍👍): | ||
* https://github.com/ampproject/amphtml/blob/master/extensions/amp-youtube | ||
* https://github.com/Daugilas/lazyYT https://github.com/vb/lazyframe | ||
*/ | ||
export class LiteYTEmbed extends HTMLElement { | ||
@@ -77,5 +61,2 @@ constructor() { | ||
} | ||
/** | ||
* Define our shadowDOM for the component | ||
*/ | ||
setupDom() { | ||
@@ -91,2 +72,5 @@ const shadowDom = this.attachShadow({ mode: 'open' }); | ||
padding-bottom: calc(100% / (16 / 9)); | ||
--lyt-animation: all 0.2s cubic-bezier(0, 0, 0.2, 1); | ||
--lyt-play-btn-default: #212121; | ||
--lyt-play-btn-hover: #f00; | ||
} | ||
@@ -98,2 +82,3 @@ | ||
height: 100%; | ||
left: 0; | ||
} | ||
@@ -114,28 +99,26 @@ | ||
top: 0; | ||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==); | ||
background-position: top; | ||
background-repeat: repeat-x; | ||
background-image: linear-gradient(180deg, #111 -20%, transparent 90%); | ||
height: 60px; | ||
padding-bottom: 50px; | ||
width: 100%; | ||
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1); | ||
transition: var(--lyt-animation); | ||
z-index: 1; | ||
} | ||
/* play button */ | ||
.lty-playbtn { | ||
#playButton { | ||
width: 70px; | ||
height: 46px; | ||
background-color: #212121; | ||
background-color: var(--lyt-play-btn-hover); | ||
z-index: 1; | ||
opacity: 0.8; | ||
border-radius: 14%; /* TODO: Consider replacing this with YT's actual svg. Eh. */ | ||
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1); | ||
border-radius: 14%; | ||
transition: var(--lyt-animation); | ||
border: 0; | ||
} | ||
#frame:hover .lty-playbtn { | ||
background-color: #f00; | ||
#frame:hover > #playButton { | ||
background-color: var(--lyt-play-btn-hover); | ||
opacity: 1; | ||
} | ||
/* play button triangle */ | ||
.lty-playbtn:before { | ||
#playButton:before { | ||
content: ''; | ||
@@ -146,4 +129,5 @@ border-style: solid; | ||
} | ||
.lty-playbtn, | ||
.lty-playbtn:before { | ||
#playButton, | ||
#playButton:before { | ||
position: absolute; | ||
@@ -156,8 +140,8 @@ top: 50%; | ||
/* Post-click styles */ | ||
.lyt-activated { | ||
.activated { | ||
cursor: unset; | ||
} | ||
#frame.lyt-activated::before, | ||
.lyt-activated .lty-playbtn { | ||
#frame.activated::before, | ||
#frame.activated > #playButton { | ||
display: none; | ||
@@ -172,3 +156,3 @@ } | ||
</picture> | ||
<button class="lty-playbtn"></button> | ||
<button id="playButton"></button> | ||
</div> | ||
@@ -182,7 +166,4 @@ `; | ||
}; | ||
this.domRefPlayButton = shadowDom.querySelector('.lty-playbtn'); | ||
this.domRefPlayButton = shadowDom.querySelector('#playButton'); | ||
} | ||
/** | ||
* Parse our attributes and fire up some placeholders | ||
*/ | ||
setupComponent() { | ||
@@ -196,8 +177,2 @@ this.initImagePlaceholder(); | ||
} | ||
/** | ||
* Lifecycle method that we use to listen for attribute changes to period | ||
* @param {*} name | ||
* @param {*} oldVal | ||
* @param {*} newVal | ||
*/ | ||
attributeChangedCallback(name, oldVal, newVal) { | ||
@@ -209,5 +184,4 @@ switch (name) { | ||
this.setupComponent(); | ||
// if we have a previous iframe, remove it and the activated class | ||
if (this.domRefFrame.classList.contains('lyt-activated')) { | ||
this.domRefFrame.classList.remove('lyt-activated'); | ||
if (this.domRefFrame.classList.contains('activated')) { | ||
this.domRefFrame.classList.remove('activated'); | ||
this.shadowRoot.querySelector('iframe').remove(); | ||
@@ -223,9 +197,4 @@ this.isIframeLoaded = false; | ||
} | ||
/** | ||
* Inject the iframe into the component body | ||
* @param {boolean} isIntersectionObserver | ||
*/ | ||
addIframe(isIntersectionObserver = false) { | ||
if (!this.isIframeLoaded) { | ||
// Don't autoplay the intersection observer injection, it's weird | ||
const autoplay = isIntersectionObserver ? 0 : 1; | ||
@@ -246,3 +215,3 @@ const wantsNoCookie = this.noCookie ? '-nocookie' : ''; | ||
this.domRefFrame.insertAdjacentHTML('beforeend', iframeHTML); | ||
this.domRefFrame.classList.add('lyt-activated'); | ||
this.domRefFrame.classList.add('activated'); | ||
this.isIframeLoaded = true; | ||
@@ -258,7 +227,3 @@ this.dispatchEvent(new CustomEvent('liteYoutubeIframeLoaded', { | ||
} | ||
/** | ||
* Setup the placeholder image for the component | ||
*/ | ||
initImagePlaceholder() { | ||
// we don't know which image type to preload, so warm the connection | ||
LiteYTEmbed.addPrefetch('preconnect', 'https://i.ytimg.com/'); | ||
@@ -274,5 +239,2 @@ const posterUrlWebp = `https://i.ytimg.com/vi_webp/${this.videoId}/${this.posterQuality}.webp`; | ||
} | ||
/** | ||
* Setup the Intersection Observer to load the iframe when scrolled into view | ||
*/ | ||
initIntersectionObserver() { | ||
@@ -295,8 +257,2 @@ const options = { | ||
} | ||
/** | ||
* Add a <link rel={preload | preconnect} ...> to the head | ||
* @param {string} kind | ||
* @param {string} url | ||
* @param {string} as | ||
*/ | ||
static addPrefetch(kind, url, as) { | ||
@@ -312,24 +268,8 @@ const linkElem = document.createElement('link'); | ||
} | ||
/** | ||
* Begin preconnecting to warm up the iframe load Since the embed's network | ||
* requests load within its iframe, preload/prefetch'ing them outside the | ||
* iframe will only cause double-downloads. So, the best we can do is warm up | ||
* a few connections to origins that are in the critical path. | ||
* | ||
* Maybe `<link rel=preload as=document>` would work, but it's unsupported: | ||
* http://crbug.com/593267 But TBH, I don't think it'll happen soon with Site | ||
* Isolation and split caches adding serious complexity. | ||
*/ | ||
static warmConnections() { | ||
if (LiteYTEmbed.isPreconnected) | ||
return; | ||
// Host that YT uses to serve JS needed by player, per amp-youtube | ||
LiteYTEmbed.addPrefetch('preconnect', 'https://s.ytimg.com'); | ||
// The iframe document and most of its subresources come right off | ||
// youtube.com | ||
LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube.com'); | ||
// The botguard script is fetched off from google.com | ||
LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com'); | ||
// TODO: Not certain if these ad related domains are in the critical path. | ||
// Could verify with domain-specific throttling. | ||
LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net'); | ||
@@ -341,4 +281,3 @@ LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net'); | ||
LiteYTEmbed.isPreconnected = false; | ||
// Register custom element | ||
customElements.define('lite-youtube', LiteYTEmbed); | ||
//# sourceMappingURL=lite-youtube.js.map |
@@ -28,3 +28,3 @@ { | ||
"license": "MIT", | ||
"version": "1.3.0", | ||
"version": "1.3.1", | ||
"main": "lite-youtube.js", | ||
@@ -31,0 +31,0 @@ "module": "lite-youtube.js", |
@@ -48,3 +48,3 @@ [![npm version](https://badge.fury.io/js/@justinribeiro%2Flite-youtube.svg)](https://badge.fury.io/js/@justinribeiro%2Flite-youtube) [![min+gzip](https://badgen.net/bundlephobia/minzip/@justinribeiro/lite-youtube)](https://bundlephobia.com/result?p=@justinribeiro/lite-youtube) [![](https://data.jsdelivr.com/v1/package/npm/@justinribeiro/lite-youtube/badge)](https://www.jsdelivr.com/package/npm/@justinribeiro/lite-youtube) | ||
```html | ||
<script type="module" src="https://cdn.jsdelivr.net/npm/@justinribeiro/lite-youtube@1.3.0/lite-youtube.js"></script> | ||
<script type="module" src="https://cdn.jsdelivr.net/npm/@justinribeiro/lite-youtube@1.3.1/lite-youtube.js"></script> | ||
``` | ||
@@ -51,0 +51,0 @@ |
Sorry, the diff of this file is not supported yet
36302
294