Как стать автором
Обновить
65
0
Павел Малышев @PaulMaly

Программист

Отправить сообщение
Так и в 2013 году рассуждали люди когда принимали решение попробовать React или остаться на jquery. Многие и до сих пор на нем сидят, но вряд ли это остановит прогресс.
Кол-во встроенных возможностей в Svelte сопоставимо с Vue и даже больше (есть встроенные store/transitions/animations/etc). React же это не более чем шаблонизатор, фукнция от стейта. Да, блин, он банально даже не реактивный.))))
Это все вкусовщина, но факт остается фактом — новый синтаксис Svelte 3 нравится значительно больше значительно большему кол-ву человек, иначе не было бы роста, который пришелся аккурат после выхода Svelte 3.
Знаете, мне то пишут что мол никто не использует из известных компаний, значит не готово для прода. А когда пишу кто в итоге использует, ретируются с ответов вроде вашего. Всем не угодишь.

Вы, в целом тоже не блещите своей аргументацией ни в предыдущем комментарии, ни в других комментариях к другим статьям. Так что извините.
Я наверно один такой сумасшедший, но мне совсем непонятно, зачем делать все эти решетки, звездочки и прочий кошмар в коде.

Может быть потому что не всем нравятся управляющие конструкции в тегах? Этим страдают Vue и Angular и это является главным минусом их шаблонизаторов.
Svelte намного мощнее React, поэтому довольно странно что вы ставите его в ряд с Angular, который мощнее Svelte. Поддержка TS базовая имеется (без шаблонов) с помощью препроцессоров. Ну и конечно же не понятно зачем TS если вы сами пишете не очень навороченных интерфейсов?
Смотрел сам примерно 8 месяцев назад, выводы точно такие же: стильно, модно, молодёжно, но в продакшн — извините.

NYT, GoDaddy, Яндекс.Деньги и Mail.Ru почему-то решили что норм. ;-) Но это ваше право конечно.
билд на react весил ~300kb, сборка на Svelte ~90kb.

Размер apk c PWA внутри получился ~1.3mb. Бандл на react-native весил ~16.4mb.

Отличные кейсы, спасибо что поделились!
Как-то не правильно в первом примере используется produce, по-моему.
Я понял это так — есть разработчики, которые бегают с мечами, щитами, копьями или даже летают на драконах. Короче им тяжко, занимаются кастылизацией. А есть секретная секта тех, кто юзает «фреймворк который нельзя называть», которые как безликие, все видят, все слышат и могут даже убить Короля Ночи. Короче крутые пацанчики, хоть их никто и не знает, но у них нет таких проблем.
Наверное боятся что все узнают о его существовании.
Спасибо за статью! svelte-gl выглядит очень многообещающем’
Просто обходится все дерево и проверяются все значения.

Не все дерево, а несколько заранее приготовленных строгий стравнений. Покажите мне где в ангуляре заранее генерируются условия для всех кейсов в buildtime? Разве что речь про последний ангуляр с AoT, так это оно и есть примерно.

Он просто обходит весь дом целиком и сравнивает все значения, как я и сказал вначале. И именно это происходит в приведенном вами коде, вопрос закрыт.

Да ежкин код. Он НЕ обходит ВЕСЬ DOM и даже ВЕСЬ стейт целиком. Он обходит только то, что нужно обойти, это и значит «он знает». Вы тугой как пробка.

Хорошо, давайте разберем конкретный кейс и сравним Реакт и Svelte. Вот есть у нас компонент:

<div class="foo">
  <h1>Hello world</h1>
  <p class="text">Lorem ipsum</p>
  <form action="/login" method="post">
    <input type="email" placeholder="Enter email">
    <input type="password" placeholder="Enter password">
    <button>Login</button>
    <button type="reset">Clear</button>
  </form>
</div>


И в какой-то момент времени изменяется стейт:

// react
this.setState({
   email: 'example@mail.com'
});

//svelte
email = 'example@mail.com';

Итак, сколько операций cd (или reconcile в случае с vdom) произойдет в этом случае?

Сколько сделает React — более 20ти по грубым подсчетам и это только реконсиляция (без самого ререндера дерева)
А сколько нужно? Ноль. Сколько сделает Svelte — ноль.

Ок, пошли дальше. Добавим немного динамики:

...
<input value={email} type="email" placeholder="Enter email">
...

React — все еще более 20-ти. Сколько нужно? Одну. Сколько сделает Svelte — одну.

Сколько манипуляций в DOM — одна. В случае с React операция в реальный DOM тоже будет одна. Только, насколько я понимаю, будет также выполнена операция получения реального DOM элемента (querySelector), а в Svelte просто:

if (changed.email) {
  input0.value = ctx.email;
}

input0 — это уже закэшированное значение нужного элемента.

Чувствуете разницу? 20 к 0 при ноле необходимых и 20 к 1 при одной необходимой. По вашему это все одно и тоже?
Очевидно же — две строки из 3-х. Натужная иммутабельность, которая плохо сказывается на читаемости, написании и поддержки кода. Пассаж про обычный js не понял, обычный js не запрещает писать костыли :)

Это же мини-демо проектик. Тащить в него immer или immutablejs для «читаемой» иммутабильности, имхо, было бы лишним. Проще написать 2 дополнительных строчки на чистом js, понятные всем. Пассаж про обычный js был про это.

Гхм… Вы меня наверное недопоняли. От них после redux уже тошно, а вы мне их ещё и в svelte тащить предлагаете? :) Я собственно потому и упомянул immer.

