Я всегда игнорировал рендеринг на стороне сервера, когда работал с библиотеками Virtual DOM, но недавно начал думать, как улучшить производительность SSR, чтобы он мог конкурировать с рендерерами шаблонов на основе строк.

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

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

Вместо того, чтобы сосредотачиваться на микрооптимизации существующих renderToString() алгоритмов, мы должны полностью скрыть все детали о структурах данных и алгоритмах Virtual DOM за некоторым простым в использовании API, который можно будет эффективно переопределить для рендеринга строк в среде Node.js.

Скрытие всех деталей не означает, что мы должны жертвовать какими-либо функциями, необходимыми для библиотек Virtual DOM, такими как передача узлов Virtual DOM, это просто означает, что мы должны иметь возможность изменять внутренние структуры данных.

Выполнение

Чтобы попробовать этот новый подход, я переработал API ivi и внедрил новый серверный рендерер.

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

Контрольные точки

Чтобы проверить, как он будет работать с рендерерами на основе строк, я выбрал тесты, которые использовались библиотекой Marko.

Кроме того, в статье Почему Marko Fast они заявляют о производительности библиотек Virtual DOM и о том, что они имеют огромное преимущество при рендеринге на стороне сервера по сравнению с библиотеками Virtual DOM.

результаты поиска

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

ivi (0.8.0) x 6,365 ops/sec ±0.79% (93 runs sampled)
marko (4.4.16) x 3,543 ops/sec ±1.48% (85 runs sampled)
react (15.6.1) x 88 ops/sec ±2.67% (71 runs sampled)

подборщик цветов

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

ivi (0.8.0) x 21,352 ops/sec ±0.74% (92 runs sampled)
marko (4.4.16) x 8,153 ops/sec ±0.99% (88 runs sampled)
react (15.6.1) x 560 ops/sec ±2.71% (79 runs sampled)

Все тесты выполнялись на Node v9.0.0-v8-canary. Исходный код теста доступен в репозитории Github.

Я надеюсь, что эти результаты показывают, что рендеринг Virtual DOM на стороне сервера может быть быстрым и может легко конкурировать со строковыми рендерерами.