v3.1.0: значительное повышение производительности и поддержка потокового рендеринга на стороне сервера.
Новый механизм внедрения CSS означает более быстрый рендеринг на стороне клиента в производственной среде, а поддержка потокового рендеринга на стороне сервера обеспечивает более быстрое получение первого байта! 🔥🔥
Более быстрое внедрение CSS в производство
Этот патч готовился давно и имеет долгую историю. Почти полтора года назад (!) Сунил Пай нашел новый и широко неизвестный DOM API: insertRule
. Он позволяет вставлять CSS из JavaScript в DOM с невероятной скоростью; Единственным недостатком является то, что стили нельзя редактировать с помощью DevTools браузера.
Когда Глен и Макс впервые создавали стилизованные компоненты, они были на 100% ориентированы на опыт разработчиков. Для небольших приложений проблем с производительностью было мало, поэтому они решили не использовать insertRule
. По мере того, как распространение росло, и люди использовали стилизованные компоненты для более крупных приложений, внедрение стиля оказалось узким местом для людей с очень динамичными вариантами использования.
Благодаря Райану Шверсу, фронтенд-инженеру Reddit, styled-components v3.1.0 теперь по умолчанию использует insertRule
в производстве.
Мы провели несколько тестов с предыдущей версией (v3.0.2) и новой с insertRule
, и результаты оказались даже лучше наших (и без того высоких) ожиданий:
Первоначальное время монтирования тестового приложения было сокращено примерно в 10 раз, а время повторного рендеринга - примерно в 20 раз!
Обратите внимание, что тесты представляют собой стресс-тестирование библиотеки и не являются репрезентативными для реального приложения. Хотя ваше приложение (вероятно) не будет монтироваться в 10 раз быстрее, время до первого взаимодействия снизилось на сотни миллисекунд в одном из наших производственных приложений!
Вот как стилизованные компоненты выдерживают сравнение с другими основными фреймворками React CSS-in-JS в этих тестах:
Хотя это (пока) не самый быстрый фреймворк CSS-in-JS в микротестах, он лишь ненамного медленнее самых быстрых - до такой степени, что его уже нельзя считать узким местом. Реальные результаты очень обнадеживают, и мы с нетерпением ждем, когда вы все поделитесь своими выводами!
Потоковый рендеринг на стороне сервера
Потоковый рендеринг на стороне сервера был представлен в React v16. Он позволяет серверу приложений отправлять HTML, когда он становится доступным, пока React все еще выполняет рендеринг, что ускоряет время до первого байта (TTFB) и позволяет вашему серверу Node обрабатывать Противодавление проще.
Это плохо сочетается с CSS-in-JS: традиционно мы вставляем тег <style>
со стилями всех ваших компонентов в <head>
после завершения рендеринга React. Однако в случае потоковой передачи <head>
отправляется пользователю до отрисовки каких-либо компонентов, поэтому мы больше не можем вводить в него.
Решение состоит в том, чтобы чередовать HTML с <style>
блоками по мере рендеринга компонентов, а не ждать до самого конца и вводить все компоненты сразу. Поскольку это мешает ReactDOM на клиенте (присутствует HTML, за который React не несет ответственности), мы должны объединить все эти style
теги обратно в <head>
перед регидратацией.
Мы реализовали именно это; теперь вы можете использовать потоковый рендеринг на стороне сервера со стилями компонентов! Вот как:
import { renderToNodeStream } from 'react-dom/server' import styled, { ServerStyleSheet } from 'styled-components' res.write('<!DOCTYPE html><html><head><title>My Title</title></head><body><div id="root">') const sheet = new ServerStyleSheet() const jsx = sheet.collectStyles(<App />) // Interleave the HTML stream with <style> tags const stream = sheet.interleaveWithNodeStream( renderToNodeStream(jsx) ) stream.pipe(res, { end: false }) stream.on('end', () => res.end('</div></body></html>'))
Позже на стороне клиента необходимо вызвать consolidateStreamedStyles()
API, чтобы подготовиться к фазе регидратации React:
import ReactDOM from 'react-dom' import { consolidateStreamedStyles } from 'styled-components' /* Make sure you call this before ReactDOM.hydrate! */ consolidateStreamedStyles() ReactDOM.hydrate(<App />, rootElem)
Вот и все! 💯 (дополнительные сведения см. В потоковой документации)
v3: без критических изменений
Хорошие новости! Если вы используете v2 (или даже v1), новая версия имеет обратную совместимость, и обновление должно происходить без проблем. В эти новые версии внесены десятки улучшений, поэтому, пожалуйста, ознакомьтесь с ними, и мы надеемся, что они вам и вашим посетителям понравятся!
См. Журнал изменений для получения дополнительной информации о выпуске v3.0.0 и v3.1.0.
Оставайся стильным! 💅
Обсудите этот пост в сообществе styled-components.
Спасибо Грегори Шехету за его тесты CSS-in-JS, на которые есть ссылки в этом сообщении.