FrontendRendimientolite-youtube

YouTube Embeds

Incrustar un <iframe> de YouTube directamente en un post cargaría ~700 KB de JavaScript, bloquearía el renderizado y dispararía peticiones de tracking antes de que el usuario hiciera nada. Usamos lite-youtube para evitar todo eso.

Análisis de Rendimiento

iframe nativo

  • ~700 KB de JS descargado por video
  • Bloquea el hilo principal repetidamente
  • Scripts de tracking disparados de inmediato
  • Retrasa severamente el LCP de la página

lite-youtube (Nyuseek)

  • ~5 KB total en toda la página
  • Solo carga una miniatura estática inicial
  • Cero ejecución JS hasta la interacción
  • Impacto nulo en métricas Core Web Vitals
Resultado medido en ProducciónPáginas con 3 videos embebidos mediante lite-youtube mantienen una puntuación Lighthouse Performance ≥ 95. Usando iframes nativos, la misma página caía a 40–55 puntos en dispositivos móviles.

Mecanismo de Inserción

El editor (Tiptap) agrega automáticamente el atributo data-embed="true" al enlace cuando el redactor usa el botón de "Insertar video". El HTML que se guarda en la base de datos tiene esta forma:

<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" data-embed="true">
  [Rick Astley - Never Gonna Give You Up]
</a>
Atributo Obligatorio: El atributo data-embed="true" es estricto para YouTube. Sin él, el enlace se trata como un hipervínculo estándar. Esto permite mencionar un video en texto sin forzar su incrustación visual.

Formatos Soportados

FormatoEjemplo de URLEstado
Watch estándaryoutube.com/watch?v=IDSoportado
URL cortayoutu.be/IDSoportado
Shortsyoutube.com/shorts/IDSoportado
Liveyoutube.com/live/IDSoportado
URL con timestampyoutube.com/watch?v=ID&t=120sSoportado (Extrae ID)

Instalación de Dependencias

Instalar Web Component

Para implementar este sistema necesitas instalar el paquete de lite-youtube:

pnpm add @justinribeiro/lite-youtube

Pipeline de Renderizado (SSR)

1

Carga Inicial HTML

El SSR recibe el HTML del post tal como está guardado en la base de datos.

2

Detección Regex

Busca todos los <a> que tengan data-embed="true" y una URL de YouTube, extrayendo el ID.

3

Reemplazo Estático

Sustituye el enlace por el Web Component <lite-youtube> en el servidor (cero fetch).

4

Hidratación Condicional

El script de lite-youtube se inyecta en el cliente solo si la bandera hasYoutube es verdadera.

Expresiones Regulares Core

Para asegurar que atrapamos el enlace sin importar el orden de los atributos (que puede variar según el editor):

// data-embed ANTES del href
const youtubeEmbedRegex = /(?:<p>)?\s*<a\s+(?:[^>]*?\s+)?data-embed=["']true["']
  (?:[^>]*?\s+)?href=["'](URL_REGEX)["'][^>]*>\[([^\]]+)\]<\/a>\s*(?:<\/p>)?/gi;

// href ANTES del data-embed
const youtubeEmbedRegex2 = /(?:<p>)?\s*<a\s+(?:[^>]*?\s+)?href=["'](URL_REGEX)["']
  (?:[^>]*?\s+)?data-embed=["']true["'][^>]*>\[([^\]]+)\]<\/a>\s*(?:<\/p>)?/gi;

El identificador siempre corresponde al grupo de captura 2 (11 caracteres):

([a-zA-Z0-9_-]{11})

Output Final Renderizado

<div class="my-8 rounded-3xl overflow-hidden shadow-sm border border-surface-100 bg-surface-50">
  <lite-youtube videoid="dQw4w9WgXcQ"></lite-youtube>
</div>

Y la inyección de script única en el footer del layout:

{hasYoutube && <script>import '@justinribeiro/lite-youtube';</script>}

Diagnóstico de Errores Comunes

El video aparece como un simple enlace

Causa: Falta data-embed="true" en la DB.

Solución: Re-insertar el video desde el editor usando la herramienta específica de Embed.

No carga la miniatura (Espacio en blanco)

Causa: El Web Component no se hidrató.

Solución: Verificar que la bandera hasYoutube se está activando y el script importado no esté bloqueado.

Muestra imagen por defecto gris

Causa: El Regex falló en aislar exactamente 11 caracteres para el ID.

Solución: Inspeccionar el videoid="" resultante en el DOM para corregir la extracción.