Автостопом по фронтенду или эволюция фронтенд фреймворков

Мостовой Никита, HeadHunter

Frontend dev in Architectural team

Пишу код для других разработчиков

Twitter, Telegram, etc: @xnimorz

Много собеседований

Начинал большой проект с 0

Занимался миграцией с XSLT на React

А как оно вообще происходит?

Концепция обновления DOM

VDOM | Compilers | Observable

import React, { useState } from "react";
import Component from "./Component";

function App() {
  const [ articles, setArticles ] = useState([
    { id: 1, text: "foo" },
    { id: 2, text: "bar" },
    { id: 2, data: {} },
  ]); 
  return (
    <div>
      <Title>Hello world</Title>
      <Content articles={articles} />
    </div>
  );
}

function Title({ children }) {
  return <H1>{children}</H1>;
}

function Content({ articles }) {
  return (
    <div>
      {articles.map((item) => {
        if (item.text) {
          return <article key={item.id}>{text}</article>;
        }

        return <Component key={item.id} article={item} />;
      })}
    </div>
  );
}
import React, { useState } from "react";
import Component from "./Component";

function App() {
  const [ articles, setArticles ] = useState([
    { id: 1, text: "foo" },
    { id: 2, text: "bar" },
    { id: 2, data: {} },
  ]); 
  return (
    <div>
      <Title>Hello world</Title>
      <Content articles={articles} />
    </div>
  );
}
function Title({ children }) {
  return <H1>{children}</H1>;
}
function Content({ articles }) {
  return (
    <div>
      {articles.map((item) => {
        if (item.text) {
          return (
            <article key={item.id}>
              {text}
            </article>
          );
        }
        return (
          <Component key={item.id} article={item} />
        );
      })}
    </div>
  );
}

Главная задача — инвалидация узла в компоненте

import React, { useState } from "react";
import Component from "./Component";

function App() {
  const [ articles, setArticles ] = useState([
    { id: 1, text: "foo" },
    { id: 2, text: "bar" },
    { id: 2, data: {} },
  ]);   
  let invalidator = {
  	div: {
    	children: {
        	Title: {deps: []},
            Content: {deps: [articles]},
        }
    }
  }
  return (
    <div>
      <Title>Hello world</Title>
      <Content articles={articles} />
    </div>
  );
}
import React, { useState } from "react";
import Component from "./Component";

function App() {
  const [ articles, setArticles ] = useState([
    { id: 1, text: "foo" },
    { id: 2, text: "bar" },
    { id: 2, data: {} },
  ]);   
  let updater = {
  	div: {
    	children: {
        	Title: null,
            Content: ([articles] => ...),
        }
    }
  }
  let invalidator = {
  	div: {
    	children: {
        	Title: {deps: []},
            Content: {deps: [articles]},
        }
    }
  }
  return (
    <div>
      <Title>Hello world</Title>
      <Content articles={articles} />
    </div>
  );
}
<script>
  import Title from "./Title";
  import Content from "./Content";
</script>

<div>
  <Title text="Hello world" />
  <Content />
</div>

App.svelte

<script>
  import Title from "./Title";
  import Content from "./Content";
</script>

<div>
  <Title text="Hello world" />
  <Content />
</div>

App.svelte

<script>
	export let text
</script>
<h1>
	{text}	
</h1>

Title.svelte

<script>
  import Title from "./Title";
  import Content from "./Content";
</script>

<div>
  <Title text="Hello world" />
  <Content />
</div>

App.svelte

<script>
  import Component from "./Component";
  import articles from "./store";
</script>

<div>
  {#each $articles as item (item.id)}
    {#if item.text}
      <article>{item.text}</article>
    {:else}
      <Component article={item} />
    {/if}
  {/each}
</div>

Content.svelte

<script>
	export let text
</script>
<h1>
	{text}	
</h1>

Title.svelte

<script>
  import Title from "./Title";
  import Content from "./Content";
</script>

<div>
  <Title text="Hello world" />
  <Content />
</div>

App.svelte

<script>
  import Component from "./Component";
  import articles from "./store";
</script>

<div>
  {#each $articles as item (item.id)}
    {#if item.text}
      <article>{item.text}</article>
    {:else}
      <Component article={item} />
    {/if}
  {/each}
</div>

Content.svelte

import { writable } from "svelte/store";

export const articles = writable([
  { id: 1, text: "foo" },
  { id: 2, text: "bar" },
  { id: 3, data: { foo: "bar" } },
]);

Store.js

<script>
	export let text
</script>
<h1>
	{text}	
</h1>

Title.svelte

Разберем инвалидацию узла на примере?

1. "Быстрее", НО!

2. Поддерживаемый код

 

 

1. Размер бандла на больших проектах и при поддержке IE10-

2. Не чистый JS

 

 

Сама концепция требует внимания. Инвалидация — это O(1) или O(N). Сравнение же — O(N^3) и уменьшается только эвристиками

Концепция компилируемых фреймворков — не нова, но требует внимания

 

Главный вопрос ререндера — корректная инвалидация и оптимизация обновлений

Twitter, Telegram, etc: @xnimorz

Спасибо за внимание :)

Автостопом по фронтенду

By Nik Mostovoy

Автостопом по фронтенду

  • 801