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

Class Component & Functional Component Rendering Comparison. #45

Open
kokocan12 opened this issue Jun 26, 2022 · 0 comments
Open

Class Component & Functional Component Rendering Comparison. #45

kokocan12 opened this issue Jun 26, 2022 · 0 comments
Labels

Comments

@kokocan12
Copy link
Owner

kokocan12 commented Jun 26, 2022

Experiment Condition

Rendering 50,000 components at each type.
Each component has 2 event-listeners, and 2 methods, 5 state.
Component code is below.

// Functional Component.
const Func = () => {
    const [direction, setDirection] = useState(false);
    const [age, setAge] = useState(0)
    const [name, setName] = useState('')
    const [address, setAddress] = useState('')
    const [height, setHeight] = useState(150)

    const onClick = () => setDirection(!direction);
    const onDoubleClick = () => setDirection(!direction);

    return <div 
            className='item'
            style={{backgroundColor: direction ? 'blue': 'red'}}
            onClick={onClick}
            onDoubleClick={onDoubleClick}
            ></div>
}

// Class Component.
class Cls extends React.Component {
    constructor() {
        super();
        this.state = { direction : false, age: 0, name: '', address: '', height: 150 };

        this.onClick = this.onClick.bind(this);
        this.onDoubleClick = this.onDoubleClick.bind(this);
    }

    onClick() {
        this.setState({ direction : !this.state.direction });
    }

    onDoubleClick() {
        this.setState({ direction : !this.state.direction });
    }


    render() {
        return <div
                className='item'
                style={{backgroundColor: this.state.direction ? 'blue': 'red'}}
                onClick={this.onClick}
                onDoubleClick={this.onDoubleClick}
                ></div>
    }
}

Initial Rendering

At the beginning, I thought FC(Functional Component) is faster than CC(Class Component).
Because CC need to generate instance of its class before rendering.
FC does not need to generate instance, because its execution is rendering.
But the result is almost same.
I think the reason is that Storing FC state info into VDOM spends almost same resource with CC's initiating.
(the state values of FC are stored in VDOM(Fiber) to memoize prev states.)

Initial Loading of FC, it takes about 550ms for mounting 50,000 components.
image
Initial Loading of CC, it takes about 600ms for mounting 50,000 components.
image

Update

I thought updating components has no difference.
The result is as expected.

Those take about 200ms for updating 50,000 components.
image
image

Memory

I thought CC spends more memory space than FC, because its methods are not reused for this binding.
Also, instances of class are stored in VDOM.
But Re-allocation of methods is not big deal than I expect.
And FC spends more memory space for closure(useState create 1 closure to know what the current Fiber is).

This is memory snapshot of class component.
Cls(the instance of the class component) spends memory spaces.
image

This is memory snapshot of functional component.
There are not Cls, but more closures than CC.
The closure is created when useState used, so 5 * 50000 closures created more than CC.
image

Conclusion

Using functional component gives you convenient develop experience,
but there are chances to miss performance elements.
Of course, you can reduce memory usage by using useReducer instead of useState.
But it is easy to use several useStates because of custom hooks,
you can not combine custom hook into hooks of component.

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

No branches or pull requests

1 participant