Что случилось с недавней тенденцией «No DomDiff»? Виртуальный Дом не благоухает?

внешний интерфейс Vue.js
Что случилось с недавней тенденцией «No DomDiff»? Виртуальный Дом не благоухает?

предисловие

В последние годы интерфейсный фреймворк претерпел стремительное развитие, хотя у каждой компании по-прежнему есть свой набор уникальных стилей или характеристик, таких как: постепенная стабильность v18,reactв погоне异步渲染,快速响应Эта дорога идет все дальше и дальше;vue3поставивreactiveи другие более простые базовые API-интерфейсы напрямую доступны разработчикам, что делает егоProxyдвигатель построенMutableПрактика реактивного программирования более основательна... Но в целом основные технологии и возможности фреймворка очень похожи. Теперь, если вы позволите себе разработать новый интерфейсный фреймворк, вы можете столкнуться со следующими вариантами:

  1. Основной принцип отбора:
    • обновление всего дерева(immutable): При обновлении не обращает внимания на то, какое состояние изменилось.Пока есть изменение состояния, напрямую сравните все дерево, чтобы найти разницу и соответствующим образом обновить его. Репрезентативный кадр:React.
    • данные реагируют (mutable): при обновлении можно точно узнать, какие состояния изменились, и добиться обновления на уровне узла.vue,Svelte,SolidJS.
  2. Выбор детализации обновления:
    • Уровень приложения: если есть изменение состояния, обновите все приложение, создайте новое виртуальное дерево Dom и выполните Diff со старым деревом. Представитель работает:React, конечно, теперь его виртуальный дом был повышен доFiber.
    • Уровень компонента: Аналогично предыдущему, но на один уровень меньше. Представитель работает:vuev2 и выше.
    • Уровень узла: обновление состояния напрямую связано с операцией конкретного узла обновления. шедеврvue1.x Svelte,SolidJS.
  3. Использовать ли виртуальный дом:
    Этот выбор тесно связан с детализацией схемы обновления, использованной выше:
    • Да: для такой степени детализации обновлений на уровне приложений виртуальный дом просто необходим, потому что вdiffПрежде чем он не сможет получить конкретную информацию об узле этого обновления, он должен пройти последующуюDomDiffОтфильтруйте самые маленькие различия, иначе добавление всего дерева приведет к катастрофе для производительности. Репрезентативный кадр:React,vue, Но здесь стоит отметить, что vue по сути не нуждается в виртуальном доме, потому что его отзывчивый механизм, основанный на сборе зависимостей, может напрямую выполнять обновления на уровне узла, но vue может достичь детализации обновления с помощью абстракции виртуального дома. of (пока на уровне компонентов) предоставляет больше возможностей для развития vue, особенно в плане кроссплатформенного рендеринга, что очень важно.
    • Нет: для фреймворков с гранулярностью обновления на уровне узла обычно нет необходимости использовать виртуальный DOM. Представитель работает:vue1.x Svelte,SolidJS.
  4. Варианты синтаксиса разработки DSL:
    • JSX:React,SolidJS
    • Шаблон + инструкция по составлению:vue(JSX необязательно),Svelte
  5. Другие вспомогательные функции: Это более тривиально, напримерSuspence,Portals,Fragments,Context,Streaming SSRЖдать.

Вы должны быть мудрыми, чтобы понять, что существует какая-то тесная связь между столь многими техническими решениями. Это нетрудно понять, потому что эти технические параметры в конечном итоге служат целям проектирования фреймворка, т.к.vueпреследуемый渐进式,Reactпреследуемый快速响应.

Дифференцированная конкуренция существует в любой сфере, и мир интерфейсных фреймворков не исключение. Всегда будут поздние нишевые школы, которые пытаются бросить вызов некоторым авторитетным практикам, использовать какие-то нетрадиционные средства, чтобы напрямую атаковать болевые точки разработчиков и проводить свою собственную дифференциацию. Он очень популярен в зарубежных странах в последнее времяSolidJS,SvelteВот и все, класс React, класс vue, оба являются представителями невиртуального Dom на уровне узла, и все они утверждают, что находятся впредставлениеилиНезависимые компоненты распределенияАспекты сделали свои собственные характеристики, и тогда я возьму вас, чтобы узнать.

текст

Виртуальный дом делает приложение быстрее или медленнее?

JS Framework BenchmarkЭто тестовый инструмент для оценки производительности JS-фреймворков, аналогичный программному обеспечению для тестирования производительности мобильных телефонов. Автор SolidJS использовал этот инструмент для тестирования почти всех JS-фреймворков на рынке, и у него закончилисьПервыйхорошие оценки, см. подробный процесс тестированияОфициальный сайт. Как именно это делается?

Мое внимание привлекла первая особенность его домашней страницы на github:

image.png

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

Возьмите введение виртуального дома раньшеReactНапример, никогда не говорится: «React быстрее, чем нативные манипуляции с DOM». Потому что его основное мышление заключается в том, чтобы перерисовывать все приложение каждый раз, когда происходит изменение состояния. Если виртуального DOM нет, простая идея состоит в том, чтобы просто сбросить «innerHTML». Многие люди не понимают, что сброс innerHTML на самом деле является разумным, когда все данные в большом списке изменились... Настоящая проблема заключается в менталитете «перерисовать все», даже если изменилась только одна строка данных. , а также необходимо сбросить весь innerHTML, что, очевидно, является большой тратой времени. Вот почему существует Virtual DOM: он гарантирует

  • 1. Как бы сильно не менялись ваши данные, производительность каждой перерисовки приемлема;
  • 2. Вы по-прежнему можете написать свое приложение так же, как и innerHTML.

