Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Styled Components injects forwardRef in every component generating unecessary overhead #3739

Open
arthurgeron opened this issue May 7, 2022 · 5 comments

Comments

@arthurgeron
Copy link

arthurgeron commented May 7, 2022

Styled component injects forwardRef into every component, forwardRef adds an overhead and has considerably more impact on a Component's render time and JS thread time compared to a regular component, causing FPS drops, tha has been widely discussed here.

I'm wondering if the styled-components' team is aware of that and if it'd be of your interest if I were to open a PR proposing removing forwardRef from the default implementation, making it optional.

@jantimon
Copy link

the issue you linked is over 2 years old - is it still relevant?

@arthurgeron-work
Copy link

I'll run some profilings later today and post the results here

@arthurgeron-work
Copy link

@jantimon After doing some deeper digging I believe this is still relevant.. React's forwardRef uses Object.defineProperty internally, which has been reported as slower than other solutions many times in the past, even though devs assumed it to be "fixed" it still is definetely slower solution. Those extra MS can and will impact greatly for hundreds or thousands of styled elements being rendered at a given time on a screen, as well as slowing down first render times.

Speed of Object.defineProperty vs a straight setter can be seen on this example here.

@jantimon
Copy link

jantimon commented May 17, 2022

the code you mentioned is only active during development - or did I miss something?

did you do any benchmarks how much slower rendering 1000 forward ref vs 1000 normal components?

would be quite interesting to understand the real impact :)

did you see this one here?

Object.defineProperty(WrappedStyledComponent, 'defaultProps', {

@arthurgeron-work
Copy link

Using a sample of 10k children
Regular Component:
image

Forward Ref Component:
Captura de Tela 2022-05-17 às 22 52 00

Styled:
Captura de Tela 2022-05-17 às 22 54 47

Those results are interesting, though not for the reason I imagined styled-components seems to add significant overhead time to render time to components. Nonetheless forwardRef does not have the impact as I thought, as you mentioned it did have the defineProperty isn't called inside forwadRef on production mode, but it is called inside styled components and could be one of the reasons for that impact on render time.

Devtools profiles: profiles.zip

Code used:

import React, { forwardRef, ReactNode } from 'react';
import logo from './logo.svg';
import './App.css';
import styled from 'styled-components';

const array = new Array(10000).fill(0);

function Div({children}: {children: ReactNode} ) {
  return <div>{children}</div>
}

const FowardRef = forwardRef((props: {children: ReactNode}, ref) => <div>{props.children}</div>);

const Styled = styled.div``;

function App() {
  return (
    <div className="App">
      <header className="App-header">
        {array.map((_,index) => <Styled>Test line {index}</Styled>)}
      </header>
    </div>
  );
}

export default App;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants