Javascript — это не просто язык для браузера. Node.JS становится популярной платформой для запуска JS на сервере. Мы учимся создавать модульные веб-сайты, где бизнес-логика и состояние не связаны с разметкой. И, наконец, мы получаем инструменты для создания универсальных веб-приложений. Но что такое универсальные приложения и почему мы должны заботиться о выборке данных?

Универсальные/изоморфные приложения

Сообщество еще не решило, как их называть, но ради единообразия я буду называть их универсальными веб-приложениями. Эти проекты имеют 2 основные особенности:

  • На сервере работает JS
  • Большая часть кода проекта используется совместно браузером и сервером.

Долгое время мы запутывали бизнес-логику с разметкой. Мы сгенерируем некоторый HTML на сервере, а JS запустится на клиенте, чтобы делать AJAX-запросы и вносить изменения в DOM.

Сегодня многие сайты начинаются как SPA, а рендеринг на стороне сервера рассматривается как улучшение.

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

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

Здесь мы видим, что некоторый код будет дублироваться, особенно в SPA. Способ улучшить это — запустить JS на сервере и попытаться написать код, отделенный от DOM. В наши дни рендеринг на стороне сервера можно рассматривать как усовершенствование SPA.

Получение данных в универсальных приложениях

В универсальных приложениях большая часть кода может совместно использоваться браузером и сервером. Одна из частей, которая отличается, — это выборка данных. Node.JS имеет собственный способ выполнения запросов, и ни XMLHttpRequest, ни выборка не поддерживаются.

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

Выбор универсального пакета запросов

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

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

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

Обратите внимание на большую разницу в размере между ними, от 4 КБ до 489 КБ. Как это может быть? Для этого нам нужно понять, что происходит, когда наш код собран.

Объединение API Node.js

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

Примером может служить Buffer, который я использовал в оболочке для [Spotify Web API. Поскольку Buffer не поддерживается в среде браузера, на долю которой приходится 44 КБ JS (минимизированный).

То же самое может произойти с этими библиотеками запросов, когда они содержат код, который должен выполняться только в Node.JS, а не в браузере.

Поле браузера

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

Для этого используйте свойство браузера в файле package.json. Он используется, среди прочего, для определения того, какой файл необходимо заменить другим при объединении. При использовании веб-пакета убедитесь, что цель не установлена ​​или не установлена ​​на веб.

Вы можете увидеть пример в исходном коде суперагента:

или iso-http:

Из протестированных мной библиотек 4 из них использовали браузер, а 2 — нет. Именно эти 2 генерируют самые большие файлы пакетов.

Получение статистики о связке

Непросто узнать, какие модули вносят наибольший вклад в выходной пакет. Вы можете попробовать создать входной JS-файл, который включает только интересующий вас модуль, что я и сделал при сравнении библиотек запросов. Но если вы используете webpack, лучше использовать webpack-visualizer.

Этот инструмент создает круговую диаграмму со всеми необходимыми зависимостями и упрощает поиск виновника.

Еще одна вещь: импорт ES6

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

Это действительно полезно, если вы реализуете оболочку для конечных точек API. Удобно поддерживать все конечные точки, но приложение может быть интересно использовать только некоторые из них.

Я начал экспериментировать с этой сборкой новой оболочки для веб-API Spotify. Он предоставляет каждую конечную точку как экспортированную функцию, а конечные точки, которые не импортируются, не являются частью сгенерированного кода.

Вывод

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

Первоначально опубликовано на jmperezperez.com.