做者|Evan Jacobs
譯者|無明
近日,styled-components v4 正式發佈測試版,新版本的主要特性包括:html
在發佈 v2 時,咱們承諾在肯定核心 API 以後把性能放在第一位,隨後提供了各類補丁版原本提高速度,其中 v3.1 版本的速度提高了 10 倍左右。
在新版本中,咱們將繼續將這一個趨勢保持下去!因爲內存使用方面的優化、JS 引擎實現細節的改進和各類重構,styled-components v4 對深度和寬度組件樹的加載速度提高了約 25%,動態樣式更新速度提高了約 7.5%:
單獨來看,性能已經很棒了。如今讓咱們看看 v4 與 CSS-in-JS 生態系統中其餘庫的加載速度相比會怎樣:
能夠看到,styled-components v4 速度是超快的。在全部較快的庫中,不管是在加載仍是更新速度方面,咱們都處於標準誤差範圍內,說明性能已經再也不是個問題!
這是一個很大的進步,咱們爲此花了不少的時間,但咱們仍將繼續關注潛在的優化,進一步提高性能。react
咱們一直在默默地醞釀一個新的全局樣式 API。舊的 injectGlobal 存在三個問題:沒法動態更新、不能從新熱加載,而且不支持基於上下文的主題化。
咱們引入了 createGlobalStyle,針對全局樣式的全新動態可更新 API!typescript
import { createGlobalStyle } from "styled-components"; const GlobalStyle = createGlobalStyle` html { color: red; } `; export default function App() { return ( <div> <GlobalStyle /> This is my app! </div> ); }
有了 createGlobalStyle,全局樣式就成爲 React 組件樹的一部分。雖然這看起來彷佛不是一個很大的變動,但它能夠動態更新、從新熱加載和基於上下文主題化你的全局樣式。npm
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> ); }
這一版本還進行了內部重構,封裝的樣式組件如今能夠自動「摺疊」,只渲染單個組件。
咱們引入了 StyledComp.extend API,由於擴展的組件是樣式組件,因此能夠對它們進行優化。由於通過內部重構後,能夠進行自動摺疊,因此使用 styled(StyledComp) 時也會自動應用 StyledComp.extend 的優化!這意味着.extend 再也不是 API 的有用部分,因此咱們將其移除。API 越少,須要交付的代碼就越少,一石二鳥!服務器
在這個版本中,還有一件事令咱們感到振奮:樣式組件如今支持「as」 prop,能夠在運行時動態渲染內容!babel
import styled from "styled-components" import { Link } from "react-router-dom" // <Component /> 渲染一個 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() 相比,這個更靈活。何況,使用新的自動摺疊機制,若是基本組件是樣式組件,就不會丟失任何樣式!react-router
import styled from "styled-components" const RedColor = styled.div` color: red; ` const BlueBackgroundRedColor = styled(RedColor)` background: blue; ` <BlueBackgroundRedColor as="span">Hello!</BlueBackgroundRedColor> // 即便咱們從渲染<RedColor />切換到渲染一個`span` , // 在藍色背景上面仍然會呈現出紅色 (這是.withComponent 作不到的)
可見,「as」 prop 很是有用,可讓你更輕鬆地在應用程序的任何位置渲染 HTML。
請注意,咱們尚未棄用.withComponent,但咱們確信「as」 prop 是很好的替代品,不過.withComponent 將在下一個主要版本中移除。app
在咱們內部遷移到新的 React v16 API 期間,咱們還發現,innerRef 能夠經過新的 React.forwardRef API 來實現。咱們並不喜歡這種解決方法,由於它帶有侵入性……不過,如今可使用原生的 ref,這要感謝 React 團隊所作出的努力:dom
import styled from "styled-components" const Component = styled.div` color: red; ` // Later in your render function <Component ref={element => { this.myRef = element; }}
雖然這與咱們沒有直接的關係,但新的 @babel/preset-typescript 確實讓咱們感到眼前一亮。如今,全部的 TypeScript 用戶均可以使用 styled-components babel 插件,並享受它所帶來的好處,包括更容易調試類中的組件名、服務器端呈現支持和更小的捆綁包!強烈推薦。
咱們還完成了從 TS 類型到 DefinitelyTyped 的遷移,這樣社區就能夠迭代它們,並在 styled-components 的發佈週期以外按照本身的節奏修復類型錯誤。能夠從 npm 上獲取 @types/styled-components。
英文原文
https://medium.com/styled-components/announcing-styled-components-v4-better-faster-stronger-3fe1aba1a112ide