Является ли Svelte следующей большой вещью в JavaScript-фреймворках?

За прошедшие годы разработка JavaScript прошла через несколько парадигм: от сырого AJAX в ванильном JS до долгого господства фреймворков, управляемых событиями, таких как jQuery и Mootools, до текущего подхода, основанного на состоянии, таких нынешних чемпионов, как React, Vue, и угловой.

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

Эволюция фреймворков JavaScript

Так или иначе, мы создавали веб-приложения еще до того, как было придумано слово «приложение».

Ранние интерактивные веб-сайты использовали возможности AJAX для улучшения навигации и даже того, что мы можем назвать первыми SPA. Но сырое состояние JS усложняло жизнь разработчикам, делая приложения все более сложными для развертывания и поддержки по мере их роста.

В 2006 году Джон Резиг создал jQuery, и началась эра фреймворков, управляемых событиями. После небольшого испытания с MooTools jQuery стал основным фреймворком для всего, что связано с интерфейсом, и он безраздельно господствовал в течение доброго десятилетия.

Но по мере того, как приложения становились больше и сложнее, потребность в совместном использовании данных между компонентами привела к сдвигу парадигмы в сторону других подходов. После краткого и быстрого сжигания Ember и AngularJS мы остановились на нынешних чемпионах, которые так или иначе нацелены на декларативный, управляемый состоянием подход к фронтенд-разработке: React, Vue и Angular.

React в настоящее время является наиболее используемым и одним из самых востребованных навыков во всех технологиях, который обеспечивает невероятно богатую среду, огромную пользовательскую базу и практически гарантированную работу для любого, кто изучает все тонкости библиотеки.

У этого есть и свои недостатки, в первую очередь разработчики используют React там, где это может быть не лучшим вариантом. Мы все время видим простые институциональные веб-сайты, созданные с помощью React и кучу надстроек, что, честно говоря, похоже на то, как забивать гвоздь кувалдой: конечно, вы забьете гвоздь, но, вероятно, вы получите хороший кусок. стены с ним. Но даже в приложениях, которые действительно нуждаются в таком инструменте, как React, легко обнаружить, что размеры пакетов выходят из-под контроля, надуманные кодовые базы со все более болезненным опытом разработчиков и определенные шаблоны, в которых пользовательский опыт серьезно страдает из-за низкой производительности.

Что такое Свелте?

Именно здесь Svelte.js обещает светлое новое будущее, предоставляя невероятно легкие и производительные приложения.

Ключевая идея, позволяющая ему это делать, — работа в качестве компилятора. Текущие платформы/библиотеки поставляются с вашим пакетом для запуска вашего декларативного кода в императивной среде программирования API-интерфейсов браузера.

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

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

Опыт разработчиков имеет значение

Одна из самых больших проблем для любого фреймворка — обеспечить хороший опыт разработчика. На самом деле мы создаем приложения не для компьютеров, а для других людей, включая как пользователей, так и наших коллег-разработчиков.

Есть миллион вещей, которые влияют на то, как воспринимается опыт разработчика системы, но мы, вероятно, можем резюмировать положительный опыт как обеспечение более легкой кривой обучения, лучшей читабельности, меньшего количества шаблонов, большего количества кода с меньшим количеством кода и простоты обслуживания.

Я осмелюсь сказать, что акцент на опыте разработчиков на самом деле является одной из основных причин, по которым Vue смог добиться такого большого успеха на рынке, где доминируют фреймворки/библиотеки, созданные отраслевыми гигантами, и почему его так тепло ценят пользователи.

Svelte приложила к этому большие усилия, используя уроки, извлеченные из предыдущих фреймворков. Он берет идеи из Vue, такие как отдельные файловые компоненты, и даже пересматривает старый девиз jQuery «пиши меньше, делай больше».

Vue-подобные однофайловые компоненты

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

Здесь Svelte.js черпает вдохновение из Vue и выводит его на новый уровень. В любом данном компоненте .svelte вы можете иметь тег <script>, объявляющий вашу логику, блок <style> для вашего CSS и обычные теги HTML, определяющие ваш шаблон. И я серьезно. В Svelte нет языка шаблонов, даже нет необходимости объявлять блок <template>. Вы просто пишете свои HTML-теги, как в старомодном HTML-файле, с дополнительной функциональностью с помощью фигурных скобок, похожих на руль.