Итак, вернемся к вопросу, делает ли виртуальный дом приложение быстрее или медленнее? На этот вопрос нужно отвечать в каждом конкретном случае:

  • Первоначальный рендеринг: Virtual DOM > Коллекция зависимостей
  • Небольшое обновление состояния: сбор зависимостей >> виртуальный DOM
  • Множество обновлений состояния: Virtual DOM > Коллекция зависимостей.

Примечание. Виртуальный DOM выше приведен послеmemo|shoudUpdateВ случае экстремальной оптимизации здесь нет конкретного сравнения данных, о нем судят на основе опыта.отвечать.
Таким образом, появление виртуального дома не всегда помогает приложениям работать быстрее, а преследует более важные преимущества и обеспечивает прежнюю производительность.Дизайн фреймворка всегда представляет собой вопрос с несколькими вариантами ответов.В поисках баланса в дизайне рамы - Ю Юйси. diff может привести к серьезным пропущенным страницам кадров и катонам, а состояние при переносе больших приложений становится более сложным, которое занимает основной поток выполнения js, также необходимо оптимизировать для этой технологии. Это тожеReactБыть в v15同步递归Reconciler, реконструкция которого стоила столько, сколькоFiberосновная причина, так какReactС точки зрения принципа работы виртуального дома, виртуальный дом — это всегда неотъемлемая часть, поэтому его мышление пытается максимально сжать пределы этой технологии. Видно, хотя сильнееreact, и этот путь не гладкий.Можно ли полностью изменить свое мышление, например: Могу ли я обойтись без виртуального дома? SolidJS: Абсолютно.

Введение в SolidJS

Существует много React-подобных фреймворков, но больше всего похож на SolidJS....

image.png

Это брат-близнец хуков React... и из-за того, что SolidJS опаздывает, нетReactТяжелое историческое бремя, такое как отсутствие необходимости заниматься совместимостью компонентов класса (SolidJS поддерживает только функциональный стиль), что делает объем исходного кода меньше, чем у большинства функций React.ReactГораздо меньше, что дает ему преимущество, когда дело доходит до загрузки выше сгиба. Вызов скомпилированного напрямуюDOMметод работы, исключаяСравнение виртуального DOMВремя, затраченное на этот шаг, делает всю цепочку обновлений намного проще, чем React.
Это стек вызовов Reactimage.png

Это SolidJSimage.png

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

  • Функции компонентов будут вызываться только один раз за весь жизненный цикл приложения.
    Ментальная модель полностью отличается от React, она такая же, какvue3Последовательно, можно сказать, что обаReact hooks+vue3Преимущества,
  • createEffect автоматически отслеживает зависимости.

image.png

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

  • Порядок вызова хуков не обязателен. То есть можно написать вложенность во внешний слой крючка, hi Da Puben.
  • Решите проблему, заключающуюся в том, что цель Proxy должна быть объектом, с помощью вызова функции. Например, в приведенном выше примере с использованиемgetCountA()решеноvue3изref.valueРаздражение, я лично думаю, что это лучше, чем.valueЕще немного лаконичного. . .

так:SolidJS = React + vue3? У этого ответа разные мнения, но его отзывчивая реализация действительно такая же, как vue, которая основана на коллекции зависимостей публикации-подписки, но не используетvueРазница во время выполнения с виртуальным Домом, но полная шумиха на этапе компиляции, компиляция обновлений состояния как независимыхDOMкак работать. Это дает ему еще одно преимущество: подходит для独立分发组件.

Независимые компоненты распределения

Здесь я меняю еще один, который очень похож на принцип SolidSvelteframework в качестве примера, это лучше, чемSolidJSВремя компиляции сделано более тщательно. Например этот шаблон:

<a>{{ msg }}</a>

будет скомпилирован в следующий код:

function renderMainFragment ( root, component, target ) {
	var a = document.createElement( 'a' );
	
	var text = document.createTextNode( root.msg );
	a.appendChild( text );
	
	target.appendChild( a )

	return {
		update: function ( changed, root ) {
			text.data = root.msg;
		},

		teardown: function ( detach ) {
			if ( detach ) a.parentNode.removeChild( a );
		}
	};
}

Видно, что на основеVirtual DOMПо сравнению с фреймворком такой вывод не требуетVirtual DOMизdiff/patchОперация, естественно, экономит много кода времени выполнения, поэтому она очень мало зависит от времени выполнения, но в чем смысл?

Сталкивались ли вы со следующими болевыми точками при разработке проекта:

Компонент проекта A очень похож на проект B, но когда вы хотите повторно использовать его, вы обнаружите, что один написан в реакции, а другой написан в Vue, а технологический стек не является равномерным. В этом случае, кроме того, Чтобы переписать также, вы хотите попробовать ссылаться на скомпилированный код непосредственно в проекте, упаковывая существующие компоненты отдельно. Потому что подсознательно, скомпилированный код всегда должен быть многоразовым. Но он игнорирует важный момент. Будь то Vue или реагирует, скомпилированный код также содержит относительно тяжелую среду выполнения, в основном разницу виртуального DOM и некоторые другие внутренние API. Сказав все это, есть ли реальное решение вышеуказанной проблемы? ответ:
WebComponent, который является стандартом компонентов, продвигаемым w3c, и не имеет ничего общего со стеком технологий. Хотя сейчас она еще не созрела и требует решения многих проблем. Но если однажды проблемы стандартизации и совместимости будут решены,SvelteНебольшая зависимость от среды выполнения является огромным плюсом для такого типа перекомпиляции. Вы можете себе представить, что вы можете напрямую скомпилировать фреймворк через этот тип фреймворка.WebComponent, вы можете вставлять и запускать везде, и это здорово.

Хвостик

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