Marcos desaparecidos

¿Por qué usamos frameworks? Angular, React y Vue nos ayudan a crear aplicaciones web complejas: estructurar nuestro código, administrar el estado y desarrollar interfaces complejas. Durante la última década, los marcos se han convertido en el estándar. Un costoso estándar. Desde que los marcos se han puesto en uso, JS ha estado muy hinchado. Hay más páginas que pesan varios megabytes, y una parte importante de este volumen es el marco en sí. Parece ser un poco, pero para el usuario es crítico: en el teléfono o en Internet débil, la página puede no cargarse. Esto es un problema



Además de tener sobrepeso, los marcos clásicos tienen muchas otras desventajas y no son adecuados para todos los proyectos. Estos problemas se resuelven en "marcos en peligro de extinción". ¿Cuál es esta nueva tendencia, por qué no es "otro marco JS", sino una buena idea y cómo los marcos misteriosos pueden mejorar nuestras aplicaciones, Pavel Malyshev dirá?

Sobre el orador: Pavel Malyshev ( PaulMaly ) - fullstack con más de 10 años de experiencia. Trabaja en Mustlab, que externaliza la web, Smart TV y dispositivos móviles, así como IoT. Un evangelista del marco Svelte JS en Rusia, lidera un grupo de Telegram sobre este tema.



Lo que no debe estar en el informe


Cuando consideré esta historia, decidí que no debería ser estándar. Por lo tanto, escribí lo que no debería estar aquí. No habrá énfasis en un marco específico, comparaciones con otros marcos: están cansados ​​de todos y, por supuesto, no quiero ser el Capitán Obvio. Todo esto no debería haber estado en mi historia, pero, desafortunadamente, será ...

Cuando leyó el nombre, probablemente pensó que había otro marco y que ya había un zoológico completo.



Me parece que si aparece un nuevo marco, los antiguos no satisfacen algunas de nuestras necesidades. Quizás las necesidades mismas cambien con el tiempo, y es por eso que necesitamos nuevas soluciones, más efectivas e interesantes. Por lo tanto, le pido que aborde lo anterior desde este punto de vista con una mente abierta y considere los marcos desaparecidos como una nueva herramienta que puede ayudarlo en su trabajo.

Para empezar, descubramos quién es quién.

Quien es quien


Tomé los tres grandes y Svelte. Es interesante que cada herramienta se caracterice de manera diferente. Angular se posiciona como un marco para todas las ocasiones, "todo en una caja". React imita una biblioteca: "Soy tan pequeño como una biblioteca", pero junto con toda la infraestructura también es un marco completo. Vue es supuestamente un marco progresivo. Puede cambiar a él con jQuery transfiriendo secuencialmente el código, comenzando casi con la etiqueta de script habitual sin recopiladores. Svelte es un marco que desaparece mágicamente. Wat?

Averigüemos de qué estoy hablando.

¿Por qué los marcos comenzaron a desaparecer?


Estamos enviando demasiado código a nuestros usuarios.

Nuestros clientes se están volviendo más móviles, pero la tecnología de Internet no es buena en todas partes, incluso 3G no está en todas partes, sin mencionar LTE. Necesitamos reducir el tamaño del código.

Hay un interesante estudio de 2017 sobre este tema, que muestra que si su aplicación tiene mucho JS, entonces puede poner solo 130 Kb para hacer feliz al usuario . Si JS es pequeño, entonces hasta 170Kb. Esta diferencia se debe al hecho de que el estudio tuvo en cuenta que JS es diferente de otros tipos de recursos, debe analizarse, interpretarse, etc.



En el estudio, 130 Kb no es solo JS, sino en general todo, incluido CSS, HTML, por supuesto, sin imágenes. Al mismo tiempo, un Angular pesa 143 Kb, y ni siquiera hemos escrito una sola línea de código. Veamos qué soluciones actuales nos ofrecen.

