컴포넌트에서 렌더링 결과에 전혀 영향을 미치지 않는 변화가 일어나면 불필요한 렌더링이 발생하게 된다.
렌더링 과정에서 수행하는 로직이 많을수록 더 많은 컴포넌트를 출력할 수록 악영향을 끼칠 확률이 높아진다.
인라인 스타일을 사용하면 코드도 깔끔하지 않고 불필요한 리렌더링을 발생시킨다.
객체의 메모리 주소값은 항상 다르다. 따라서 가상돔에 변화가 일어났다고 인식을 하게되고, 불필요한 리렌더링이 발생하게 된다.
{} === {} // false
불필요한 리렌더링을 방지하기 위해서는
import React from 'react';
import styled from 'styled-components';
import { Button } from 'antd';
const StyledBtn = styled(Button)`
color: red;
`;
const App = () => {
return <StyledBtn type='submit'>버튼</StyledBtn>
}
export default App;
또는
import React, { useMemo } from 'react';
import { Button } from 'antd';
const App = () => {
const buttonStyle = useMemo(() => ({ color: 'red' }), [])
return (
<>
<Button style={buttonStyle}>버튼</Button>
</>
)
}
export default App;
DOM 조작을 한다는 것은 각 조작이 레이아웃 변화, 트리 변화 그리고 렌더링을 일으킨다. 그러면 그 변화를 적용하기 위해서 브라우저는 연산을 많이 해야하고, 성능이 안 좋아진다.
실제 돔을 만들 수 있는 리액트 요소 트리를 가상 돔이라고 한다.
가상 돔은 UI에서 변경된 부분을 빨리 찾기 위한 개념이므로 컴포넌트의 리액트 요소도 가상 돔의 일부라고 생각할 수 있다.
가상 돔 트리는 렌더링 되지 않기 때문에 연산 비용이 적다. 연산이 끝난 후 최종적인 변화를 실제 DOM에 하나로 묶어서 던져준다. 리렌더링 규모는 커질 수 있지만 렌더 트리 재생성, 레이아웃, 페인팅과 같은 과정이 한번만 일어나기 때문에 효율적이다.