Фреймворки JavaScript! Любите их или ненавидите, нельзя отрицать их влияние на область веб-разработки, куда бы вы ни повернулись, появляется новая среда JavaScript. Когда вы ищете работу, практически неизбежно требуется опыт работы с React, Vue, Angular, Ember или даже Svelte. Затем, когда вы думаете, что уже все это видели, начинают появляться и мета-фреймворки, Next.js для React, Nuxt.js для Vue, Svelte-Kit или Sapper для Svelte, все с обещанием причудливых вещей, таких как сервер. сторонний рендеринг и ваш внутренний API, интегрированный с вашим интерфейсным кодом.

При этом нельзя утверждать, что эти фреймворки не крутые. Приятно иметь возможность писать JavaScript, встроенный в ваш HTML, потому что кажется настолько интуитивно понятным, что можно объявить функциональное поведение, скажем, формы прямо там, где эта форма находится в вашем коде. Затем, когда вы захотите иметь возможность использовать эту форму в своем коде в другой раз, просто выделите ее в отдельный компонент и вставьте туда, куда хотите. Или, если вы хотите отображать эту форму только в том случае, если пользователь выполнил предыдущие шаги, используйте доступный условный рендеринг.

Говоря о фреймворках JavaScript, есть как оптимисты, так и пессимисты. Оптимисты смотрят на React и видят в нем большой набор функций, интуитивно понятный синтаксис и парадигму, основанную на компонентах. Однако пессимисты могут взглянуть на React и увидеть только раздувание, медленную виртуальную структуру DOM и SPA, что значительно усложняет оптимизацию и развертывание поисковой системы. Хотя обе школы мысли имеют убедительные доводы, я думаю, что важно сделать шаг назад и задать важный вопрос.

Почему вообще существуют фреймворки?

Фреймворки, API и библиотеки являются неотъемлемой частью разработки, и перед ними стоит важная задача: упростить разработку. Мы, разработчики, делаем многое: проектируем, кодируем, отлаживаем, тестируем, развертываем и поддерживаем все в благородном стремлении найти решение проблемы. Поэтому все, что облегчает нам весь этот процесс, приветствуется в основном с распростертыми объятиями. Это то, что делают фреймворки JavaScript, они дают нам доступ к широкому спектру инструментов, которые упрощают процесс разработки веб-приложения или страницы.

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

Рекомендации по фреймворкам

*Я хочу подчеркнуть, что в основном буду использовать React в качестве примера, так как это то, с чем я в основном знаком. Если я ошибаюсь/ввожу в заблуждение или несправедлив в чем-то, или вы считаете, что необходимо внести редактирование/поправку, просто дайте мне знать.

Виртуальный дом

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

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

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

Раздувание

Если я прямо сейчас запускаю create-react-app, что является наиболее распространенным способом настройки среды разработки React, он загружает 150 мегабайт JavaScript на мое устройство в виде node_modules. Это безумие. Это не просто зависимости развития. Мое личное портфолио, которое по праву построено на React, отправляет 150 КБ JavaScript для отображения в браузере. Это потому, что для того, чтобы React работал, он должен отправить инструкции о том, как создать виртуальный DOM и все ваши компоненты. Это может резко снизить производительность и вызвать реальное торможение на стороне клиента.

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

Рендеринг на стороне клиента

Ваш браузер не просто отправляет большую кучу JavaScript, он также отправляет очень маленький HTML-файл, который необходим браузеру, чтобы понять, что делать даже с имеющимся у него JavaScript. Файл HTML существует, поэтому при запуске сценария он может ориентироваться на тело HTML как на корень приложения. Вот почему, если вы зайдете на веб-сайт на основе React (например, мое портфолио), вы увидите div с именем root, еще один с именем App, и, наконец, начнут появляться компоненты.

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

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

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

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

Одностраничные приложения

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

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

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

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

И что?

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

Итак, когда я использую Framework?

Скажем, вы ищете книгу. Вы заходите в книжный магазин, и они говорят, что она у них есть, но она продается только в упаковке с 4 другими книгами по цене 50 долларов. Вы также можете купить его отдельно онлайн за 15 долларов. Какой из них имеет смысл? Ну видите, это зависит. Если вам действительно нужна только эта книга и вы никогда не планируете читать какие-либо другие книги в пакете, то очевидным выбором будет онлайн-вариант, вы заплатите немного больше за книгу, чем в пакетном варианте, но вы сэкономите деньги. в долгосрочной перспективе. Однако, если вы проявляете интерес к другим книгам и видите, что читаете их, возможно, имеет смысл купить и эти другие книги по более низкой цене по отдельности. Я уверен, вы понимаете, к чему я клоню.

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

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

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

Есть ли золотая середина?

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

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

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

Забрать

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

Удачного программирования всем!