Rendimiento


En principio, cualquier marco clásico es una abstracción sobre una plataforma que nos permite escribir en niveles más convenientes. Esto es malo porque cualquier abstracción tiene algunos costos, incluido el rendimiento.

Incurrimos en costos adicionales debido a abstracciones innecesarias entre nuestro código y el navegador.

La característica de los marcos que desaparecen es que eliminan abstracciones y cálculos innecesarios del tiempo de ejecución del navegador , realizando análisis y cálculos en el momento de la compilación. Por eso desaparecen. Hablaremos de esto con más detalle a continuación.

Compatibilidad


Las soluciones escritas para el marco clásico no se pueden aplicar en ninguna parte.

Funcionan solo dentro del marco de este marco. Por ejemplo, haces 2-3 proyectos en tu React favorito, escribes un montón de soluciones geniales para él y luego decides pasar a Angular. Ya no necesita estas soluciones; puede tirarlas. Aunque la idea central es la coincidencia de componentes, los marcos clásicos nos hacen imposible reutilizar el código.

Lo que pasa con los frameworks que desaparecen es que no tienen abstracciones , y en este caso no hay framework en tiempo de ejecución. Su código es absolutamente vainilla JS, que puede llevarse a cualquier parte, a cualquier proyecto, incluso en un marco diferente. Por ejemplo, puede tomar el código en un marco que desaparece y transferirlo a React.

División de códigos y sacudidas de árboles


Las viejas tecnologías dificultan la aplicación de nuevas tecnologías.

La mayoría de los marcos se crearon cuando estas tecnologías no estaban tan desarrolladas. Tenemos un núcleo bastante monolítico, y cualquier componente, incluso la pieza más pequeña de su código, está vinculado a todo el marco. En consecuencia, no es posible dividir el código de manera efectiva e incluso sacudir el árbol.

Ahora todos los marcos están evolucionando hacia una mayor modularidad para "sacudirse" mejor. En los frameworks que desaparecen, esto se decide fuera de la caja, porque están hechos de tal manera que solo el código que necesita inicialmente se agrega al paquete y resuelve su tarea exclusivamente. Este es un caso muy específico: como si escribiera el código con las manos para su tarea y lo atascara en el paquete, solo el marco lo hace por usted.

Costo de la característica


Cualquier marco tiene un precio para una nueva característica.

La comunidad requiere nuevas características diferentes y cada miembro necesita algo propio, y cualquier característica tiene un precio. En marcos desaparecidos, este problema se resuelve a nivel de concepto, porque cualquier característica que no use nunca entrará en su paquete.
Entonces, la pregunta principal: ¿pueden los marcos desaparecidos, y específicamente Svelte, resolver todos estos problemas? Vamos a hacerlo bien.

Bez con tiempo de ejecución


Rantime es un tema bastante efímero. No está claro qué es, y diferentes personas lo entienden de manera diferente. En este contexto, hablaré sobre el tiempo de ejecución desde el punto de vista de dos aspectos: el entorno en el que se ejecuta el código y el código mismo .

Runtime como entorno


Veamos un ejemplo. Si el código está escrito en Vanilla, entonces el único tiempo de ejecución que se necesita es el DOM. Si el código está escrito en React, entonces necesita un tiempo de ejecución diferente: DOM, React y React DOM.

Cualquiera, el componente más pequeño de su código en React dependerá del entorno en el que funcione su marco, es decir, en tiempo de ejecución.


Tiempo de ejecución como ejecución de código


El segundo punto es el tiempo de ejecución en términos de ejecución de código en tiempo de ejecución. Veamos el caso de tiempo de ejecución básico de hoy para el frontend, el DOM virtual, una gran parte de tiempo de ejecución, por ejemplo, en aplicaciones React, usando un ejemplo simple:

 <h1>Hello {world}</h1> 

