React 최적화 - 반응형과 throttle

React, throttle, optimization

Posted by Seongkyun Yu on 2020-11-21
Estimated Reading Time 1 Minutes
Words 310 In Total
Viewed Times

업비트 클론 프로젝트 Downbit 배포 링크

Github Repo 링크


반응형 최적화

반응형을 개발할 때 보통 media tag에 조건을 달아 display: none을 적용하는 방식으로 필요없는 요소를 감춘다.

갱신이 잦은 요소가 아니라면 그것으로 충분하겠지만 리랜더링이 빈번하게 일어나는 요소라면 어떨까?

당연히 DOM에 존재하지 않게 하는 것이 성능 개선에 도움이 될 것이다.

따라서 조건에 따라 아예 컴포넌트를 페이지에 랜더링하지 않는 방법을 선택했다


width값 측정하기

미디어 태그에서 자동으로 viewport의 width값을 측정하는 것과 달리

컴포넌트에서 width 값을 사용하기 위해선 직접 값을 측정해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React, { useCallback, useEffect, useState } from "react";

const withSize = () => (OriginalComponent) => (props) => {
const [widthSize, setWidthSize] = useState(window.innerWidth);
const [heightSize, setHeightSize] = useState(window.innerHeight);

const handleSize = useCallback(() => {
setWidthSize(window.innerWidth);
setHeightSize(window.innerHeight);
}, []);

useEffect(() => {
window.addEventListener("resize", handleSize);
return () => {
window.removeEventListener("resize", handleSize);
};
}, [handleSize]);

return (
<OriginalComponent
{...props}
widthSize={widthSize}
heightSize={heightSize}
/>
);
};

export default withSize;

HOC 패턴을 사용하여 간단하게 만들어 보았다.

다만 이 코드에는 문제가 있는데 resize 이벤트가 발생할 때 너무 많은 이벤트가 한번에 발생한다는 것이다.


width 측정 개선하기

많은 연속적인 이벤트 발생 중 하나만 캐치하는 방법이 있지만 여기선 throttle을 사용해 보겠다.

lodash를 사용하면 쉽게 throttle을 구현할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import React, { useCallback, useEffect, useState } from "react";
import { throttle } from "lodash";

const withSize = () => (OriginalComponent) => (props) => {
const [widthSize, setWidthSize] = useState(window.innerWidth);
const [heightSize, setHeightSize] = useState(window.innerHeight);

const handleSize = useCallback(() => {
setWidthSize(window.innerWidth);
setHeightSize(window.innerHeight);
}, []);

useEffect(() => {
window.addEventListener("resize", throttle(handleSize, 200));
return () => {
window.removeEventListener("resize", handleSize);
};
}, [handleSize]);

return (
<OriginalComponent
{...props}
widthSize={widthSize}
heightSize={heightSize}
/>
);
};

export default withSize;

다음과 같이 window.addEventListener로 이벤트에 handleSize 함수를 등록할 때 throttle을 사용하므로써 이벤트 발생을 200ms마다 한번씩만 처리할 수 있다.


If you like this blog or find it useful for you, you are welcome to comment on it. You are also welcome to share this blog, so that more people can participate in it. If the images used in the blog infringe your copyright, please contact the author to delete them. Thank you !