성능 최적화

wldls·2023년 7월 20일
0

React

목록 보기
12/12

login

최적화 전

최적화 후

  1. 각 함수에 useCallback을 추가하여 불필요한 렌더링을 방지
  2. 전체 컴포넌트를 React.memo로 감싸서 불필요한 리렌더링을 방지

follower, following

최적화 전

공통 : UserFollow 컴포넌트에 React.memo를 사용하여 불필요한 리렌더링을 방지

공통 추가 코드

  // 불필요한 리렌더링 방지용 메모이제이션 컴포넌트
  const MemoizedUserFollow = React.memo(UserFollow);

map

최적화 전

최적화 후

변경된 코드에서 기존에 비동기 로직 없이 지도 SDK를 불러오던 부분에서 새로운 코드는 loadScript 함수와 promise를 사용하여 비동기적으로 지도 SDK를 가져옵니다. 이를 통해 지도 SDK가 완전히 로딩되고 실행될 때까지 기다리게 되어, 지도 기능과 관련된 오류가 줄어듭니다. 또한, REACT_APP_KAKAO_MAP_KEY 라는 환경 변수를 사용하여 보안을 강화하였습니다. 이렇게 함으로써 이전 코드에서 하드코딩되어 있던 API 키를 사용하지 않고 환경 변수에서 가져올 수 있으므로, 키 관리가 훨씬 쉬워집니다. 요약하면, 코드 수정으로 인한 성능 최적화와 보안 강화의 결과를 확인할 수 있습니다:
1. 지도 SDK 로딩을 비동기적으로 처리하여 더 안정적인 지도 기능 이용.
2. 환경 변수를 사용하여 API 키 관리를 개선하고 보안을 강화.

🚨 성능 문제점 🚨

document.write() 피하기
연결이 느린 사용자의 경우 document.write()에서 동적으로 삽입된 외부 스크립트로 인해 페이지 로드가 몇십 초까지 지연될 수 있습니다.

해결

수정하신 코드대로 동작한다면 document.write()를 사용하지 않고 외부 스크립트를 비동기적으로 로드할 수 있는데, 이를 통해 페이지 로딩 성능을 개선할 수 있습니다. 기존 코드에서는 아래 부분을 변경하였습니다.

javascript
const loadScript = (url) => {
    return new Promise((resolve, reject) => {
        const script = document.createElement('script');
        script.src = url;
        script.async = true;
        script.onload = resolve;
        script.onerror = reject;
        document.head.appendChild(script);
    });
};

변경된 코드에서는 document.createElement('script')를 이용하여 script 태그를 동적으로 생성하고,async 속성을 사용하여 외부 스크립트를 비동기적으로 로드하도록 했습니다. 이 방식으로 외부 스크립트를 로드할 경우, 문제점으로 지적된 document.write() 를 사용하지 않고도 성능 개선을 기대할 수 있습니다. public/index.html에서 script 태그를 제거해주세요. 그리고 REACT_APP_KAKAO_MAP_KEY는 .env 파일에 저장해야 합니다. 수정된 코드가 원래 기능을 모두 구현하면서 성능 개선을 달성할 수 있도록 코드를 꼼꼼히 테스트해주세요. 만약 문제가 발생하면 사이트의 로딩 속도와 관련된 정보를 참조하여 추가로 최적화할 수 있습니다.

🚨 성능 문제점 🚨

과도한 DOM 크기 지양하기 요소 5,031개 ??
DOM이 크면 메모리 사용량이 늘어나고 스타일 계산 시간이 길어질 수 있으며 큰 비용이 드는 레이아웃 리플로우가 발생할 수 있습니다.

해결

이전에 제공된 코드와 비교하여 성능 최적화가 이루어진 부분은 PreschoolMap 및 PreschoolList 컴포넌트를 비동기적으로 불러올 수 있게 처리한 부분입니다. 이것이 단계적으로 컨텐츠를 로딩할 수 있게 하여 초기 로드 시간을 줄이고 성능 설정을 개선할 수 있습니다. 이러한 변경은 다음 코드에서 확인할 수 있습니다.

const PreschoolMap = lazy(() =>
  import('../../components/mapInfo/PreschoolMap'),
);
const PreschoolList = lazy(() =>
  import('../../components/mapInfo/PreschoolList'),
);


<Suspense fallback={<div>Loading...</div>}>
  <PreschoolMap
    ...
  />
  <PreschoolList
    ...
  />
</Suspense>
profile
다양한 변화와 도전하는 자세로

0개의 댓글