Hay una variable dinámica en este fragmento de HTML. Desde el punto de vista del DOM virtual, el código funciona así.

  • Esta variable está siendo modificada.
  • Se está construyendo el árbol DOM virtual en memoria.
  • En comparación con la versión anterior.
  • Las manipulaciones DOM se realizan directamente, lo que al final es bastante efectivo, porque obtuvimos algún tipo de diferencia y sabemos exactamente qué cambiar en el DOM real.



Un DOM virtual es una sobrecarga absoluta, ya que siempre será más rápido de esta manera: tan pronto como se produjeron cambios, inmediatamente hicieron cambios en el DOM.



Pregunta: ¿cómo entender qué ha cambiado y qué debe cambiarse? El DOM virtual resuelve el problema de lo que ha cambiado, no la velocidad de estos cambios. La velocidad se logra debido al hecho de que sabemos tanto como sea posible lo que ha cambiado, y podemos manipular efectivamente el DOM.

Compilarlo


Para resolver este problema, los marcos de desaparición simplemente determinan los cambios en la etapa de compilación: usted escribió el código, durante la compilación, el marco de desaparición construye todas las dependencias, calcula qué manipulaciones en el DOM son necesarias. De hecho, todo lo que hace un DOM virtual en tiempo de ejecución, un marco de desaparición lo hace en tiempo de construcción: genera manipulaciones directas con el DOM, que simplemente se llaman durante el tiempo de ejecución. El resultado es un diagrama: cuando hacemos cambios, la manipulación en el DOM se realiza de inmediato.

No puede escribir aplicaciones serias en JavaScript vainilla sin golpear un muro de complejidad. Pero un compilador puede hacerlo por usted.
Rich Harris, creador de Svelte

Te diré cómo conocí a Svelte. Teníamos un proyecto interesante : un widget para insertar en un número ilimitado de sitios, aunque no sabemos qué sitios son, en qué dispositivos los abrirá el usuario. El widget debe ser muy pequeño en tamaño y muy rápido en velocidad. Naturalmente, cuando asumimos esta tarea, entendimos de inmediato qué hacer en React o incluso en Vue no es una opción, ya que resulta una sobrecarga adicional.

Estábamos casi inclinados a escribir en vainilla, pero es difícil y no siempre es conveniente mantenerlo. Pero tuvimos suerte: nos encontramos con Svelte. La idea principal de este marco se da en una cita: no puede escribir una aplicación seria en Vanilla, porque rápidamente se encontrará con un muro de complejidad: será difícil para el equipo trabajar, no hay enfoques comunes y el compilador puede hacerlo por usted.

Como funciona




El código fuente es un código basado en el marco, un código que depende del marco. Todo está como siempre: hay algo de documentación, usted escribe el código como si estuviera usando cualquier otro marco que tenga algún tipo de API, principios y enfoques. Todo esta como siempre.

En el momento de la compilación, este código se compila. Como resultado, vanilla JS se encuentra en el paquete y, como dije, exactamente el código que se necesita para ejecutar su aplicación específicamente llega allí. Si en dos minutos agrega otra función nueva allí o usa una nueva característica del marco, Svelte la agregará allí y también entrará en el paquete. De lo contrario, esto no sucederá.

Consideremos los pasos con más detalle. El primer paso es el componente . Considera el mismo componente.

 <h1>Hello {world}</h1> 

En el segundo paso, AST , el código se produce en un árbol de sintaxis abstracta.

 {"type": "Element", "name": "h1", "children": [{ "type": "Text", "data": "Hello",....}]} 

El tercer paso es la API DOM . Sobre la base del árbol, el código se genera directamente, lo cual es necesario para el funcionamiento de este componente. El código es muy simple, no hay tiempos de ejecución complicados y abstracciones aquí en principio.

 function update(changed, ctx) { if (changed.name) { text_1.data = ctx.name; } } 

