Хабрахабр

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

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

Особенности 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.

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


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

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


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

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

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

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

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

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

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

Благодаря использованию 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 ( <ThemeProvider theme={{ fontFamily: "Helvetica Neue" }}> <GlobalStyle backgroundColor="turquoise" /> </ThemeProvider> );
}

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

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

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

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

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

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

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

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

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

Предполагается, что этот переходный период продлится не слишком долго, и мы, в очередном крупном релизе, уберём .withComponent. Обратите внимание, что пока мы не убедимся в том, что свойство as способно стать подходящей заменой для .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
<Component ref={element => { this.myRef = element; }}

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

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

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

Итоги

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

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

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»