<script> const title = "World"; </script> <style> h1 { font-size: 2.5rem ; } </style> <h1>Hello {title}!</h1> <p>This is my first Svelte component</p>

Это одна из вещей, которые, на мой взгляд, делают Svelte таким привлекательным для новичков: если вы знаете HTML, CSS и JS, Svelte покажется вам знакомым в первый раз, когда вы его увидите. И чтобы доказать это, проверьте этот фрагмент кода (чуть более сложный) и посмотрите, сможете ли вы понять, что он делает:

<script> let count = 0; function (addOne){ count += 1; } </script> <button on:click={addOne}> Clicked {count} times </button>

Почти уверен, что большинство людей, читающих это, даже те, кто никогда раньше не видел код Svelte, но знаком с HTML и JS, сразу поймут, что у нас есть кнопка, которая показывает, сколько раз она была нажата, и обновляется через обработчик событий.

Конечно, некоторые части синтаксиса JavaScript могут быть непонятны (подробнее об этом позже), но все же его относительно легко понять. С Svelte нет необходимости изучать целый дополнительный язык шаблонов, такой как React JSx, или понимать всю систему, прежде чем вводить строку кода, как в случае с Angular.

Ограниченный, модульный CSS

Одной из самых больших проблем при стилизации веб-сайтов и приложений является сохранение контроля над специфичностью и областями действия CSS. По мере того, как приложения становятся больше, довольно часто можно увидеть блоки CSS, которые никто не решается удалить или изменить просто потому, что вы не знаете, на что это повлияет.

Фреймворк Svelte решает эту проблему за счет того, что ваши стили привязаны к модулю, в котором вы их объявляете по умолчанию. Вы можете добавить тег <style> к своему компоненту, не беспокоясь о том, что это повлияет на что-либо еще в приложении. Это достигается путем добавления сгенерированного компьютером уникального хэша к стилям, объявленным в каждом модуле. Это дает вам большинство преимуществ CSS-in-JS без каких-либо его недостатков.

Например, рассмотрим этот код:

/* app.svelte */ <script> import Nested from './Nested.svelte'; </script> <p>This is a paragraph.</p> <Nested/> <style> p {color: purple; } </style>
/* Nested.svelte */ <p>This is another paragraph.</p>

У нас есть два модуля, один вложен в другой. Получившееся приложение покажет два абзаца, но только первый будет фиолетовым. Если вы просмотрите скомпилированный код, чтобы проверить, как все работает внутри, вы увидите, что Svelte создает уникальный класс, что-то вроде p.svelte-urs9w7{color:purple;}, и применяет его только к <p> элементам, явно объявленным в этом модуле.

Хотя я вижу огромные преимущества, которые это дает большинству команд, если у вас есть преданный специалист по CSS, они, вероятно, прямо сейчас кричат: «Вместо этого просто используйте каскад». Я знаю, что я бы… Ну, оказывается, ты можешь.

Svelte не привязывает вас к этой архитектуре. У вас по-прежнему есть возможность воздействовать на вложенные элементы с помощью <style global> и даже возможность использовать препроцессоры и любой фреймворк или архитектуру, которые вам нравятся. Это дает вам простой и эффективный способ обработки вашего CSS, но вы можете переопределить его любым другим подходом, который вы предпочитаете.

Хотите оживить ситуацию с помощью SASS? вы поняли, просто объявите <style lang="scss">. Хотите использовать любой вариант CSS-In-JS по какой-либо причине? Ты сможешь. Бросить в Tailwind для вашего удобства? Без проблем.

Истинная реактивность

Некоторые говорят, что существует столько же определений «реактивного программирования», сколько существует реактивных программистов, и они совершенно правы. Но основная идея заключается в определении динамического поведения значения во время объявления.

Хороший пример реактивного программирования можно найти в электронных таблицах. Когда мы объявляем значение ячейки, мы можем сделать это по отношению к другим ячейкам. Это создает сложное дерево отношений, которое точно знает, какие значения зависят друг от друга, знает, какие ячейки должны обновляться и в каком порядке всякий раз, когда мы вносим изменения.

