Los Web Components están bien
(nolanlawson.com)- El debate sobre los web components no se trata de elegir solo entre máximo rendimiento y estándares de la plataforma, y ya de entrada es exagerado asumir que deben reemplazar a todos los frameworks de JavaScript
- Los Custom Elements tienen overhead porque usan el DOM como interfaz, pero en productos reales no solo se evalúa el rendimiento, sino también la mantenibilidad, seguridad, usabilidad y accesibilidad
- El costo de soporte de web components en los frameworks puede absorberse con algunas comprobaciones simples, y que algo sea una función estándar no significa que todos los frameworks deban adoptarla necesariamente
- Los web components tienen debilidades en server-side rendering (SSR), accesibilidad y parte de la interoperabilidad, por lo que siguen existiendo casos donde React, Solid y Svelte son más adecuados
- En entornos donde son importantes las apps con renderizado del lado del cliente, los marketplaces de componentes y la retrocompatibilidad a largo plazo, como en Salesforce, los web components pueden ser una opción realista
El punto de partida del debate y la posición del autor
- El debate reciente continúa a partir de “Web Components Are Not the Future” de Ryan Carniato y “Web Components Are Not the Future — They’re the Present” de Cory LaViska
- La cuestión no es atacar al bando contrario, sino ver si desarrolladores con restricciones distintas pueden encontrar puntos en común
- Ryan Carniato es muy valorado por su trabajo en Solid y en el diseño de frameworks y rendimiento que se refleja en
js-framework-benchmark - Los web components también tienen áreas de uso reales vinculadas con implementaciones de frameworks, creación de componentes, el Web Components Community Group, el grupo Accessibility Object Model y el trabajo en shadow DOM, custom elements y accesibilidad
Rendimiento: el costo del DOM es real, pero no lo es todo
- La debilidad básica de los web components es que se basan en Custom Elements
- Como toda la interfaz debe pasar por el DOM, eso genera overhead de rendimiento
- Si el objetivo es tener el framework más rápido en términos absolutos, hay que reducir al máximo los nodos del DOM, y bajo ese criterio los web components salen en desventaja
- Aun así, el rendimiento no es el único criterio en el desarrollo de software
- También hay que considerar mantenibilidad, seguridad, usabilidad y accesibilidad
- Si no se renderizan atributos
aria-*, el renderizado del DOM puede ser un poco más rápido, pero esos atributos pueden ser necesarios para una interfaz accesible - Las microoptimizaciones como que un bucle
forsea más rápido que.forEach()o quevarsea más rápido queconst/letnormalmente no compensan el costo que implican
- Minimizar nodos del DOM es la idea central de la virtualization
- Incluso si no es la opción más rápida, a veces un enfoque más simple es suficiente
components as elementstampoco es lo óptimo, pero no siempre hace falta apuntar a lo óptimo
- Usar juntos custom elements creados con distintos frameworks también tiene valor en el trabajo real
- Puede ser necesario migrar gradualmente del Framework A al Framework B
- También puede haber casos donde se deban combinar varios micro frontends
- No será la interfaz más rápida, pero puede ser el trade-off necesario
- En el rendimiento web real son más comunes otros puntos de mejora de bajo costo, como el layout thrashing, los waterfalls de red o los rerenderizados innecesarios
- Competencias como
js-framework-benchmarkson interesantes para quienes crean frameworks, pero no siempre son decisivas en productos comunes - Si se trabaja en un entorno con recursos limitados donde cada milisegundo importa, también es válido optar por descartar los web components
- Competencias como
Costo de soporte en frameworks y libertad de elección
- El autor no está de acuerdo con la idea de que soportar web components tenga un costo excesivo para quienes crean frameworks
- La detección de props y attributes puede resolverse con una comprobación
prop in element - Emitir web components puede ser incómodo, pero no es algo que todos los frameworks deban hacer obligatoriamente
- Vue 2 usó una web component wrapper library aparte, y Remount existe sin intervención del equipo de React
- La detección de props y attributes puede resolverse con una comprobación
- Se puede crear un gran framework incluso ignorando funciones añadidas a la plataforma web desde 2011
- jQuery v1 todavía funciona en muchos sitios web
- Como los equipos de rendimiento de navegadores optimizan patrones usados por desarrolladores web del pasado, el código antiguo incluso puede volverse más rápido en navegadores nuevos
- Elegir adoptar funciones modernas de la plataforma web trae consigo nuevas consideraciones
- Funciones como
Symbol,Proxyy Promises entran en la misma categoría - Gracias a la retrocompatibilidad de la web, el código escrito hoy puede seguir funcionando dentro de 10 años
- Funciones como
- También es totalmente válido que existan frameworks que no tengan interés en los web components o no quieran soportarlos
- Se puede construir toda la UI con web components
- También se puede mezclar solo una parte con HTML web components
- También se puede optar por no usarlos en absoluto
- Incluso un framework de “no web components” puede ganarse sus seguidores
El estándar es un punto de referencia, no una obligación
- Cuando una función se vuelve estándar, los desarrolladores tienden a tomarla como comparación base
- Quien crea componentes debe decidir si su
<slot>debe comportarse como el<slot>nativo - También debe elegir si usar
IntersectionObservero<img loading="lazy">, o crear su propia abstracción
- Quien crea componentes debe decidir si su
- Los estándares proporcionan un punto de referencia común y un vocabulario compartido
- Dan una base para comparar y contrastar enfoques distintos
- Pero que algo sea estándar no significa que haya que usarlo sí o sí
- En la web conviven funciones que no es necesario usar y APIs antiguas
- APIs deprecated como
document.domain,withy<frame>siguen estando soportadas - Las funciones de la plataforma web pueden elegirse, ignorarse o descartarse
- APIs deprecated como
Dónde encajan los web components y dónde no
- Los web components hacen bien muchas cosas, pero no son una herramienta para reemplazar a todos los frameworks de JavaScript
- Entre sus debilidades están el server-side rendering (SSR), la accesibilidad y parte de la interoperabilidad
- Todavía hay muchas situaciones donde frameworks como React, Solid o Svelte brillan más
- Decir que “los web components no son el futuro” puede ser cierto para ciertos desarrolladores o proyectos
- En el fondo del debate está el hecho de que distintas personas construyen cosas distintas bajo restricciones distintas
El caso de Salesforce y el juicio práctico
- Salesforce muestra un entorno donde los web components pueden encajar muy bien
- Crea apps con renderizado del lado del cliente
- Tiene su propio marketplace de componentes
- Necesita garantías estrictas de retrocompatibilidad
- Sus periodos de soporte se miden en años y, en algunos casos, en décadas
- Si no se dan esas condiciones, puede que no haga falta construir toda la UI con web components, shadow DOM y toda la configuración asociada
- En la plataforma web conviven juegos, proyectos artísticos y apps SaaS empresariales creados con funciones muy diversas, como WebGL, Wasm y Service Workers
- Cuando se añade una nueva función a la plataforma, en vez de limitar la creatividad, aumentan las oportunidades de expresión de formas antes impensables
- Como lecturas complementarias, también están el artículo de Lea Verou y el artículo de Baldur Bjarnason
1 comentarios
Opiniones de Hacker News
Intenté entender el artículo citado “Web Components Are Not the Future”, pero no encontré muchos argumentos convincentes.
El estado actual de los frameworks de frontend es un desastre, y no quiero aprender magia (
useState,createSignal, etc.) que no se puede entender sin antes leer un framework complejo o su documentación.Si uno empieza con Web Components, se siente intuitivo, y también obtiene capacidades que no existen en otros lados, como el aislamiento de Shadow DOM.
Creo que lo único que vale la pena conservar de la era de React es JSX, así que hice una biblioteca que usa Web Components junto con JSX: https://webjsx.org
No queda claro si no quiere aprender el framework en sí, si quiere algo que se sienta tan mágico que no haga falta aprenderlo, o si quiere leer documentación o no.
He usado principalmente Vue, y aunque el ecosistema SPA es complejo, tampoco tengo claro qué otro sistema sería viable para gestionar apps de cliente con estado complejo.
El patrón básico de jQuery está centrado en efectos secundarios, seleccionando elementos y cambiándolos, mientras que React o Vue.js permiten crear componentes cuya UI está determinada por datos de estado.
Cuando los datos cambian, se actualiza con cambios mínimos en el DOM, y este enfoque hace que los widgets de UI sean mucho más fáciles de leer y mantener según su ubicación.
Hoy los sitios web y las apps de escritorio basadas en web son mucho más complejos que hace 20 años, así que, si no vas a construir solo UIs simples, la innovación en gestión de estado es importante.
useStatepor dentro, y la forma de aplicarlo es bastante intuitiva.En cambio, la biblioteca propuesta parece exigir desde el inicio un modelo mental más complejo.
Aunque entender a fondo los detalles de un framework es lo ideal, React ha tenido éxito porque permitió crear apps bastante sofisticadas con muy poco conocimiento de su modelo interno.
Puede influir que soy un desarrollador que viene desde la beta de C# y desde los primeros tiempos de HTML/JS/CSS, pero lo entendí rápido.
Elegí Angular para reemplazar un portal central de administración de infraestructura viejo y complejo, y resultó estable, rápido, atractivo, y todos quedaron satisfechos.
La “curva de aprendizaje pronunciada” parece venir sobre todo de desarrolladores que entraron a la industria sabiendo solo JavaScript y algo de React; con más experiencia, se aprende de inmediato.
useStatepor dentro, puede llegar en segundos a una respuesta lógica y correcta.No es complejo ni mágico; una implementación mínima parecida a los hooks de React puede hacerse en unos cientos de líneas.
Una implementación básica de
useStateyrunFunctionComponentes más fácil que la mayoría de las tareas del tercer semestre de Ciencias de la Computación en la universidad.Si ese es el estándar de lo mágico, entonces estamos rodeados de Warlocks de nivel 20 que inventan nuevas Eldritch Invocation hasta durante el desayuno.
Creo que una de las razones por las que la gente no se pone de acuerdo en este debate es que están optimizando para objetivos distintos.
Si estás en una startup financiada por VC, creando rápido un producto central que seguirá recibiendo mantenimiento, un framework puede encajar bien.
Pero en un laboratorio académico no hay mucho dinero para mantener apps ya hechas, y tienen que seguir funcionando incluso después de que el financiamiento pase a un proyecto nuevo.
Estoy casi terminando de reescribir una app en Vue como Web Components, porque las dependencias se habían podrido y ya no era posible actualizarla.
Antes gastaba tiempo arreglando el infierno de dependencias, y habría seguido así, pero probé Web Components y de inmediato me pareció mejor, así que hice el cambio.
Las dependencias bajaron de unas 15 a aproximadamente 1 (d3js), y no me arrepiento.
App anterior: https://bam.iobio.io/, app nueva: https://bam2.iobio.io/
Nadie te obliga a subir siempre un framework a la versión más reciente, así que podrías haberte quedado con la versión de Vue que ya usabas.
Si no había una razón especial, quizá habría estado bien usar la misma versión hasta el final.
No quiero decir que Vue fuera necesario para ese caso de uso, ni que eliminar dependencias haya sido una mala decisión, pero si Vue te gustaba, no veo una fuerza que te obligara a mantenerte en la versión más reciente.
Me pregunto si la razón por la que Vue requiere dependencias adicionales está del lado del sistema de build.
Por eso no entiendo bien por qué el ecosistema de VC no podría sobrevivir sin frameworks.
Me gusta que Svelte permita generar Web Components mediante la Custom Elements API.
Como Svelte compila a JS/HTML/CSS normal, resulta natural crear componentes reutilizables que funcionen en cualquier framework o en JS vanilla: https://svelte.dev/docs/custom-elements-api
He seguido la discusión sobre Web Components durante años, pero como desarrollador full-stack todavía no tengo claro qué pueden hacer para mejorarme la vida
La mayoría de estos ejemplos apenas consistían en meter datos en HTML como plantillas, y eso ya se puede hacer con handlebars
¿Me estoy perdiendo de algo?
Si usas HTML como documento, con Web Components puedes agregar funciones de interacción en tiempo real más sofisticadas
Algunos ejemplos son un emulador de terminal conectado a WebSocket, un selector de fecha, elementos de formulario personalizados, mapas, tablas de datos, widgets de pestañas y los componentes personalizados que antes ofrecía jquery-ui
También se puede hacer sin Web Components, pero al convertirlo en componentes personalizados, el HTML se mantiene mucho más limpio y con apariencia de documento
Estaría bien tener una biblioteca coherente de Web Components, y con HTMX y eventos enviados por el servidor también parece posible hacer un chat en tiempo real bastante decente
El navegador aísla todo el HTML, CSS y JS sin trucos adicionales
Me gusta que puedas crear un Web Component, definir claramente las API de JS, HTML y CSS en términos de variables, y luego ponerlo en cualquier entorno sin que se rompa, o sin tener que crear un laberinto de namespaces de CSS complejos y dependencias de frameworks
Por ejemplo, puedes agregar funciones como filtrado o reordenamiento con arrastrar y soltar mediante un Web Component que envuelva una tabla, y si JS está desactivado o falla al cargar, el usuario igual recibe la tabla y el contenido básicos
Antes eso era mucho mejor que la pantalla en blanco de los frameworks de frontend, pero ahora el renderizado del lado del servidor está ampliamente disponible, así que la ventaja es menor
La encapsulación de estilos también está bien, pero hoy las bibliotecas de UI headless y los estilos con scope de los frameworks son comunes, así que parece menos urgente que hace 10 años
Dicho eso, para usar slots hay que optar por Shadow DOM, y al crear componentes reutilizables propios es molesto no poder estilizarlos poniendo una sola hoja de estilos en la página
Si una demo muestra 200 líneas de ajustes manuales del DOM, es difícil decir que Web Components son el futuro
Eso es todo, y para la mayoría de los demás fines son bastante malos
Además, puedes distribuir un componente de UI que funcione en todos los frameworks sin tener que crear 7 versiones
Lo peor de Web Components y Shadow DOM es que pueden hacer que las extensiones del navegador no funcionen bien, o que directamente no puedan funcionar
Los proveedores de navegadores tampoco tienen prisa por arreglar esta situación
Creo que uno de los mayores “errores” de Web Components fue haberlos asociado con Shadow DOM en la mente de la gente
En el desarrollo de apps, si te quedas con el DOM vivo, Web Components se vuelven una opción muy liviana y sencilla
Puedes seguir usando las herramientas de CSS que quieras, como bootstrap o tailwind, y aun así obtener una excelente encapsulación funcional casi sin costo, especialmente si usas algo como lit-html como renderizador
En general, a los equipos les pareció refrescante trabajar con Web Components nativos, y los desarrolladores que venían del mundo de los frameworks, después de una semana más o menos de adaptación, no querían volver
Con simples propiedades de clase y llamadas manuales a la función de render desde
set(), obtienes los beneficios de la reactividad sin la carga de un frameworkEl problema es que hay poco material que muestre cómo empezar en “modo fácil”
La mayoría del material introductorio te empuja de inmediato a tecnologías dolorosas como Shadow DOM y CSS parts, más orientadas a autores de bibliotecas que a desarrolladores de apps
Creo que habría que escribir una guía tipo “The Good Parts” sobre cómo hacerte la vida más fácil con Web Components
Como alternativa, existen los “HTML web components”, que usan solo el DOM vivo, priorizan el renderizado del lado del servidor y son buenos como reemplazo del “toque de jQuery”: https://adactio.com/journal/20618
También existe “Shadow gristle”, que usa Shadow DOM lo menos posible y deja en el DOM vivo lo que requiera estilos o composición: https://glazkov.com/2023/03/02/shadow-gristle/
Esta tecnología parece tener tanto bendiciones como maldiciones según cómo se use, así que estoy reuniendo material y comentarios al respecto
Lo mejor es no caer en el infierno de dependencias cada dos semanas
La interoperabilidad es la mayor ventaja desde el punto de vista del usuario, pero creo que se subestima que, como precio, puede aparecer un costo de rendimiento porque cada componente que se usa puede traer consigo un runtime innecesario
Usar un framework como Lit junto con Web Components es la forma recomendada, y con el tiempo, cuando aparezcan nuevos frameworks y los componentes queden atados a versiones antiguas, ese costo se acumula
No le recomendaría a nadie ir en la dirección de tener varias bibliotecas duplicadas en una misma página, y si eso forma parte de las mejores prácticas, no es bueno a largo plazo
Después de ver durante años artículos, redes sociales y videos de defensores de Web Components —y yo debería ser precisamente el usuario objetivo—, veo que además del impuesto de interoperabilidad están llenos de desventajas que no existen en los frameworks mainstream
Dentro del ecosistema de cada framework, la interoperabilidad funciona bien, y la misma dinámica que hace que los desarrolladores busquen interoperabilidad también hace que se agrupen alrededor de unos pocos frameworks mainstream
Creo que Web Components no logra ponerse al día en lo técnico y agrega mucha complejidad a la plataforma web para un diseño de principios de la década de 2010: https://x.com/Rich_Harris/status/1840116730716119356
También hay muchos frameworks con runtimes pequeños, como Svelte, y aunque no digo que pongamos 100 en una misma página, creo que 5 o 6 están bien
No digo que sea ideal, pero puede ayudar en migraciones graduales o micro frontends
Como referencia, React 17 también introdujo la capacidad de tener varias versiones de React en la misma página: https://nolanlawson.com/2021/08/01/why-its-okay-for-web-components-to-use-frameworks/, https://bundlephobia.com/package/svelte@4.2.19, https://legacy.reactjs.org/blog/2020/10/20/react-v17.html
React y react-dom juntos superan los 100 KB, mientras que Svelte y Lit están en unos pocos KB de un solo dígito
Podrías meter bastantes frameworks antes de acercarte a la hinchazón que la gente usa todos los días sin pensarlo
Las señales que he visto de forma constante hasta ahora no son buenas; esa comunidad está en X, y Web Components no resuelve sus problemas ni se usa bien incluso en el mejor de los casos
Espero que logren convencerlos, pero en general suelen decir que Web Components fracasó y que, en conjunto, fue malo para la web
La mayoría de los runtimes son bastante pequeños, y que dos runtimes se ejecuten al mismo tiempo no implica un gran overhead de rendimiento
Los frameworks web modernos son todos reactivos, así que si no hay nada a lo que responder, no hacen nada
No veo bien por qué una página con una parte hecha en React, otra en Lit y otra en Svelte tendría una experiencia de usuario o un consumo de batería notablemente peores que una página con un solo framework
El tuit citado trata sobre si Web Components son “primitivas útiles para crear frameworks”, y probablemente ni siquiera los fans que los han usado de verdad dirían que sí
Web Components es un mecanismo de distribución, y si la única alternativa es crear la misma biblioteca 7 veces para React, Preact, Svelte, Solid, Vue y JS vanilla, eso es horrible
Me gustan Web Components y soy optimista sobre su posibilidad de sacarnos del infierno frontend actual que creamos nosotros mismos
Hace poco di una charla breve sobre el futuro del frontend, y parece que otras personas también esperan una salida
Creé una tabla de datos para una GUI de base de datos y el scroll sigue siendo muy fluido incluso cargando cientos de miles de filas
También estoy por publicar pronto una biblioteca de Web Components; todavía es temprana y algo verde, pero me gustaría que más gente la viera: www.astra-ui.com
Sería bueno reubicar la barra lateral pensando en un diseño responsive para pantallas pequeñas, y poner max-width en el body en vez de width
El botón “explore components” al final de la página principal no parece enlazar a ningún lado
Dice “aprende de implementaciones de componentes bien estructuradas y accesibles”, pero no encontré en la documentación ningún enlace a la implementación
Dice “no hay dependencias que mantener o actualizar”, pero me parece que astra-ui en sí misma es una dependencia, y también tiene changelog: https://www.astra-ui.com/changes/
También dice “control total sobre el código y el styling”, pero no entiendo cómo puede haber control total si dependes de las implementaciones que proporciona la biblioteca
Me da curiosidad por qué decidieron publicar esta biblioteca. Abrir el código de software interno puede ser útil cuando la empresa tiene un objetivo específico, pero normalmente tiende a convertirse en una pérdida de tiempo sin recompensa
Una biblioteca de componentes tiene que pelear por la adopción del ecosistema; si no, no tiene audiencia y hay pocas razones para publicarla
Parece una gran solución
Hace unos meses, en mi nuevo trabajo, heredé una base de código JS de unas 250 mil líneas.
Una sola clase enorme y algunas subclases hacían todo, y algunos archivos tenían hasta 30 mil líneas.
No había framework ni reactividad, así que al hacer clic en un botón había que actualizar manualmente todo en la pantalla con event listeners.
Era código que parecía escrito por alguien encerrado durante años en una celda de monasterio con solo un libro básico de JavaScript.
Como tenía que hacerlo poco a poco, empecé a refactorizarlo con Web Components, lo que ayudó mucho, y hasta ahora reduje 50 mil líneas.
Pero el verdadero objetivo era aprender todo lo que hacía el código existente antes de reescribirlo.
Rehacerla con Web Components es una forma de lograr ese objetivo, y es bueno que no hayan tirado todo para empezar de cero.
Eso sí, si avanzas hasta cierto punto y luego te mueven a otro proyecto, existe el riesgo de que llegue la siguiente persona y empiece a refactorizar a su propio estilo, convirtiéndola en una base de código críptica con tres estilos distintos.
Aun así, es mejor que reescribir de golpe una de 250 mil líneas.
Una cosa que me gustó de Web Components es que, al menos en teoría, pueden funcionar incluso con JS deshabilitado.
Lo he hecho algunas veces para progressive enhancement.
En general estoy de acuerdo con Nolan. Web Components tiene suficientes aristas ásperas como para que, en su estado actual, sea difícil que conquiste el mundo, pero es bastante bueno para ciertos casos de uso.
Eso sí, no sé bien a qué se refieren con que no encaja con server-side rendering; lo he usado sin problemas.
Por lo que he visto, parece que hace falta JavaScript para registrar una plantilla en una etiqueta específica: https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots
En ReactJS puedes renderizar componentes o plantillas en el servidor, y considero que JSX es un lenguaje de plantillas bastante bueno.
Entiendo que Web Components no trae un buen lenguaje de plantillas integrado, así que tienes que traer el tuyo.
No conozco un mecanismo estándar para tomar un fragmento de componente JS asociado a una etiqueta y renderizar el HTML necesario sin ejecutar JS.
Si en el futuro se pueden renderizar en el servidor 3 frameworks distintos de Web Components, componerlos entre sí y hacer hydration de forma limpia, entonces podría considerarlo resuelto: https://nolanlawson.com/2023/08/23/use-web-components-for-what-theyre-good-at/