Al final del artículo, indique en la encuesta si le gusta la idea de la compilación AOT del marco Svelte. La última vez, la mayoría habló positivamente.



Ahora veamos qué es Svelte.

Esbelto


La palabra inglesa svelte o svelt significa "delgado, flexible". Svelte JS es!

Afirmo que este no es "Otro marco JS más" porque es un marco UI en tiempo de construcción . Los marcos regulares funcionan en tiempo de ejecución, y Svelte existe solo antes de que lo compilemos.

Este es un analizador estático en tiempo de compilación , o un analizador de código estático que pasa por el código durante la compilación, lo analiza estáticamente y, en base a esto, genera el paquete final correspondiente.

Este es un compilador anticipado , un compilador AOT que lo hace todo.

El creador del framework Rich Harris, que puedes conocer de herramientas como Rollup, Ractive, Buble, un análogo de Babel, es un tipo genial. En mi opinión, el mismo Rollup sigue siendo la mejor implementación para sacudir árboles. Apareció mucho antes que en Webpack, y aún funciona mejor. Harris originalmente construyó el marco Svelte con sacudidas de árboles, división de código y otros enfoques modernos.

Svelte es una herramienta para escribir vanilla JS sin tener que escribir vanilla JS.

Miremos este marco desde adentro.

Componente de archivo único


Svelte es un componente de un solo archivo . Si trabajó con Vue, le recordará mucho este marco, pero no es casualidad. La sintaxis que Vue usa principalmente se deriva del marco Ractive, que Harris también creó en 2012. Este marco, desafortunadamente, no se hizo popular, me parece, porque se lanzó en 1.0 demasiado tarde. Estaban tan confundidos con las versiones que Ractive estuvo en versiones menores durante 6 años.

Vue tomó prestadas muchas interfaces de allí, y Svelte es el sucesor de Ractive. Por lo tanto, le parecerá que todo es similar, pero los componentes de un solo archivo aparecieron en Ractive en 2013. Se ven un poco diferentes, pero en general, se ve. Cualquier componente que escriba en Svelte se verá así.

 <h1 >Hello {world}!</h1 > <script> export default { /* component behaviour */ }; </script> <style>    /* scoped styles */ </style> 

Arriba hay una cierta plantilla HTML: HTML simple sin excepciones. Lo único además es un cierto lenguaje de plantilla llamado HTMLx . Te contaré más sobre él más tarde.

Luego viene el script en el que escribimos el comportamiento de nuestro componente. Cómo escribirlo se describe en la guía. Allí puede importar, realizar diversas funciones y métodos, todo como en Vue.

Puede usar el estilo de ámbito para obtener estilos de componentes aislados del cuadro. Funciona así: en la compilación principal, se genera un hash, como resultado, es como emular un DOM DOM.

Ninguna de las secciones es necesaria, por lo que un componente puede constar de un solo HTML.

Sintaxis HTMLx


Como con cualquier HTML, los datos se escriben entre paréntesis.

 <button>Say hello {name}</button> 

