Code Splitting
React는 기본적으로 SPA(Single Page Application)이다.
SPA (Single Page Application)
웹 사이트의 전체 페이지를 하나의 JS 파일에 담아 액션에 따라 동적으로 화면을 변경하며 표현하는 방식이다.
과거에는 한 페이지마다 크기가 작았기에 페이지 변경 시 서버에서 하나의 페이지가 담긴 html 파일을 통째로 전달해주곤 했다.
하지만, 서버의 부하, 화면 blinking 등의 이슈로 Client Side Rendering인 SPA가 등장하게 되었다.
SEO (검색 엔진 최적화)의 효율이 좋지 않아 최근에는 Server Side Rendering을 고려하는 경우가 많다.
SPA의 가장 큰 문제점은 모든 페이지가 하나의 JS 파일에 담겨져 있으므로 처음 웹 화면이 보여지기까지의 로딩 속도가 길다는 점이다.
코드 스플리팅을 사용해 이를 분리시켜 필요할 때마다 로딩되도록 할 수 있고, 로딩 속도를 개선 시킬 수 있다.
React.Lazy
코드 스플리팅에는 여러 기법이 있지만, React에서 간단하게 사용할 수 있는 React.lazy()를 제공한다.
클라이언트 사이드 렌더링만 가능한 함수로, 서버사이드 렌더링에서 코드 스플리팅을 하고 싶다면 서드파티 라이브러리인 'Loadable Components' 사용해야한다. 또한, 리액트 공식문서에서도 이를 권장하고 있다.
적용하기
import React, { lazy, Suspense } from "react";
const DashBoard = lazy(() => import("./Routes/DashBoard"));
const Exchanges = lazy(() => import("./Routes/Exchanges"));
기존에 import 된 컴포넌트를 위와 같이 lazy 함수로 변경해준다. 반드시 해당 컴포넌트는 default export 되어야 한다.
Suspense
일반적으로 React로 개발된 웹 페이지에서 페이지를 이동할 때 페이지가 새롭게 로딩된다는 느낌을 확실히 받을 수 없지만,
코드 스플리팅을 적용한 페이지를 최초로 이동할 때에는 화면의 깜빡임 등이 발생한다. Suspense의 fallback으로 로딩 화면을 생성해줄 수 있다. 필수적으로 Lazy된 컴포넌트는 Suspense 내에 선언되어야한다.
<Suspense fallback={<div></div>}>
<Exchanges />
<Suspense />
그럼 최상단에 Suspense를 선언하고 모든 컴포넌트를 Lazy로 선언하면 안되나요?
Suspense의 모든 하위 컴포넌트들은 함께 재렌더링된다. 즉, Navigation이나 Footer, Floating Button과 같이 페이지가 바뀌어도 그 자리에서 유지되어야 하는 컴포넌트들이 함께 로딩 화면으로 변경된다는 말이다.
또한, 모든 컴포넌트를 Lazy로 선언해 최초 로딩 속도를 향상 시켰다고 하더라도 결국에 각 페이지에서 재 로딩이 발생하기 때문에 적절하게 분배하지 않으면 더 나쁜 UX를 선사할 수 있다.
Preload
위의 방법대로 Lazy를 사용하면 컴포넌트가 렌더링 될 때 파일이 import 되지만, 미리 파일만을 로딩 할 수도 있다.
const dashboard = import("./Routes/DashBoard");
const DashBoard = lazy(() => dashboard);
위 처럼 분리 작성하게 되면, import 되는 파일에 작성된 것들이 실행된다.
추가적으로
React.Lazy()는 최초부터 존재한 함수가 아니라, 리액트가 업데이트 됨에 따라 제공되고 있는 함수이다. 그래서 이 함수가 생기기 이전에 어떤 방식으로 코드 스플리팅을 적용해왔는지 한번 훑어보면 좋겠다.
'React > React Tech' 카테고리의 다른 글
[React] 다국어 변환 라이브러리 i18n (0) | 2022.06.02 |
---|---|
[React] Redux Thunk (미들웨어) (0) | 2022.05.03 |
[React] Redux 이해하기 (0) | 2022.04.17 |
웹사이트 성능 최적화하기 with LightHouse (0) | 2022.04.13 |