Фундаментальная причина существования современных js-фреймворков

внешний интерфейс JavaScript React.js Web Components

Оригинальная ссылка:The deepest reason why modern JavaScript frameworks exist

Адрес перевода Чжунчэн:Основная причина существования современных js-фреймворков(Перевод тоже сделан мной, но в нем не хватает нескольких картинок, поэтому Наггетсы переизданы~)

Интенсивное чтение «Фундаментальная причина существования современных js-фреймворков» by Хуан Цзыи(Спасибо великому Богу за прочтение, я тоже читал исходный текст по его подсказке, а также кстати привез переводы для всех)

Я видел много, много людей, слепо использующих (интерфейсные) фреймворки, такие как React, Angular или Vue и т. д. Эти фреймворки предлагают много интересного, но обычно люди (думают) используют фреймворки, потому что:

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

но этонетОсновная причина использования фреймворка.

Наиболее существенные причины:

(UI очень сложно синхронизировать с состоянием)

Да, вот почему, давайте посмотрим, почему

Предположим, вы разрабатываете веб-приложение, в котором пользователи могут приглашать других (на мероприятие), отправляя массовые электронные письма. Дизайн дизайнера UX / UI выглядит следующим образом: (до того, как пользователь введет какой-либо адрес электронной почты) есть пустое состояние и добавьте для этого некоторую справочную информацию; (после того, как пользователь введет адрес электронной почты) отобразите адрес электронной почты. , справа от каждого адреса. У каждого есть кнопка для удаления соответствующего адреса.

Состояние этой формы может быть оформлено как массив, содержащий несколько объектов, состоящих из адресов электронной почты и уникальных идентификаторов. В начале массив пуст. Когда (пользователь) вводит адрес электронной почты и нажимает ввод, добавьте элемент в массив иОбновить пользовательский интерфейс. Когда пользователь нажимает кнопку удаления, удаляет (соответствующий в массиве) адрес электронной почты иОбновить пользовательский интерфейс. Вы это чувствовали?Всякий раз, когда вы меняете состояние, вам нужно обновить пользовательский интерфейс.

(Вы можете сказать:) И что? Что ж, давайте посмотрим, как это реализовать без фреймворка:

Реализовать относительно сложный пользовательский интерфейс с нативным (JS)

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

В этом примере HTML отвечает за создание статической страницы, а JavaScript отвечает за создание статической страницы черезdocument.createElementДинамические изменения (структура DOM). Это приводит к первой проблеме: код JavaScript, связанный с построением пользовательского интерфейса, не является интуитивно понятным и легко читаемым, мы разделили конструкцию пользовательского интерфейса на две части (Примечание переводчика: следует относиться к HTML и JavaScript). Хотя мы использовалиinnerHTML, читабельность повышается, но производительность (страницы) снижается, и могут быть уязвимости CSRF. Мы также можем использовать механизм шаблонов, но если вы измените DOM на большой площади, вы столкнетесь с двумя проблемами: неэффективностью и необходимостью перепривязки обработчиков событий.

Но это и не самая большая проблема (неиспользование фреймворков). Самая большая проблема это(вручную) обновлять пользовательский интерфейс каждый раз при изменении состояния. Требуется много кода для изменения пользовательского интерфейса при каждом обновлении состояния. При добавлении адреса электронной почты требуется всего две строки кода для обновления состояния и тринадцать строк кода для обновления пользовательского интерфейса. (В данном случае) мы максимально упростили пользовательский интерфейс (интерфейс и логику)! !

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

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

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

Отзывчивый пользовательский интерфейс экономит все

Так что не из-за сообщества, не из-за инструментов, не из-за экологии, не из-за сторонних библиотек...

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

Если вы знаете некоторые (конкретные) правила для конкретного фреймворка (например, неизменное состояние), вы почти закончили.

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

Как работает фреймворк?

На основе двух основных стратегий:

  • Перерендерите весь компонент, как React. Когда состояние компонента изменяется, (новая) структура DOM вычисляется в памяти и сравнивается с существующей структурой DOM. На самом деле это очень дорого. Поэтому он принимается (для сопоставления реального DOM) с виртуальным DOM.Сравнивая разницу между виртуальным DOM до и после изменения состояния, реальная структура DOM изменяется после расчета изменения. Этот процесс называется примирением.

  • Отслеживайте изменения (добавляя) наблюдателей, таких как Angular и Vue.js. Свойства состояния в приложении отслеживаются, и при их изменении перерисовываются только элементы DOM, зависящие от (измененных) свойств.

Как насчет веб-компонентов?

Часто люди связывают React, Angular и Vue.js (фреймворки и т. д.) сWeb componentsсравнение. Это ясно показывает, что люди не понимают самого большого преимущества, которое предлагают эти фреймворки: сохранение синхронизации пользовательского интерфейса с состоянием. Веб-компоненты не предоставляют этот механизм синхронизации. ЭтоТолькопредоставил<template>Метки, но не обеспечивает никакого механизма координации (между состоянием и пользовательским интерфейсом).Если вы хотите, чтобы пользовательский интерфейс синхронизировался с внутренним состоянием при использовании веб-компонентов в вашем приложении, вам нужно сделать это вручную (разработчиком) или использовать что-то вроде Stencil.js(внутри, как и React, использует виртуальный DOM) и другие библиотеки.

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

комфортно жить без чьей-либо помощи

Если вы хотите понять основные принципы, хотите знатьКонкретная реализация виртуального DOM. Так почему бы не попробовать переписать, используя только виртуальный DOM без использования фреймворка?Родной пользовательский интерфейсШерстяная ткань?

вот рамаосновной, базовый класс для всех компонентов.

Вот переписанный компонент AddressList (с помощью babel для поддержки трансформации JSX).

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

Теперь, помимо обработки событий, это выглядит как приложение React, верно? У нас естьhaverender(),componentDidMount(),setState()и т.п. Как только вы решите проблему синхронизации вашего пользовательского интерфейса в приложении с состоянием, все складывается (компоненты) естественным образом.

можно найти в этомРепозиторий на гитхабеНайдите полный исходный код в формате .

В заключение

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