[Unit 3] React의 주목해야할 기능

JeongYeon·2023년 5월 22일
0

[SEB FE]section4

목록 보기
7/16
post-thumbnail

코드 분할(Code Spliting)

코드 분할(code spliting)
대부분의 리액트 앱은 webpack이나 rollup과 같은 툴을 사용해 번들링을 한다. 번들링을 하면 html웹 페이지에 js를 쉽게 추가할 수 있다.
하지만 예전과 달리 지금은 js엔진이 해석해야할 js코드양이 많아지면서 번들링했을때 특정지점에서 코드를 해석하고 실행하는 정도가 느려졌다.
어느페이지에서 코드를 해석하고 실행하는 정도가 느려졌는지 파악해 번들을 나눈 뒤 필요한 코드만 불러올 수 수는 없을까? 라는 아이디어에서 시작한 것이 코드분할이다.


번들이 거대해지는 것을 방지하기 위한 좋은 해결방법은 번들을 물리적으로나누는 것이다.
코드분할은 런타임 시 여러 번들을 동적으로 만들고 불러오는 것으로 번들러가 지원하는 기능이다.
코드분할을 하게 되면 지금 당장 필요한 코드가 아니면 따로 분리시키고, 나중에 필요할 때 불러와 사용할 수 있다.

번들 분할 / 줄이는 법
번들링 되는 파일에는 서드파티 라이브러리도 포함된다.
( 서드파티 라이브러리 : 개인 개발자, 프로젝트 팀, 업체 등 에서 개발하는 라이브러리, 제 3자 라이브러리 )
서드파티 라이브러리는 사용자에게 다양한 메서드를 제공해주기 때문에 코드 양이 많고 번들링 시 많은 공간을 차지한다.
그래서 사용중인 라이브러리의 전부를 불러오는 것보다 따로따로 불러와서 사용하는게 공간 차지를 줄일 수 있다.

/* 이렇게 lodash 라이브러리를 전체를 불러와서 그 안에 들은 메서드를 꺼내 쓰는 것은 비효율적입니다.*/
import _ from 'lodash';
...
_.find([]);
/* 이렇게 lodash의 메서드 중 하나를 불러와 쓰는 것이 앱의 성능에 더 좋습니다.*/
imprt find from 'lodash/find';
find([]);

lodash라는 라이브러리는 하나의 폴더와같고, 그 폴더 안에는 개발 시 다양한 상황에 쓰기 좋은 함수 코드들이 있다.
이 함수 코드들의 양이 많아 정말로 필요한 것 한두 개만 쓰이면 나머지는 그냥 쓰이지 않고 덩어리로 앱 내부에 남게 된다.
그래서 필요한 것 한 두개만 가져다 쓰는 방식으로 개발하는 것이 좋다.


React에서의 코드 분할
리액트에서 코드분할 방법은 dynamic import(동적 불러오기)를 사용하는 것이다. 그전에는 코드파일의 최상위에 import 지시자를 사용하는 static import(정적 불러오기)를 사용했다.

/* 기존에는 파일의 최상위에서 import 지시자를 이용해 라이브러리 및 파일을 불러왔습니다. */
import moduleA from "library";
form.addEventListener("submit", e => {
 e.preventDefault();
 someFunction();
});
const someFunction = () => {
 /* 그리고 코드 중간에서 불러온 파일을 사용했습니다. */
}

기존에는 항상 import를 문서의 상위에 위치했고, 블록문 안에서는 사용할 수 없는 제약이 있었다.
하지만 이제는 구문 분석과 컴파일 해야하는 스크립트의 양을 최소화하기 위해 dynamic import 구문을 지원한다.

form.addEventListener("submit", e => {
  e.preventDefault();
	/* 동적 불러오기는 이런 식으로 코드의 중간에 불러올 수 있게 됩니다. */
  import('library.moduleA')
    .then(module => module.default)
    .then(someFunction())
    .catch(handleError());
});
const someFunction = () => {
    /* moduleA를 여기서 사용합니다. */
}

dynamic import는 then함수를 사용해 필요한 코드만 가져온다.
가져온 코드에 대한 모든 호출은 해당 함수 내부에 있어야 한다.
dynamic import는 React.lazy와 함께 사용할 수 있다.


React.lazy() & Suspense

React.lazy()
이 함수를 사용하면 dynamic import를 사용해 컴포넌트를 렌더링할 수 있다.
컴포넌트를 동적으로 import 할 수 있어서 초기 렌더링 지연시간을 어느정도 줄일 수 있다.

import Component from './Component';
/* React.lazy로 dynamic import를 감쌉니다. */
const Component = React.lazy(() => import('./Component'));

React.lazy로 감싼 컴포넌트는 단독으로 사용할 수 없고 React.suspense컴포넌트 하위에서 렌더링해야 한다.

React.Suspense
suspense는 아직 렌더링이 준비되지 않은 컴포넌트가 있을 때 로딩 화면을 보여주고, 로딩이 완료되면 렌더링이 준비된 컴포넌트를 보여주는 기능이다.

/* suspense 기능을 사용하기 위해서는 import 해와야 합니다. */
import { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
const AnotherComponent = React.lazy(() => import('./AnotherComponent'));
function MyComponent() {
  return (
    <div>
			{/* 이런 식으로 React.lazy로 감싼 컴포넌트를 Suspense 컴포넌트의 하위에 렌더링합니다. */}
      <Suspense fallback={<div>Loading...</div>}>
				{/* Suspense 컴포넌트 하위에 여러 개의 lazy 컴포넌트를 렌더링시킬 수 있습니다. */}
        <OtherComponent />
				<AnotherComponent />
      </Suspense>
    </div>
  );
}

Suspense컴포넌트의 fallbackprop은 컴포넌트가 로드될때까지 기다리는동안 로딩 화면으로 보여줄 리액트 엘리먼트를 받아들인다.
Suspense컴포넌트 하나로 여러 개의 lazy 컴포넌트들을 보여줄 수 있다.


React.lazy & Suspense적용
중간에 적용시키는 것보다 웹 페이지를 불러오고 진입하는 단계인 Route에 이 두 기능을 적용하는 것이 좋다.

import { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);

내용 출처, 참조 : 코드스테이츠
이미지 출처 : 코드스테이츠

profile
프론트엔드 개발자 될거야( ⸝⸝•ᴗ•⸝⸝ )੭⁾⁾

0개의 댓글

관련 채용 정보