ru:https://highload.today/blogs/konfiguratsiya-iz-bekenda-na-frontend/ ua:https://highload.today/uk/blogs/konfiguratsiya-iz-bekenda-na-frontend/
logo
Решения      03/11/2021

Как передать конфигурацию из бэкенда на фронтенд: почему мой подход сработает лучше остальных

Николай Коваленко BLOG

Backend Developer в Ronis Business Tools

Часто для реализации какого-либо конфигурируемого функционала на фронтенде необходимо передать параметры конфигурации из бэкенда на фронтенд. Для этого используется множество неоптимальных подходов.

Простой подход

Как это обычно делают? Подключают вот такой вот js-скрипт в head-блок:

<html>
  <head>
    <!-- блокировка рендеринга страницы на время выполнения скрипта -->
    <script>
      const configuration = <?php echo json_encode($configuration) ?>;
    </script>

    <!-- блокировка рендеринга страницы на время выполнения скрипта -->
    <script>
      //какое-то использование конфигурации в head
      window.console.log(configuration);
    </script>

    <!-- блокировка рендеринга страницы на время загрузки и выполнения скрипта -->
    <script src="/app-configuration-initialization.js"></script>
  <body>
    <!-- блокировка рендеринга страницы на время выполнения скрипта -->
    <script>
      //какое-то использование конфигурации в body
      window.console.log(configuration);
   </script>
  </body>
</html>

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

Казалось бы, все хорошо. Удобно конфигурировать и удобно использовать. Но есть в таком подходе ряд проблем с производительностью.

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

Часто используемый подход

Что же можно улучшить в этой ситуации? Итак:

  • во-первых, подключить внешний js-скрипт без блокировки рендеринга страницы;
  • во-вторых, опустить конфигурацию и весь js-код, использующий ее, как можно ниже.

Давайте посмотрим, как это будет выглядеть:

<html>
  <head>
    <!-- загрузка скрипта теперь не блокирует рендеринг страницы -->
    <!-- скрипт будет выполнен после инициализации всей страницы -->
    <!-- не страница ждет скрипт, а скрипт страницу -->
    <script defer src="/app-configuration-initialization.js"></script>
  <body>
    <!-- блокировка рендеринга страницы на время выполнения скрипта --> 
    <script> 
      const configuration = <?php echo json_encode($configuration) ?>;
    </script> 

    <!-- блокировка рендеринга страницы на время выполнения скрипта --> 
    <script> 
      //какое-то использование конфигурации в head 
      window.console.log(configuration); 
    </script>
    <!-- блокировка рендеринга страницы на время выполнения скрипта -->
    <script>
      //какое-то использование конфигурации в body
      window.console.log(configuration);
   </script>
  </body>
</html>

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

Онлайн-курс "Чистий код та патерни проєктування" від robot_dreams.
Прискорюйте й спрощуйте процес розробки.Під менторством лектора з 15-річним досвідом ви навчитеся застосовувати 20+ шаблонів, опануєте рефакторинг і принципи чистого коду.
Детальніше

Каждому свое место

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

Итак, выносим весь js-код, который можем, во внешние скрипты:

<html>
  <head>
    <!-- загрузка скрипта теперь не блокирует рендеринг страницы -->
    <!-- скрипт будет выполнен после инициализации всей страницы -->
    <!-- не страница ждет скрипт, а скрипт страницу -->
    <!-- в этом же скрипте теперь находится весь код использующий конфигурацию -->
    <script defer src="/app-configuration-initialization.js"></script>
  <body>
    <!-- блокировка рендеринга страницы на время выполнения скрипта --> 
    <script> 
      const configuration = <?php echo json_encode($configuration) ?>;
    </script> 
  </body>
</html>

Стало намного лучше, js-код инициализации конфигурации все еще блокирует окончание загрузки страницы.

Отложить на потом не так уж и плохо

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

Подробнее и с примерами можно посмотреть в видео:

Совет от Google, конечно, интересный и хороший, но всегда же можно сделать лучше.

Есть у тега скрипт — возможность задать его тип. И есть такой тип как application/JSON. Его особенность в том, что браузер не парсит его содержимое во время рендеринга страницы и попросту пропускает такие теги, как вроде бы их и нет вовсе. Но при этом мы можем получить содержимое этих тегов в виде текста в нашем js-скрипте и распарсить уже известным нам методом, предложенным в видео.

В итоге у нас получается вот такой код:

Онлайн-курс "Режисура та візуальний сторітелінг" від Skvot.
Перетворюй свої ідеї на сильні історії в рекламі, кліпах чи кіно Досвідом ділиться режисер, продюсер та власник продакшену, який 10+ років у професії.
Детальніше про курс
<html>
  <head>
    <!-- загрузка скрипта теперь не блокирует рендеринг страницы -->
    <!-- скрипт будет выполнен после инициализации всей страницы -->
    <!-- не страница ждет скрипт, а скрипт страницу -->
    <!-- в этом же скрипте теперь находится весь код использующий конфигурацию -->
    <!-- в этом же скрипте теперь происходит инициализация конфигурации-->
    <script defer src="/app-configuration-initialization.js"></script>
  <body>
    <!-- скрипт не блокирует рендеринг страницы и не выполняется --> 
    <script type="application/json" id="app-configuration-json"> 
      <?php echo json_encode($configuration) ?>;
    </script> 
  </body>
</html>

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

Итоги

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

Повторим принципы, которые были реализованы этим подходом:

  • внешние ресурсы нужно подключать асинхронно, чтобы не блокировать рендеринг страницы;
  • использовать js-скрипты в теле страницы нельзя, чтобы не блокировать рендеринг страницы;
  • передавать конфигурацию лучше всего через script-тег с типом application/JSON и парсить ее при инициализации с помощью JSON.parse, чтобы не блокировать рендеринг страницы и onLoad-событие.

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

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

Курс-професія "Motion Designer" від Skvot.
Навчіться створювати 2D- та 3D-анімації у софтах After Effects, Cinema 4D та Octane Render. Протягом курсу ви створите 14 моушн-роликів, 2 з яких — для реального клієнта.
Детальніше про курс

If you have found a spelling error, please, notify us by selecting that text and pressing Ctrl+Enter.

Онлайн-курс "Режисура та візуальний сторітелінг" від Skvot.
Перетворюй свої ідеї на сильні історії в рекламі, кліпах чи кіно Досвідом ділиться режисер, продюсер та власник продакшену, який 10+ років у професії.
Детальніше про курс

Этот материал – не редакционный, это – личное мнение его автора. Редакция может не разделять это мнение.

Топ-5 самых популярных блогеров марта

PHP Developer в ScrumLaunch
Всего просмотровВсего просмотров
2434
#1
Всего просмотровВсего просмотров
2434
Founder at Shallwe, Python Software Engineer (Django/React)
Всего просмотровВсего просмотров
113
#2
Всего просмотровВсего просмотров
113
Career Consultant в GoIT
Всего просмотровВсего просмотров
95
#3
Всего просмотровВсего просмотров
95
CEO & Founder в Trustee
Всего просмотровВсего просмотров
94
#4
Всего просмотровВсего просмотров
94
Рейтинг блогеров

Ваша жалоба отправлена модератору

Сообщить об опечатке

Текст, который будет отправлен нашим редакторам: