Svelte - очень хороший фреймворк / библиотека, но у него есть чувствительная проблема - это детектор изменений, он не очень хорошо обнаруживает изменения, если вы меняете объекты, поэтому иногда я слышу, что мне следует использовать неизменяемый способ.

И я хотел попробовать любой другой детектор изменений в Svelte, например. которые есть в Angular. Итак, я сделал некоторый экспериментальный компилятор, похожий на Svelte (Svelte-M), между прочим, он дал лучший размер пакета и производительность:

Размер пакета для тестового todo-app почти вдвое меньше:

  • Svelte: 4,7 КБ (2,2 КБ в сжатом виде)
  • Svelte-M: 2,7 КБ (1,2 КБ в сжатом виде)

Производительность (эталонный тест обновлен в 2020–07–05, Firefox 78) :

  • Рендеринг 5000 элементов: Svelte 353 мс, Svelte-M 327 мс (Svelte-M немного быстрее)
  • Повторный рендеринг (удаление и добавление 5000 элементов): Svelte: 445 мс, Svelte-M 277 мс (в два раза быстрее)

Пример todo-приложения, скомпилированного с помощью Svelte-M: example.html и развернутого в jsfiddle. Источник эталона.

Предупреждение: Svelte-M - это всего лишь небольшой эксперимент, поэтому функций не так много и очень мало

Почему это быстрее? Svelte строит DOM элемент за элементом, а затем добавляет реквизиты, это не самый быстрый способ создания DOM, и он увеличивает исходный код, Svelte-M строит DOM как одну команду и элементы (дерево DOM) клонируются с использованием Node.cloneNode (как 1 команда, а не поэлементное построение).

Хотите прочитать эту историю позже? Сохраните в Журнале.

Другой детектор изменений

Но наиболее важным является обнаружение еще одного изменения (я бы назвал его проверкой привязки), ниже приведены несколько примеров того, как это лучше:

let todos = [];
const add = () => {
  todos.push({name: 'Hello!'});
};

Когда вы вызываете функцию add (), Svelte не обнаруживает изменений, поэтому DOM не будет обновляться, вы должны использовать присваивание, например t odos = todos, (в других фреймворках это похоже на ручное «setValue»). Этот сниппет отлично работает со Svelte-M, обнаруживает любые изменения.

Другой случай: у меня есть список задач, и я хочу что-то изменить, щелкнув по todo:

<script>
  let todos = [];
  const fix = (todo) => {
    todo.name += '!';
  }
</script>
<ul>
  {#each todos as todo }
  <li>
    <span on:click={() => fix(todo)}>{todo.name}</span>
  </li>
  {/each}
</ul>

Когда вы щелкаете элемент и вызываете функцию «исправить», Svelte не обнаруживает изменений, есть несколько способов исправить это, но в любом случае вам нужно что-то сделать. Со «Свелте-М» это работает просто потому, что его поменяли.

Таким образом, другая система обнаружения изменений может быть лучше, она работает так, как ожидалось (ближе к javascript), меньше уловок и работает достаточно быстро. Хотелось бы видеть подобное в Svelte…

Исходный код компилятора Svelte-M: https://github.com/lega911/svelte-m

Если вы попробуете, есть небольшое изменение привязки, просто потому, что он короче:

Svelte:
  <span on:click={() => fix(todo)}>
Svelte-M:
  <span on:click={fix(todo)}>

📝 Сохраните эту историю в Журнале.

👩‍💻 Просыпайтесь каждое воскресное утро и слушайте самые интересные истории из области технологий, ожидающие вас в вашем почтовом ящике. Прочтите информационный бюллетень« Примечательно в технологиях .