Everything you wanted to know about Qwik - the new framework from the creator of Angular

In early May, Misko Hevery , the creator of the Angular framework , announced his departure from Google and the Angular team to builder.io .





Just a month and a half later, on his dev.to page , there was an Announcement of a new framework - Qwik .





I decided to figure out what it is and why it is needed.





Qwik is now at a stage proof of concept



, there are very few docks and there is no corresponding infrastructure, and it is not even clear whether it will fire or not, but the main ideas are already clear, and you can touch the code.





Let's figure out what interesting it will bring us, and whether we will have to learn a new framework (spoiler: it's too early).





Why is Qwik needed?

The main task of Qwik - as you might guess from the name - is to be very fast!





The fact is that since May of this year, Google began to take into account the performance of the application in search results. Specifically, the score is calculated using a set of Web Vitals metrics .





Most modern frameworks can, using Server Side Rendering, get fast First Contentful Paint and most other metrics, but one metric is not yet conquered by them -  Time to interactive .





The thing is that after sending the HTML generated on the server, you also need to download the framework and application code, run it, and only after that you can process events.





This is the problem that Qwik is trying to solve.





What is Qwik able to do?

Qwik allows you to write code that will be reused on the server and on the client, while the code will be loaded on the client immediately before execution.





It works like this :





  • On the first render, the server serializes all data into HTML node attributes.





  • (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 , , - .





, , , .





I also want to express my gratitude to everyone who participated in the writing, suggested and asked questions, and a big thank you to everyone who read this to the end!








All Articles