React lazy

2023. 6. 18.·🎨 프론트엔드 공부/React & Next

📍lazy

✅컴포넌트의 최초 렌더링까지 코드 로딩(예-import 문)을 지연시킬 수 있다

const SomeComponent = lazy(load)

 

📍lazy(load)

✅lazy loading 컴포넌트를 선언하기 위해 컴포넌트 바깥에서 lazy 함수를 호출한다

import { lazy } from 'react';

const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

 

✅매개변수

load

- Promise 또는 .then() 과 함께 쓰이는 유사 Promise 객체를 리턴하는 함수

- lazy 함수로 반환한 컴포넌트가 최초 렌더링되고나서야 load 콜백 함수가 호출된다

- load 콜백 함수 호출이 로드된 후, resolve까지 대기했다가 resolve된 값이 React 컴포넌트로 렌더링된다

- load 콜백 함수가 반환하는 Promise와 그 Promise의 reslove 값 모두 캐시되므로, load는 1번만 호출된다

- 만약 Promise가 reject 되면, 가까운 곳에서 에러가 발생한다

 

✅반환값

- lazy api는 lazy 컴포넌트를 반환

- lazy 컴포넌트의 코드가 로드되는 중에 렌더링을 시도하면 suspend (중단) 된다

- <Suspense> 를 사용하여 로딩중 loading indicator를 표시할 수 있다

 

📍load 함수

✅매개변수

- 없음

 

✅반환값

- Promise 혹은 .then() 을 사용 가능한 유사 Promise 객체

- 반환되는 Promise는 유효한 React 컴포넌트로 resolve되어야 한다

함수, memo, forwardRef 컴포넌트 등..

 

📍Lazy-loading 컴포넌트 w/ Suspense

일반 import와 다르게, lazy api를 사용하면, 컴포넌트의 코드 로딩을 지연시킨다

import { lazy } from 'react';

//import MarkdownPreview from './MarkdownPreview.js'; // 이 코드 대신 아래처럼 import
const MarkdownPreview = lazy(() => import('./MarkdownPreview.js'));

 

이제 이 코드는 dynamic import 에 의존한다 (번들러 or 프레임워크의 기능 필요할 수 있음)

- dynamic import를 통해 on demand 방식으로 로딩 (요청 시 로딩)

- 코드가 로딩중일 때 무엇을 화면에 표시할지 명시해야 함

- 이는 lazy api가 반환하는 컴포넌트 (lazy component)를 Suspense 로 래핑하여 구현할 수 있다

 

<Suspense fallback={<Loading />}>
  <h2>Preview</h2>
  <MarkdownPreview />
</Suspense>

 

📍예제

https://beta.reactjs.org/reference/react/lazy#suspense-for-code-splitting

 

lazy

A JavaScript library for building user interfaces

beta.reactjs.org

 

- MarkdownPreview 컴포넌트는 렌더링을 시도하기 전까지는 로드되지 않는다

- 이 때, 로딩 전이므로 Loading 컴포넌트가 대신 렌더링된다

 

App.js

import { useState, Suspense, lazy } from 'react';
import Loading from './Loading.js';

const MarkdownPreview = lazy(() => delayForDemo(import('./MarkdownPreview.js')));

export default function MarkdownEditor() {
  const [showPreview, setShowPreview] = useState(false);
  const [markdown, setMarkdown] = useState('Hello, **world**!');
  return (
    <>
      <textarea value={markdown} onChange={e => setMarkdown(e.target.value)} />
      <label>
        <input type="checkbox" checked={showPreview} onChange={e => setShowPreview(e.target.checked)} />
        Show preview
      </label>
      <hr />
      {showPreview && (
        <Suspense fallback={<Loading />}>
          <h2>Preview</h2>
          <MarkdownPreview markdown={markdown} />
        </Suspense>
      )}
    </>
  );
}

// Add a fixed delay so you can see the loading state
function delayForDemo(promise) {
  return new Promise(resolve => {
    setTimeout(resolve, 2000);
  }).then(() => promise);
}

 

Loading.js

export default function Loading() {
  return <p><i>Loading...</i></p>;
}

 

MarkdownPreview.js

import { Remarkable } from 'remarkable';

const md = new Remarkable();

export default function MarkdownPreview({ markdown }) {
  return (
    <div
      className="content"
      dangerouslySetInnerHTML={{__html: md.render(markdown)}}
    />
  );
}

 

📍주의사항

✅lazy component의 상태가 예기치 않게 리셋될 때

⭐lazy components는 컴포넌트 바깥에서 선언해야 한다

 
'🎨 프론트엔드 공부/React & Next' 카테고리의 다른 글
  • [React] 불필요한 리렌더링 제거하기
  • 비제어 컴포넌트 vs 제어 컴포넌트
  • React forwardRef
  • [React] 디바운스 함수로 입력 이벤트 최적화하기
지식물원
지식물원
지식이 자라는 식물원!
  • 지식물원
    지식물원
    지식물원
  • 전체
    오늘
    어제
    • 분류 전체보기 (516)
      • 🎨 프론트엔드 공부 (253)
        • JS & TS (92)
        • HTML & CSS (22)
        • React & Next (49)
        • Vue & Nuxt (22)
        • 기타 (68)
      • 🤓 기술 학습 & 공부 기록 (116)
        • Node.js (0)
        • Python (37)
        • 백엔드 (0)
        • 딥러닝 (1)
        • 컴퓨터 일반 (72)
        • 개발 인프라 (6)
      • 👨‍💻 프로젝트 경험 (6)
        • Work (0)
        • Toy (6)
      • ⚙️ 개발 팁 & 노하우 (21)
        • 프론트엔드 (6)
        • 기타 (15)
      • ☕️ 커리어 & 인터뷰 준비 (88)
        • 코딩 테스트 (88)
      • 📰 기술 트렌드 & 생각 정리 (4)
      • 📚 기타 (25)
        • 마케팅 (15)
        • 비개발서적 (10)
  • 블로그 메뉴

    • 태그
  • 링크

  • 공지사항

    • 모바일 접속 시 코드 하이라이팅 깨질 때
  • 인기 글

  • hELLO· Designed By정상우.v4.10.3
지식물원
React lazy
상단으로

티스토리툴바