lazy loading

YEONGHUN KO·2022년 4월 19일
0

REACT JS - BASIC

목록 보기
23/30
post-thumbnail

인스타 클론 하다가 배웠다.

lazy는 게으르다는 뜻인데 프로그래밍에서는 조금 다른 의미로 쓰인다. 그냥 최소한의 노력으로 최대의 효율을 누리다 의 개념으로 보면 좋을 것 같다.

lazy라는 말은 예전에 바닐라 js의 제너레이터로 지연평가를 하는 방법에 대해서 배울때 들은 적이 있다.

예를 들어 1부터 무한대로 증가하는 infinity함수가 있다고 하자. 이때 앞에서 5의 배수 2개만 뽑아낸다고 하면 결과는 [5,10] 일것이다.

그럼 무한대로 증가하는 함수는 1부터 10까지만 숫자를 만들어내고 그다음엔 멈출것이다. 이렇듯 딱 필요한만큼 만들어서 필요할때 보내주는 것이 지연평가라고 할 수 있을것 같다. 참고로 제너레이터를 이용한 5의배수를 뽑는 코드는 아래와 같다

// 제너레이터는 function키워드 뒤에 *가 붙고, yield라는 키워드를 이용해 값을 저장한다.
function* GenerateNum(num) {
  let i = 1;
  while (i < n) {
    yield i++;
  }
}

function fiveArr(iter) {
  const res = [];
  for (const item of iter) {
    if (item % 5 === 0) {
      res.push(item);
    } else if (res.length === 2) {
      break;
    }
  }

  return res;
}

fiveArr(GenerateNum(100)); // [5,10]

이때 GeneratoNum에 어떠한 수가 들어가도 걸리는 시간은 같을 것이다. fiveArr에서 iter를 통해 값을 요청할때만 GenerateNum가 돌아가기 때문이다.

미리 100개의 원소를 만들어놓고 기다리지 않는다.

위키피디아는 아래와 같이 지연평가를 정의한다.

계산의 결과 값이 필요할 때까지 계산을 늦추는 기법.

그럼 리액트의 lazy는 어떠한 개념으로 사용될까?

컴포넌트를 미리 import하여 번들에 추가하는 기존방식과는 달리, 랜더링할때만 import하여 번들에 추가한다.

그렇게 되면 non-essential code를 tree shaking할 수 있어서 번들 파일이 줄어든다. 번들파일이 줄어들면 로딩속도가 빨라져 UX가 개선된다.

즉 핵심은 필요할 때만 가져온다라는 것 이다.

React.lazy는 dynamic import 기법을 사용한다. 그리고 lazy에 들어있는 import된 컴포넌트가 랜더링 될때 비로소 번들안에 포함된다.

코드를 살펴보자

import React from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));

이때 OtherComponent는 Promise객체를 리턴하고 사용되어질때 비로소 OtherComponent 컴포넌트로 resolve된다.
lazy 로딩으로 랜더링되는 컴포넌트는 Suspense 컴포넌트 안에서 사용할 수 있다.

import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </Suspense>
    </div>
  );

요런식으로 말이다. 이때 Suspense의 fallback prop은 lazy로딩으로 불러올때 잠깐의 틈이 생기는 데 그때 로딩화면처럼 띄어줄 컴포넌트를 출력한다.

이로써 또다시 성능을 최적화 하는 법을 배웠다.

https://reactjs.org/docs/code-splitting.html#reactlazy 참고

profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글