Декларативная природа современных фреймворков JavaScript ближе к реактивному программированию, чем предыдущие императивные, но все еще очень далека от истинной реактивности, подобной электронным таблицам. Как ни странно, React не является реактивным. Чтобы понять разницу, мы должны погрузиться в то, как на самом деле работают фреймворки.

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

Революционная основная функция React заключалась в том, чтобы предоставить нам легкое представление DOM в памяти, которое мы можем перемещать намного быстрее для манипуляций. Это называется виртуальным DOM.

Когда происходит изменение, React обновляет виртуальный DOM, сравнивает его с предыдущим снимком, чтобы точно знать, какие элементы изменились, и обновляет только эти элементы в реальном DOM с помощью процесса, называемого согласованием или сравнением.

Вот почему люди утверждают, что виртуальный DOM намного быстрее, чем реальный DOM. И, конечно же, если бы вы перерисовывали весь DOM для каждого изменения, использование виртуального DOM и diffing было бы на несколько порядков быстрее.

Но что, если бы мы могли позволить приложению знать, какие элементы должны изменяться, вообще не полагаясь на какой-либо обход DOM (виртуальный или реальный)? Это, очевидно, было бы еще быстрее.

Ну, это именно то, к чему стремится Svelte.js. Вместо того, чтобы полагаться на виртуальный DOM и сравнивать, Svelte позволяет нам явно объявлять отношения между элементами, используя топологический порядок. Приложение всегда знает, какие элементы должны обновляться и в каком порядке при каждом изменении.

Давайте рассмотрим пример, чтобы понять, что на самом деле означает топологический порядок. Допустим, мы хотим, чтобы переменная B всегда была в два раза больше A. В обычном коде JS (и почти во всех языках программирования и фреймворках) это потребовало бы от нас повторного назначения B каждый раз, когда изменяется A. Например:

var a = 10; var b = a * 2; a = 25; /* a is 25, b still 20 */ b = a * 2; /* re-assigning b to update it to 50 */

Когда мы изменяем значение A, мы повторяем присвоение B, чтобы оно обновлялось. В этом крошечном кусочке кода это не выглядит слишком ужасно, но в реальном приложении это приводит к ненужному повторению и повторному запуску огромных блоков кода.

Но что, если бы существовала декларация, которая позволяла бы нам постоянно привязывать значение B к A таким образом, чтобы всякий раз, когда изменяется A, B изменялось вместе с ним?

Это истинная реактивность и сложная взаимосвязь того, как должны изменяться множественные реактивные переменные и в каком порядке находится топологический порядок. И это революционная особенность Svelte.

Конечно, для такого рода операций нет встроенного синтаксиса JS, поэтому для достижения этого, придерживаясь действительного кода, Svelte перехватывает довольно неиспользуемый фрагмент синтаксиса JS, известный как помеченный оператор, и делает его свой собственный. Возвращаясь к приведенному выше примеру, чтобы значение B было привязано к результату A * 2, было бы достаточно объявить:

Теперь всякий раз, когда меняется А, меняется Б вместе с ним.

Давайте посмотрим, как это будет работать в нашем предыдущем примере с кликабельной кнопкой, добавив абзац, который говорит нам о двойнике.

<script> let count = 0; function (addOne){ count += 1; } $: doubled = count * 2; </script> <button on:click={addOne}> Clicked {count} times </button> <p>{count} doubled is {doubled}</p>

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

Решение для текущих стандартов производительности: Svelte

Со все более сложными приложениями и все более нетерпеливыми пользователями производительность быстро становится ключевым аспектом разработки интерфейса. Любое приложение должно стремиться к мгновенному отклику, если вы хотите, чтобы пользователи оставались вовлеченными (или вообще оставались). Кроме того, недавнее обновление страницы Google придает огромное значение производительности как фактору ранжирования в результатах поиска. Веб-производительность может быть определяющим фактором успеха вашего продукта. В 2021 году производительность — это новое SEO.