Así es como se escriben las declaraciones condicionales.

 {#if name} <button>Say hello {name}</button> {/if} 

Enumeraciones y bucles:
 {#each users as { name, email}} {#if name} <button>Say hello {name}</button> {/if} {/each} 

Puede usar directivas para capturar eventos, para doble enlace de datos.

 {#each users as { name, email}} {#if name} <button on:click="say(name)">Say hello {name}<button> {/if} {/each} 

Hay muy pocas directivas en HTMLx, solo 4-5 tipos, y no hay directivas personalizadas, como en Angular.

Puede insertar cualquier información dinámica en cualquier atributo, no hay problema con esto.

 <div id= "{dynamic}"class="used"> {#each users as { name, email}} {#if name} <button on:click="say(name) " >Say hello {name}<button> {/if} {/each} </div> 

Estilos aislados y eliminación de no utilizados


Si utiliza estilos aislados, además de aislarse, los estilos no utilizados también se cortan automáticamente.

 <div id= "{dynamic}"class="used"> {#each users as { name, email}} {#if name} <button on:click="say(name) " >Say hello {name}<button> {/if} {/each} </div> </style> .used {...} .unused {...} </style> 

Si se used el estilo, entonces se usa, y si el estilo no se usa, no estará en el paquete. El marco lo cortará todo, pero perfectamente. Por lo tanto, esta característica se puede romper fácilmente si usa mucha dinámica. Svelte pensará: "Mejor no toco", y se irá. Hay que tener cuidado, pero es muy conveniente. Como Svelte tiene un analizador estático, muestra en la consola al inicio qué estilos no se usan. Si realmente no los necesita, puede eliminarlos de inmediato.

Composición de componentes


Aquí todo es como siempre: importamos el archivo, lo registramos en los componentes, lo usamos como etiqueta.

 <Nested foo= "static" bar={dynamic} bind:baz=baz /> <script> import Nested from 'Nested.html';' export default {   components: {Nested} }; </script> 

Puede transferir cualquier dato a través de los atributos, use doble enlace. O no usar: el doble enlace es opcional, incluso se puede deshabilitar en el nivel del compilador, y no estará en ningún otro lugar. Esto es para aquellos a quienes no les gustan las ataduras. Los enlaces se obtienen utilizando la directiva bind:

Características adicionales de Svelte


Las dos primeras posibilidades son: SSR e hidratación : representación e hidratación del servidor, y gestión de estado incorporada: gestión de estado global incorporada basada en nuestra propia solución, la llamada tienda.

En principio, puede usar Redux, lo que muchos hacen: aquellos que están acostumbrados a Redux lo usan con Svelte. Pero hay una solución interna más simple que está profundamente integrada, de modo que si la registra en la tienda, estará inmediatamente disponible en todas las jerarquías de componentes, sin ninguna manipulación. Lo único que se puede usar es usar el prefijo $ , es decir, todos los métodos o almacenar datos se escriben con este prefijo. $ se puede usar en cualquier plantilla.

La tienda tiene una característica interesante que no he visto en ningún otro lugar: se extiende globalmente a una jerarquía de componentes. Si, por ejemplo, tiene un componente raíz, se utiliza en toda esta jerarquía. Si tiene otra tienda en algún lugar dentro de esta jerarquía, esta tienda se extiende a toda la jerarquía inferior.

Esto es conveniente cuando desea hacer un componente complejo grande con muchos subcomponentes, y luego usarlo en diferentes proyectos, en algunos de los cuales hay Redux, y en otros no. Si usa tiendas regulares con Redux, debe asegurarse de que el proyecto donde lo agregue tenga Redux. No es necesario hacer esto aquí: Svelte implementa su propia tienda para esta jerarquía. Se puede transferir fácilmente incluso a aquellos proyectos en los que no hay una tienda global. Lo trajiste, y Svelte ya está haciendo todo por dentro.

Los elementos personalizados son compatibles desde el primer momento . Hay un sitio especial en el que el soporte se prueba mediante marcos del estándar de componentes web. Según las pruebas, Svelte tiene un soporte del 100% para elementos personalizados. Funciona así: el nombre de la etiqueta se especifica, el indicador "customElement: true" se establece en el compilador y se genera un elemento personalizado listo para usar que admite todas las funciones Svelte existentes.

Zapador: creador de aplicaciones esbeltas . Este es un análogo de Next.js y Nuxt.js para Vue. En principio, todo es igual: isomorfismo, soporte para división de código, captación previa y fuera de la caja y otras características. En mi opinión, recientemente incluso algunas de las ideas de enrutamiento vinieron de Sapper a Next.js.

Pero ninguno Svelte hace esto. Estamos para la competencia justa!

Quien mas


Stencil es un marco de los desarrolladores de Ionic. También funcionan en un marco compilado, pero con un gran enfoque en componentes web y elementos personalizados. Svelte se diferencia de él en que sus componentes generalmente se compilan en clases JS normales y no hay sesgo en los componentes web.

Glimmer : creo que todos conocen este proyecto. Se presenta aquí solo porque también compila: tiene su propio código de bytes, su propia máquina virtual, que obviamente proporciona optimizaciones adicionales para el código final.

Marko de eBay . No lo he estudiado en detalle, pero también compilan, no estoy seguro de qué es tan profundo como Svelte. Es cierto que no entendí en detalle y podría estar equivocado.

Angular Aquí hay un compilador AOT, y será bien promocionado, pero es solo una recopilación de patrones de cadenas en una forma ya analizada de antemano. Por lo que yo entiendo, todavía no hay una compilación completa de AoT.

Hola peliculas


Escribí una pequeña aplicación: una lista de películas con filtros basados ​​en la API TMDb. Tiene categorías: popular, mejor valorada, próxima. Puede recorrer las páginas, seleccionar un país, aplicar filtros para él, cambiar el idioma. Esta aplicación primitiva toma solo 6.4 Kb.

En total, HELLO MOVIES tiene solo 172 líneas de código junto con HTML, de las cuales 36 líneas de código JS, junto con todo tipo de comillas. Este es todo el código que escribí personalmente. Naturalmente, todo esto se compila en un volumen mucho mayor, pero para mí, como desarrollador, no importa.

Unos cuantos indicadores más. "TodoList MVC" en Svelte toma 3.6 Kb - depende de a quién diga, pero incluso en Vanilla toma 11 Kb, y en Vue y React aún más - 80 y 300 Kb, respectivamente. El proyecto "RealWorld", un clon de Medium, con registro, cuentas, me gusta, acciones, amigos - 40 Kb, en React and Angular - 211 y 575 Kb. El clon de "HackerNews" en Svelte es de 30 Kb, en React y Vue, varias veces más.

Puntos de referencia


Todos amamos hollichivat en el tema de los puntos de referencia. Usé el famoso punto de referencia Krausest . Probablemente piense que ahora mostraré los resultados donde Svelte simplemente hace trizas a todos, e Inferno simplemente llora a un lado. Pero esto no va a suceder.



Hice una comparación de Svelte con los Tres Grandes: Angular, React y Vue en versiones recientes. Como resultado, identificó las dos primeras posiciones con respecto a Vanilla. Y aquí los números no son tan importantes como la idea principal, que es que Svelte está muy equilibrado .

Svelte se esfuerza por ser equilibrado: es bueno en todos los aspectos en cualquier punto de referencia . De alguna manera, Svelte incluso supera a Vanilla, en algunos toma el primero, pero en algún lugar supera a Vue y Angular. Sin embargo, en todas las pruebas, Angular y Vue consumen mucha memoria, pero Svelte no. , , . — .

Svelte — . , .

- — !


Svelte New York Times. . , Svelte, , legacy- CMS, . , , .



, - « » — , Drag&Drop. Svelte, .

Soft-Gear , , Svelte. , - .

airca.st Svelte. Dabble Svelte. - i-want-to-ride-an-electric-citi Svelte.

. , RuTube. Smart TV Tizen, Samsung. Tizen Smart TV Svelte. , .





standalone vanilla JavaScript . , , overhead .

. Svelte DOM. .

. , Vue, Svelte . , REPL , , .

. , — , . , .

Code-splitting & tree-shaking . code-splitting tree-shaking. . , .

Micro-frontends ready . -. , , PHP, Svelte-. , . , . code-splitting tree-shaking.



Svelte , . 2016 . .

. , . . , , , , , Vue.

. React Facebook, Angular — Google, Vue , Rich Harris , .

Frontend Conf ++ , , . 33 . ++ 27 28 .

Source: https://habr.com/ru/post/450822/


All Articles