React 최적화 - 반응형과 throttle

Seongkyun Yu·2020년 11월 18일
21

오늘의 이슈

목록 보기
2/2

😥 두나무의 요청으로 클론 사이트 배포를 중단하였습니다...
💁‍♂️ 레포 링크

반응형 최적화

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

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

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

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


width값 측정하기

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

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

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을 구현할 수 있다.

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마다 한번씩만 처리할 수 있다.

profile
FrontEnd Developer

2개의 댓글

comment-user-thumbnail
2020년 12월 15일

Thanks a lot for sharing!JOKER123

답글 달기
comment-user-thumbnail
2021년 4월 12일

업비트에선 왜 중단해달라고 요청했나요?

답글 달기