Текущие фреймворки в последние годы приложили много усилий для повышения своей производительности, и по большей части они достаточно быстры, чтобы обеспечить хорошее взаимодействие с пользователем и достичь удовлетворительных показателей для SEO. Если ваша команда выполнит свою часть работы, фреймворк, вероятно, не станет ограничивающим фактором для производительности на компьютерах и смартфонах.

Но Интернет — это уже не только компьютеры и смартфоны. У нас есть все виды устройств, подключенных к Интернету, и нам может потребоваться обращаться к ним с одинаковой важностью. Например, платежный терминал может иметь довольно ограниченные аппаратные ресурсы, но предоставление им высокопроизводительного решения может иметь решающее значение для успеха бизнеса. Вот где традиционные фреймворки просто не помогут, и ваш выбор в значительной степени ограничен либо ванильным JS, либо Svelte.js.

Мое собственное знакомство со Svelte заключалось в создании графического интерфейса для интеллектуальных 3D-принтеров, к которому необходимо было получить доступ с настольных компьютеров, мобильных устройств и встроенного браузера Chromium на собственном Raspberry Pi принтера. Мы начали создавать проект в React, но очень быстро стало ясно, что ограниченные аппаратные ресурсы не смогут обеспечить достаточную производительность.

Это показывает одно из самых больших заблуждений в нашем современном наборе интерфейсных инструментов: люди постоянно повторяют «Виртуальный DOM быстр» почти как мантру, но оказывается, что это не совсем так. Это просто «достаточно быстро», но все же дополнительный шаг. Виртуальный DOM — это чистые накладные расходы.

И я не делаю здесь прорывного открытия: команда React знает это очень хорошо, и именно поэтому они создают уровни абстракции поверх базового виртуального DOM, чтобы предотвратить ненужные перекомпоновки с помощью таких инструментов, как shouldComponentUpdate, useMemo или useCallback, и стратегий амортизации. как параллельный режим.

Но даже если вы помешаны на производительности и очень тщательно создаете свое приложение React для достижения превосходной производительности (что, будем честны, большинство существующих кодовых баз даже близко не стоят), ничто не сравнится с скомпилированной, реактивной природой Svelte. Создание вашего приложения в Svelte обычно приводит к написанию примерно на 30% меньше кода, чем React, гораздо меньшему количеству пакетов благодаря его скомпилированному характеру, а отзывчивость на несколько порядков выше.

Встроенный анализ специальных возможностей

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

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

Конечно, это (как и любой автоматизированный тест на доступность) не гарантирует доступности, и, в конце концов, вам все равно решать, предоставлять ли доступный код и взаимодействие с пользователем, но здорово иметь встроенный быстрый линтер прямо в случае мы забыли что-то очевидное.

Стройная популярность: задача достижения критической массы

Позвольте мне привести короткую забавную аналогию: когда формируются планетарные системы, некоторые небесные тела собирают большую часть массы системы. Тем не менее, только те, кому удается получить достаточную массу для запуска ядерного синтеза, превращаются в звезды, а те, кому не хватает лишь немного, в конечном итоге становятся газовыми гигантами. Буквально, гигантский газовый шар.

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

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

Но промышленность ценит стабильность превыше всего. Любой опытный разработчик и большинство заинтересованных сторон придают большое значение стабильности. Они должны быть уверены, что код, который вы пишете сегодня, будет по-прежнему актуален в ближайшие годы, что они смогут найти других разработчиков для поддержки и дальнейшего развития своего приложения с относительной легкостью, что они инвестируют в надежный выбор. а не огромная куча технического долга или будущего устаревшего кода.

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

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

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

Вывод

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

Остается выяснить, достаточно ли этого, чтобы бросить вызов нынешней парадигме и ее сторонникам. Индустрия явно предпочитает стабильность, и, учитывая их широкое распространение и тот факт, что React поддерживается Facebook, а Angular — Google, мы можем быть уверены, что они не исчезнут в ближайшее время. Возможно даже, что если Svelte в конечном итоге докажет, что компиляция и/или истинная реактивность — это путь вперед, они могут просто перепроектировать себя, приняв новую парадигму, сохранив при этом часть своей идентичности.

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

Первоначально опубликовано на https://www.scalablepath.com 15 июля 2021 г.