본문 바로가기
React

[React 스터디] 3 : 코드 분할

by 바나냥 2020. 8. 31.

번들링

모듈 번들러란 웹 애플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 의미합니다.

 

// App.js
import { add } from './Math.js';

// Math.js
export function add(a, b) {
  return a + b;
}

 

Math.js에서 export된 모듈이 App.js에서 import된 후 Webpack으로 빌드했을 때 번들링됩니다.

 

 

https://velog.io/@bigbrothershin/Webpack-JS-ES6-%EB%AA%A8%EB%93%88%EC%8B%9C%EC%8A%A4%ED%85%9C-%EC%9D%B4%ED%95%B4

 

Webpack - 모듈시스템과 번들링의 이해

JavaScript ES6 부터 추가된 모듈 시스템과 모듈 시스템의 번들러를 위한 webpack의 동작을 이해하고자 한다. js/math.js에서 export 된 모듈이 js/app.js에서 import된 후 웹팩으로 빌드를 했을 때 어떤 식으로

velog.io

 


 

코드 분할 (Code Splitting)

 

import()

import("./math").then(math => {
  console.log(math.add(16, 26));
});

 

React.lazy

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

 

React.lazy 함수를 사용하면 동적 import를 사용해서 App이 로드된 후에만 컴포넌트를 렌더링 합니다.

React 16.6 버전에서는 코드를 불러오는 동안 기다릴 수 있고, 기다리는 동안 로딩 상태를 선언적으로 지정할 수 있도록 <Suspense> 컴포넌트가 추가되었습니다.

lazy 컴포넌트는 Suspense 컴포넌트 하위에서 렌더링되어야 하며, 하나의 Suspense 컴포넌트로 여러 lazy 컴포넌트를 감쌀 수도 있습니다. fallback prop은 컴포넌트가 로드될 때까지 기다리는 동안 렌더링하려는 React 엘리먼트를 받아들입니다.

 

import React, { Suspense } from 'react';

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

function MyComponent() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}> //컴포넌트를 다 불러오기 전까지 loading...이라는 컴포넌트를 보여줍니다.
        <section>
          <OtherComponent /> //다 불러오면 해당 컴포넌트를 보여줍니다.
          <AnotherComponent />
        </section>
      </Suspense>
    </div>
  );
}

 

 

Suspense를 사용하면, 렌더링을 시작하기 전에 응답이 오기를 기다리지 않아도 됩니다.

 

// 이것은 promise가 아닙니다. Suspense로 만든 특별한 객체입니다.
const resource = fetchProfileData();

function ProfilePage() {
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}>
      <ProfileDetails />
      <Suspense fallback={<h1>Loading posts...</h1>}>
        <ProfileTimeline />
      </Suspense>
    </Suspense>
  );
}

function ProfileDetails() {
  // 아직 로딩이 완료되지 않았더라도, 사용자 정보 읽기를 시도합니다.
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}

function ProfileTimeline() {
  // 아직 로딩이 완료되지 않았더라도, 게시글 읽기를 시도합니다.
  const posts = resource.posts.read();
  return (
    <ul>
      {posts.map(post => (
        <li key={post.id}>{post.text}</li>
      ))}
    </ul>
  );
}

 

1. fetchProfileData() 내에서 요청을 발동시킵니다.

2. React는 <ProfilePage>의 렌더링을 시도합니다. 자식 컴포넌트로 <ProfileDetails>와 <ProfileTimeline>을 반환합니다.

3. React는 <ProfileDetails>의 렌더링을 시도합니다. resource.user.read()를 호출합니다. 아직 불러온 데이터가 아무 것도 없으므로, 이 컴포넌트는 “정지합니다”. React는 이 컴포넌트를 넘기고, 트리 상의 다른 컴포넌트의 렌더링을 시도합니다.

4. React는 <ProfileTimeline>의 렌더링을 시도합니다. resource.posts.read()를 호출합니다. 또 한번, 아직 데이터가 없으므로, 이 컴포넌트 또한 “정지합니다”. React는 이 컴포넌트도 넘기고, 트리 상의 다른 컴포넌트릐 렌더링을 시도합니다.

5. 렌더링을 시도할 컴포넌트가 남아있지 않습니다. <ProfileDetails>가 정지된 상태이므로, React는 트리 상에서 <ProfielDetails> 위에 존재하는 것 중 가장 가까운 <Suspense> Fallback을 찾습니다. 그것은 <h1>Loading profile...</h1>입니다. 일단, 지금으로서는 할 일이 다 끝났습니다.

 

resource.user를 불러오고 나면, <ProfileDetails> 컴포넌트는 성공적으로 렌더링이 이루어지고 <h1>Loading profile...</h1> Fallback은 더 이상 필요가 없어집니다. 결국 모든 데이터가 준비될 것이고, 화면 상에는 Fallback이 사라질 것입니다. 불러올 때 렌더링을 수행하기 때문에, user posts보다 응답에 먼저 들어있을 경우 응답이 완료되기도 전에 바깥의 <Suspense> 경계를 해제할 수 있습니다.

 

 

 

ko.reactjs.org/docs/concurrent-mode-suspense.html

 

데이터를 가져오기 위한 Suspense (실험 단계) – React

A JavaScript library for building user interfaces

ko.reactjs.org

velog.io/@ansrjsdn/React.lazy-%EC%82%AC%EC%9A%A9%ED%95%B4%EB%B3%B4%EA%B8%B0

 

React.lazy 사용해보기

오늘은 React에 내장되어있는 lazy를 사용해 볼 것이다. React.lazy는 코드분할을 하게 해준다. 코드 분할은 앱을 "지연 로딩"하게 도와주고 사용자들에게 획기적인 성능 향상을 하게 해줍니다. 앱의 �

velog.io

 

비동기식 반응 라우터

특정 Route에 있을 때만 컴포넌트를 로드할 수 있습니다.

다른 컴포넌트와 함께 사용할 때 특정 Route에 있을 때만 로드되도록 컴포넌트를 포장할 수 있습니다.

 

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';

const FunComponent = lazy(() => import('./FunComponent'));
const TerribleComponent = lazy(() => import('./TerribleComponent'));
const TestComponent = lazy(() => import('./TestComponent'));
const LoadingMessage = () => "I'm loading...";

const App = () => (
	<Suspense fallback={<LoadingMessage />}>
        <Switch>
          <Route path="/fun">
            <FunComponent />
          </Route>

          <Route path="/terrible">
            <TerribleComponent />
          </Route>

          <Route>
            <TestComponent />
          </Route>
        </Switch>
      </Suspense>
);

 

 

itnext.io/async-react-using-react-router-suspense-a86ade1176dc

 

Async React using React Router & Suspense

Using Suspense and `lazy` to make asynchronous loading of React components as easy and as intuitive as you’d expect.

itnext.io

 

'React' 카테고리의 다른 글

[React 스터디] 5 : Ref 전달하기  (0) 2020.09.20
[React 스터디] 4: Context  (0) 2020.09.03
숫자만 입력 가능하게 하기  (0) 2020.08.31
Styled-Components (& ~ &, & + &)  (0) 2020.08.27
[Hooks] 3 : useReducer  (0) 2020.08.26

댓글