01/02/2024
Incorporar vídeos do YouTube em sites é uma tarefa comum, mas pode tornar o site mais pesado. O método tradicional carrega o player mesmo se ninguém clicar para assistir ao vídeo, aumentando o tempo de carregamento da página.
Neste tutorial, abordaremos uma forma mais leve de incorporar vídeos do YouTube. Em vez de carregar o player de imediato, ele será carregado apenas se o usuário clicar para assistir. Essa técnica não só melhora a velocidade da página, mas também oferece mais controle ao usuário.
O código abaixo incorpora dois vídeos do YouTube na página, sem que o player tenha que ser carregado a cada acesso.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>YouTube</title>
</head>
<body style="font-family: sans-serif;">
<youtube-video video-id="_RZm7E9E-CM" style="width: 720px;"></youtube-video>
<script>
class YouTubeVideo extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(this.getStyle());
this.addEventListener('click', () => {
this.classList.add('clicked');
this.shadowRoot.appendChild(this.getIframe());
});
}
getStyle() {
const style = document.createElement('style');
style.textContent = `
:host {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
max-width: 100%;
aspect-ratio: 16/9;
cursor: pointer;
background: silver url('https://img.youtube.com/vi/${this.getAttribute('video-id')}/0.jpg') no-repeat center / cover;
}
:host:before {
content: '';
width: 15%;
aspect-ratio: 1;
border-radius: 50%;
background: white url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 140 122.88"><polygon points="140,60.97 32,122.88 32,0 140,60.97" fill="black" /></svg>') no-repeat center / 50% 50%;
filter: drop-shadow(0px 0px 16px rgba(0,0,0,0.3));
transition: all 0.3s ease;
}
:host(.clicked):before {
opacity: 0;
}`;
return style;
}
getIframe() {
const iframe = document.createElement('iframe');
iframe.setAttribute('frameborder', '0');
iframe.setAttribute('allow', 'autoplay');
iframe.setAttribute('allowfullscreen', '');
iframe.style.cssText = `position: absolute; top: 0; left: 0; width: 100%; height: 100%;`;
const params = new URLSearchParams({ autoplay: 1, modestbranding: 1, rel: 0, iv_load_policy: 3, showinfo: 0 });
['controls', 'start', 'end', 'loop', 'playlist'].forEach(
attr => { if (this.hasAttribute(attr)) params.set(attr, this.getAttribute(attr)); }
);
iframe.src = `https://www.youtube-nocookie.com/embed/${this.getAttribute('video-id')}?${params}`;
iframe.onload = () => this.style.background = 'transparent';
return iframe;
}
}
customElements.define('youtube-video', YouTubeVideo);
</script>
</body>
</html>
Ao clicar na imagem abaixo, o player do YouTube será carregado e o vídeo será reproduzido automaticamente.
<youtube-video>
A tag <youtube-video>
representa o componente personalizado. O atributo video-id
deve ser usado para especificar o ID do vídeo do YouTube que se deseja exibir. Por exemplo:
<youtube-video video-id="dQw4w9WgXcQ" style="width: 720px;"></youtube-video>
YouTubeVideo
O Web Component YouTubeVideo
é definido estendendo a classe HTMLElement
. A função constructor
configura o Shadow DOM e adiciona o evento click
.
class YouTubeVideo extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.appendChild(this.getStyle());
this.addEventListener('click', () => {
this.classList.add('clicked');
this.shadowRoot.appendChild(this.getIframe());
});
}
// Métodos getStyle e getIframe são definidos aqui
}
customElements.define('youtube-video', YouTubeVideo);
:host
e getStyle
O método getStyle
cria um elemento de estilo que contém as regras CSS para estilizar o componente. Utilizamos o pseudo-seletor :host
para definir estilos diretamente no componente <youtube-video>
. Isso inclui configurações de posição, flexbox, aspect ratio, e a imagem de fundo que é a miniatura do vídeo do YouTube.
getStyle() {
const style = document.createElement('style');
style.textContent = `
:host {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
max-width: 100%;
aspect-ratio: 16/9;
cursor: pointer;
background: silver url('https://img.youtube.com/vi/${this.getAttribute('video-id')}/0.jpg') no-repeat center / cover;
}
:host:before {
content: '';
width: 15%;
aspect-ratio: 1;
border-radius: 50%;
background: white url('data:image/svg+xml;utf8,') no-repeat center / 50% 50%;
filter: drop-shadow(0px 0px 16px rgba(0,0,0,0.3));
transition: all 0.3s ease;
}
:host(.clicked):before {
opacity: 0;
}`;
return style;
}
<iframe>
com getIframe
O método getIframe
cria e configura um <iframe>
que será usado para carregar o vídeo do YouTube. Este método configura o iframe
para iniciar o vídeo automaticamente (autoplay), permite o modo tela cheia, e define os parâmetros da URL do vídeo. O iframe
é posicionado para cobrir completamente o componente, permitindo que o vídeo seja exibido no espaço designado.
getIframe() {
const iframe = document.createElement('iframe');
iframe.setAttribute('frameborder', '0');
iframe.setAttribute('allow', 'autoplay');
iframe.setAttribute('allowfullscreen', '');
iframe.style.cssText = 'position: absolute; top: 0; left: 0; width: 100%; height: 100%;';
const params = new URLSearchParams({ autoplay: 1, modestbranding: 1, rel: 0, iv_load_policy: 3, showinfo: 0 });
['controls', 'start', 'end', 'loop', 'playlist'].forEach(attr => {
if (this.hasAttribute(attr)) params.set(attr, this.getAttribute(attr));
});
iframe.src = `https://www.youtube-nocookie.com/embed/${this.getAttribute('video-id')}?${params}`;
iframe.onload = () => this.style.background = 'transparent';
return iframe;
}
Ao usar o Web Component <youtube-video>
para incorporar vídeos do YouTube, temos uma alternativa mais eficiente em comparação com o método de incorporação padrão. Esta abordagem melhora significativamente o tempo de carregamento da página ao carregar o player do YouTube somente após o usuário clicar para iniciar a reprodução do vídeo.
Esperamos que as técnicas e métodos apresentados aqui inspirem você a explorar mais sobre Web Components e a aplicá-los em seus próprios projetos web.