Окей, я понял. Ни разу не являюсь фанатом redux, поэтому ничего не предлагаю. Говорю о том, что можете юзать в Svelte что хотите.

Ну тут надо пробовать. Я пока близко в Svelte не присматривался. Насколько я понимаю, он выискивает все мутабельные операции и добавляет к ним явные setter-ы. Так что в случае immer тут будет всё зависеть от того, сможет ли он подхватить их, будет ли там callback, как на него отреагирует svelte. Нужно ли будет помещать такой блок в $: {} кодовый блок. Как я и написал выше — надо пробовать и смотреть что получится…

Раз не пробовали, тогда поверьте тем, кто пробовали. Юзаем immer на одном проекте. Вот переписал пример с его использованием: REPL

Всё таки это компилятор и надо понимать что получится в итоговом js-коде, какие будут обёртки и стоит ли игра свеч.

Ничего особенного там в этом смысле не получается. Единственное правило — Svelte должен «увидеть» присвоение в стейт. Можно считать что = это автоматический вызов setState. Если подробнее:

// не будет перерисовки, даже если immutable=false
arr.push(item);

// будет перерисовка, если immutable=false
arr.push(item);
arr = arr; // триггер дла set state

// НЕ будет перерисовка, если immutable=true
arr.push(item);
arr = arr;

// будет перерисовка, если immutable=true
arr = [ ...arr, item ];

Последний вариант самый правильный и стоит юзать immutable=true. Как именно вы будете делать иммутабильность для Svelte не важно. В случае с immer:

arr = produce(arr, _arr => _arr.push(item));

// скомпилируется всего лишь в это:

$$invalidate('arr', arr = produce(arr, _arr => _arr.push(item)));
C immer прекрасно работает. Не понимаю какое вообще отношение к этому имеет компиляция.

После стандартных redux-их {… } простыней видеть эти костыли в Svelte, конечно, неприятно.

Так используйте {… } никто также не мешает. Как вы обеспечиваете иммутабильностью Svelte вообще не волнует. Для реактивности важен только факт присвоения значения, а иммутабильность не обязательна и работает внутри. Флагом immutable: true вы лишь говорите Svelte — «тебе не стоит парится на объектами, если ссылка на них не изменилась».

И было бы интересно узнать что из примера выше вы считаете «костялем»? Вроде бы обычный js.
Иммутабельность же. Помогает всем фреймворка и Svelte в том числе лучше «понимать» что изменилось в объекте. В Svelte есть специальная опция компилятора immutable: true, которую мы обычно используем в проектах. И всем советую. Собственно с этой опцией ваш способ работать не будет.
Ну да, типа того. Возможно если статусов станет больше и одного лишь наличия winner будет недостаточно, чтобы понять какую часть шаблона нужно отрисовать, то придетяся считаться какой-то status в скрипте. Вообще сильно зависит от логики определения. Например, возможно будет достаточно такой конструкции:

<script>
  ...
  $: winner = calculateWinner(squares);
  $: draw = ! squares.includes('') && ! winner;
  ...
</script>

<div class="status">
{#if winner}
  Winner: {winner}
{:else if draw}
  Draw!
{:else}
  Next player: {xIsNext ? 'X' : 'O'}
{/if}
</div>


Обновил мой пример. Тот же draw пригождается еще и для отмены click()
$: status = (() => {
const winner = calculateWinner(state.squares);
return winner? `Winner: ${winner}`: `Next player: ${(state.xIsNext? 'X': 'O')}`;
})();

Воу, зачем так сложно)) Это же не JSX какой-то, а обычны JS (по крайней мере синтаксически ;-) ). Можно делать блочные реактивные декларации:

let status;
$: {
  const winner = calculateWinner(squares);
  status = winner ? `Winner: ${winner}` : `Next player: ${xIsNext ? 'X' : 'O'}`;
}

Но в целом, я бы не стал увлекаться конкатенацией строк в скриптах и полностью перевел бы это дело в шаблон. На случай если вывод статуса нужно будет как-то дополнительно задизайнить, например `Winner: ${winner}` выводить жирным:

<div class="status">
{#if winner}
  <b>Winner: {winner}</b>
{:else}
  Next player: {xIsNext ? 'X' : 'O'}
{/if}
</div>

Все таки в Svelte у нас html-first и прекрасный DSL для этого.
Блин, в примере, который я правил не было нуля. Только крестники ставились.))) Короче не последняя версия видимо. Исправил пример на скорую руку. Можно конечно и еще проще написать. Спасибо что заметили!
Спасибо за статью! Рад что интерес к Svelte ростет.))

Несколько ремарок:

Svelte такого не умеет, или я просто не нашел, как это правильно сделать, поэтому пришлось использовать диспетчер событий

Svelte умеет ровно также:

<button class="square" on:click={() => handleClick(i)}>...</button>

Поэтому диспатчер тут лишний. Он нужен только для создания полностью кастомных событий компонентов. Более того, в вашем случае можно вообще автоматически «всплывать» событие клика на компоненте Square, а не вызывать коллбек. Делается это так:

<button class="square" on:click>...</button>


Далее можно ловить клик прямо на Square и вообще не передавать i в Square:

<Square value={square} on:click={e => handleClick(i)}/>


Заранее извиняюсь, но позволил себе переписать ваш пример немного более рационально.

Информация

В рейтинге
Не участвует
Откуда
Нижегородская обл., Россия
Зарегистрирован
Активность