[Перевод] Лучше, быстрее, мощнее: styled-components v4

Автор материала, перевод которого мы публикуем сегодня, хочет представить сообществу веб-разработчиков бета-версию библиотеки styled-components v4. Он, выступая от лица создателей библиотеки, говорит, что теперь в styled-components имеется новое глобальное API для работы со стилями и нативная поддержка свойств as и ref. Библиотека пошла по пути отказа от .extend, она совместима со StrictMode React v16 и стала лучше, быстрее и мощнее.

txxf6u1rz9jrcize_-uuv7iykni.jpeg

Особенности styled-components v4


Для того чтобы установить свежую версию styled-components, воспользуйтесь такой командой:

npm install styled-components@beta


Вы можете ознакомиться с возможностями библиотеки, проверить их, и, если окажется, что что-то в ней нуждается в улучшении — сообщить об этом разработчикам. Здесь можно найти инструкцию по переходу на новую версию библиотеки. Вот журнал изменений для styled-components v4.0.0-beta.0.

Рассмотрим основные особенности этого релиза styled-components:

  • Уменьшение размера и увеличение быстродействия. Размер библиотеки уменьшен с 16.1 Кб до менее чем 15 Кб (её итоговый размер зависит от вашего бандлера и от использования плагина babel). Скорость монтирования возросла примерно на 25%, скорость повторного рендеринга — примерно на 7.5%.
  • Новое API createGlobalStyle, которое является заменой старого API injectGlobal с поддержкой горячей перезагрузки и тем.
  • Поддержка свойства as — более гибкой альтернативы .withComponent().
  • Избавление от Comp.extend с поддержкой автоматического перевода кодовой базы на унифицированный формат styled(Comp).
  • Полная совместимость со StrictMode React v16. Это, кроме того, означает, что разработчикам пришлось отказаться от поддержки React v15 и других, более старых версий React (хотя, для организации работы со styled-components v4 в React v15, вероятно, можно использовать полифиллы).
  • Нативная поддержка ref для любых стилизованных компонентов, и, благодаря React v16, отсутствие необходимости использования innerRef.


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

Производительность


Когда была выпущена вторая версия styled-components, мы обещали, после доработки основных API, сосредоточиться на производительности. С тех пор, благодаря патчам, мы повышали производительность библиотеки, что, в частности, привело к 10-кратному росту производительности в v3.1.

Работа над быстродействием styled-components продолжается. Благодаря внутренним оптимизациям, касающимся работы с памятью, благодаря учёту особенностей реализации JS-движка и рефакторингу кода, скорость монтирования styled-components v4 и для глубоких, и для широких деревьев компонентов, возросла примерно на 25%. Обновления динамических стилей стали быстрее примерно на 7%. Вот сравнение производительности styled-components v3 и v4, проведённое по результатам трёх испытаний. Первые два связаны с исследованием монтирования деревьев компонентов, третье касается обновления компонентов с динамическими стилями.

4972a70fff6d1beb1a1f5d1bd8970bd4.png
Сравнение производительности styled-components v3 и v4

Эти результаты, полученные в изолированном окружении, выглядят впечатляюще. Однако довольно интересно будет сравнить styled-components v4 с другими библиотеками экосистемы CSS-in-JS, в частности, по скорости монтирования.

7df0d75a3536f9f1588ab9f1da059604.png
Сравнение производительности styled-components v4 и других библиотек

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

Хотя производительность styled-components — это результат развития библиотеки и немалых затрат времени и сил на её совершенствование, это не означает, что улучшениями производительности мы больше заниматься не будем. Если мы обнаружим возможность сделать библиотеку ещё быстрее — мы этой возможностью воспользуемся.

Новое API глобальной стилизации


Мы уже довольно долго занимались разработкой нового API глобальной стилизации. Старое API, injectGlobal, имеет три серьёзных недостатка: оно не поддерживает динамическое обновление, горячую перезагрузку и контекстуальное использование тем.

Теперь мы с удовольствием представляем вам createGlobalStyle — новое API глобальной стилизации, поддерживающее динамическое обновление. Вот как выглядит работа с ним:

import { createGlobalStyle } from "styled-components";
const GlobalStyle = createGlobalStyle`
  html {
    color: red;
  }
`;
export default function App() {
  return (
    
This is my app!
); }


Благодаря использованию createGlobalStyle глобальные стили теперь являются частью дерева компонентов React. Хотя, на первый взгляд, ничего особенного в этом нет, это даёт возможность динамического обновления и горячей перезагрузки стилей, а также позволяет использовать контекстуальные темы для глобальных стилей. Выглядит всё это точно так же, как при работе с любыми другими стилизованными компонентами.

