Todo lo que quería saber sobre Qwik: el nuevo marco del creador de Angular

A principios de mayo, Misko Hevery , el creador del marco Angular , anunció su salida de Google y el equipo de Angular a builder.io .





Solo un mes y medio después, en su página dev.to , había un anuncio de un nuevo marco: Qwik .





Decidí averiguar qué es y por qué se necesita.





Qwik está ahora en una etapa proof of concept



, hay muy pocos muelles y no hay una infraestructura correspondiente, y ni siquiera está claro si se disparará o no, pero las ideas principales ya están claras y puede tocar el código.





Averigüemos lo interesante que nos traerá y si tendremos que aprender un nuevo marco (spoiler: es demasiado pronto).





¿Por qué se necesita Qwik?

La tarea principal de Qwik, como puede adivinar por el nombre, es ¡ser muy rápido!





El caso es que desde mayo de este año, Google empezó a tener en cuenta el rendimiento de la aplicación en los resultados de búsqueda. Específicamente, la puntuación se calcula utilizando un conjunto de métricas de Web Vitals .





La mayoría de los frameworks modernos pueden, con la ayuda de Server Side Rendering, obtener rápidamente First Contentful Paint y la mayoría de las otras métricas, pero una métrica aún no las ha conquistado:  Time to Interactive .





El caso es que después de enviar el HTML generado en el servidor, también debe descargar el marco y el código de la aplicación, ejecutarlo y solo después de eso puede manejar los eventos.





Este es el problema que Qwik está tratando de resolver.





¿Qué puede hacer Qwik?

Qwik le permite escribir código que se reutilizará en el servidor y en el cliente, mientras que el código se cargará en el cliente inmediatamente antes de la ejecución.





Funciona como este :





  • En el primer renderizado, el servidor serializa todos los datos en atributos de nodo HTML.





  • (0.5 , 1ms ) Qwik, .





  • , .





  • , .





  • , DOM .





? ?

- . , - , , ( guess.js)





Time to interactive,  ?

Time to interactive , 50 . 





, , , . 





10%, , SSR



, , Time to interactive .





, , 20-70 100.





, Habr.com 29.





Web Vitals





?

, , . 





, , . 





Angular, , .





, ? 

Qwik



- , Time to Interactive.







Markojs.com - Ebay, , , core team , . , core Marko Qwik







Astro.js, , (islands)





?

Qwik



, (quick), - : 





  • , ..





  • Github (monorepo builder.io), npm.





qoot, .





, !

TODO , , StackBlitz, (, Web Containers) Github.





, , , - Header:





import { jsxFactory, QRL, injectMethod } from '../qwik.js';
import { HeaderComponent } from './Header_component.js';

export const _needed_by_JSX_ = jsxFactory; // eslint-disable-line @typescript-eslint/no-unused-vars
export default injectMethod(
  HeaderComponent, //
  function (this: HeaderComponent) {
    return (
      <>
        <h1>todos</h1>
        <input
          class="new-todo"
          placeholder="What needs to be done?"
          autofocus
          value={this.$state.text}
          on:keyup={QRL`ui:/Header_addTodo#?value=.target.value&code=.code`}
        />
      </>
    );
  }
);
      
      



- JSX ( Angular), , , , . , , , . ( . @nin-jin , JSX)





:





export const _needed_by_JSX_ = jsxFactory; // eslint-disable-line @typescript-eslint/no-unused-vars
      
      



, JSX transform





( Angular



), TODO







// TODO: Create QFor and QIf directive?
<Q for="todos.value" do={(todo) => <Item $item={todo} />} />
<Q if="todos.value.length > 0" then={(value) => <section></section>} />
      
      



, # :







<input on:keyup={QRL`ui:/Header_addTodo#addTodo?value=.target.value&code=.code`} />
      
      



, :





  • QRL



    - Template Literal Tag,





  • ui:/



    - Namespace, , , qwik:/ .





  • /Header_addTodo



    -





  • #addTodo



    - ,





  • ?value=



    - - (query params



    )





  • .target.value



    - , Event





, :





export const addTodo = injectEventHandler(
  HeaderComponent,
  provideQrlExp<string>('value'),
  provideQrlExp<string>('code'),
  provideProviderOf(provideEntity(TodoEntity.MOCK_USER)),
  async function (
    this: HeaderComponent,
    inputValue: string,
    charCode: string,
    todoEntity: () => Promise<TodoEntity>
  ) {
    if (charCode === 'Enter' && inputValue) {
      (await todoEntity()).newItem(inputValue);
      this.$state.text = '';
      markDirty(this);
    }
  }
);
      
      



Dependency Injection Qwik ( Angular)





, : 





InjectFunction



- (?value=.target.value



), provideQrlExp<string>('value')



.





injectMethod



- ( ) , (this



), , .





InjectEventListener



- , Event







.





/

, , Qwik (Enitity): , ( TodoListEntity, TodoItemEntity) DOM . , ID .





, .





Change Detection

Change Detection: markDirty



( Angular Ivy), DOM



, Entity







. DOM



, on:q-render



change detection cycle



requestAnimationFrame



.





change detection cycle



, , , querySelectorAll('[on:q-render]')







DOM, DOM 





:





, , :





<Item $item={item} />
      
      



DI:





export const Item = injectFunction(
  provideEntityState<Item>(
    provideComponentProp('$item')
  ),
  function ItemTemplate(item: Item) {
    // code
  }
);
      
      







, emitEvent



Qwik



, open



.





on:open







<my-component on:open="./onOpen"">
   <button on:click="base:qwik#emitEvent?$type=open&someArg=someValue">open</button>
</my-component>
      
      



, ?

, v1 , : 





  • ,





  • IDE , ( , , )





  • Firefox 





  •  





, Qwik ?

Angular Google, React Facebook, 100% , flow killedbygoogle





Qwik Builder.io, 2017 , Issues , jsx-lite builder





, Qwik - .  





rxjs?

, .





?

, , Discord , - .





, Qwik.





API , , - .





, , , .





También quiero expresar mi gratitud a todos los que participaron en la redacción, sugirieron e hicieron preguntas, ¡y un gran agradecimiento a todos los que leyeron esto hasta el final!








All Articles