import { createGlobalStyle, ThemeProvider } from "styled-components";
// Глобальные стили, которые теперь поддерживают обновления и темы
const GlobalStyle = createGlobalStyle`
  html {
    background: ${p => p.backgroundColor}
    color: red;
    font-family: ${p => p.theme.fontFamily};
  }
`;
export default function App() {
  return (
    
      
    
  );
}


Отказ от .extend и «сворачивание» компонентов


В этом релизе styled-components имеется внутренний механизм, благодаря которому стилизованные компоненты в обёртках теперь автоматически «сворачиваются», что позволяет рендерить лишь один компонент.

Что это означает для пользователей библиотеки? Дело в том, что API StyledComp.extend появилось в библиотеке для того, чтобы позволить выполнить некоторые оптимизации, основываясь на том факте, что расширяемые компоненты были стилизованными компонентами. Благодаря внутренней работе над автоматическим «сворачиванием» компонентов, при использовании styled(StyledComp) автоматически применяются те же оптимизации, которые применялись благодаря StyledComp.extend. Это означает, что от .extend теперь особенной пользы нет, что позволило отказаться от этого API. Как результат, теперь пользователи библиотеки могут писать меньше кода и получают возможность не тратить время на освоение дополнительного одного API. Мы полагаем, что это очень хорошо.

Полиморфное свойство as


Есть ещё одна новая возможность styled-components v4, к которой мы относимся с большим энтузиазмом. Речь идёт о нативной поддержке свойства as для любых стилизованных компонентов, что позволяет динамически, во время выполнения программы, влиять на рендеринг. Рассмотрим пример:

import styled from "styled-components"
import { Link } from "react-router-dom"
//  рендерит в DOM элемент div
const Component = styled.div`
  color: red;
`
Hello World!
// Но мы можем сделать так, чтобы он рендерил любой другой HTML-тег или компонент!
Hello World!
Hello World!


Если сравнить это с существующим механизмом .withComponent(something), то новое средство является более гибким, так как при его использовании не нужно заранее описывать замену, и, благодаря новому внутреннему механизму «сворачивания», не теряется стилизация если базовый компонент — это styled-component!

import styled from "styled-components"
const RedColor = styled.div`
  color: red;
`
const BlueBackgroundRedColor = styled(RedColor)`
  background: blue;
`
Hello!
// Даже хотя мы переключаемся на рендеринг `span` с рендеринга
// , объект имеет красный цвет поверх синего 
// фона!! (.withComponent на это не способен)


Как видите свойство as — это просто потрясающая штука, которая значительно упрощает рендеринг семантического HTML-кода в любом месте приложения. «Суп» из тегов

больше оправдывать нечем.

Обратите внимание, что пока мы не убедимся в том, что свойство as способно стать подходящей заменой для .withComponent во всех вариантах использования, мы не будем от него отказываться. Предполагается, что этот переходный период продлится не слишком долго, и мы, в очередном крупном релизе, уберём .withComponent.

React v16 и ref


В процессе перехода на API React v16 мы, кроме прочего, обнаружили, что,  благодаря новому API React.forwardRef, можно избавиться от innerRef. Нам никогда особенно не нравился этот приём, так как выглядел он как некий не особо чистый хак. Но благодаря отличной работе команды React теперь можно пользоваться нативным ref:

import styled from "styled-components"
const Component = styled.div`
  color: red;
`
// Позже в функции render
 { this.myRef = element; }}


Улучшения для тех, кто пишет на TypeScript


Мы напрямую этим не занимаемся, но нам очень нравится новый @babel/preset-typescript. Его существование означает, что теперь все, кто пишет на TypeScript, наконец смогут использовать плагин babel для styled-components со всеми его полезностями, включая упрощённую отладку с применением имён компонентов в классах, поддержку серверного рендеринга и уменьшение размеров бандлов.

Кроме того, мы завершили перевод TS-типов в DefinitelyTyped. Теперь сообщество может работать с ними и исправлять ошибки типизации в собственном темпе, не привязываясь к релизам styled-components. Объявления типов можно найти здесь.

Итоги


Из этого материала вы узнали о новых возможностях бета-версии библиотеки styled-components v4 и о внесённых в неё улучшениях. Надеемся, всё это пригодится тем, кто пользуется styled-components, а, возможно, окажется интересным тем, кто только собирается эту библиотеку попробовать.

Уважаемые читатели! Пользуетесь ли вы библиотекой styled-components в своих проектах?

1ba550d25e8846ce8805de564da6aa63.png

© Habrahabr.ru