๐Ÿ“ฆ 23. ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…๊ณผ Lazy Loading โ€” ์‚ฌ์šฉ์ž์—๊ฒŒ ๋” ๋น ๋ฅธ ์•ฑ์„ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•

JM_Devยท2025๋…„ 5์›” 4์ผ
0
post-thumbnail

์ฒ˜์Œ์—๋Š” ํŽ˜์ด์ง€ ํ•˜๋‚˜์— ์ฝ”๋“œ๊ฐ€ ๋ช‡๋ฐฑ ์ค„๋ฐ–์— ์—†์—ˆ๋Š”๋ฐ,
์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งŽ์•„์ง€๊ณ  ๊ธฐ๋Šฅ์ด ๋Š˜์–ด๋‚˜๋ฉด ์–ด๋А ์ˆœ๊ฐ„ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ๊ฐ€ ์ปค์ง€๊ณ  ๋กœ๋”ฉ์ด ๋А๋ ค์ง„๋‹ค.
์ด๋Ÿด ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋ฐ”๋กœ ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…(Code Splitting)๊ณผ Lazy Loading์ด๋‹ค.

์ด๋ฒˆ ๊ธ€์€ ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์ด ์™œ ํ•„์š”ํ•œ์ง€, React์—์„œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”์ง€,
๊ทธ๋ฆฌ๊ณ  ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ์–ผ๋งˆ๋‚˜ ์˜ํ–ฅ์„ ์ฃผ๋Š”์ง€๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์ •๋ฆฌํ–ˆ๋‹ค.


โœ… ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์ด๋ž€?

์•ฑ์„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ž‘์€ ๋ฒˆ๋“ค๋กœ ๋‚˜๋ˆ„๋Š” ๊ฒƒ
์‚ฌ์šฉ์ž๊ฐ€ ํ•„์š”ํ•œ ์‹œ์ ์— ํ•„์š”ํ•œ ์ฝ”๋“œ๋งŒ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

์˜ˆ์ „์—๋Š” ํ•˜๋‚˜์˜ JS ํŒŒ์ผ๋กœ ๋ชจ๋“  ์•ฑ์„ ๋ฌถ์—ˆ์ง€๋งŒ,
์š”์ฆ˜์€ ํŽ˜์ด์ง€ ๋‹จ์œ„, ๋ผ์šฐํŠธ ๋‹จ์œ„, ์ปดํฌ๋„ŒํŠธ ๋‹จ์œ„๋กœ ๋‚˜๋ˆ ์„œ ๋กœ๋”ฉํ•œ๋‹ค.


๐Ÿข Lazy Loading๊ณผ์˜ ๊ด€๊ณ„

์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์ด ์ด๋ฃจ์–ด์ง„ ์ฝ”๋“œ๋“ค์„ ํ•„์š”ํ•  ๋•Œ ๋น„๋™๊ธฐ๋กœ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ธฐ์ˆ ์ด Lazy Loading์ด๋‹ค.

์ฆ‰, ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ… = ๋‚˜๋ˆ ๋†“๊ธฐ,
Lazy Loading = ๋‚˜๋ˆ ๋†“์€ ๊ฑธ ์ƒํ™ฉ์— ๋”ฐ๋ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ


๐Ÿ”ง React์—์„œ์˜ ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ… ๋ฐฉ๋ฒ•

1๏ธโƒฃ React.lazy + Suspense

import React, { Suspense } from 'react';

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

function App() {
  return (
    <Suspense fallback={<div>๋กœ๋”ฉ ์ค‘...</div>}>
      <HeavyComponent />
    </Suspense>
  );
}
  • React.lazy()๋กœ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋น„๋™๊ธฐ๋กœ ๋ถˆ๋Ÿฌ์˜ด
  • <Suspense>๋กœ ๋กœ๋”ฉ ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•จ

2๏ธโƒฃ Next.js์˜ next/dynamic

import dynamic from 'next/dynamic';

const HeavyComponent = dynamic(() => import('./HeavyComponent'), {
  loading: () => <p>๋กœ๋”ฉ ์ค‘...</p>,
  ssr: false, // SSR ์‹œ์ ์— ๋กœ๋”ฉํ•˜์ง€ ์•Š๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ
});
  • SSR ์ง€์› ์—ฌ๋ถ€๊นŒ์ง€ ์ œ์–ด ๊ฐ€๋Šฅ
  • React.lazy๋ณด๋‹ค ์œ ์—ฐํ•˜๊ฒŒ ์„ค์ • ๊ฐ€๋Šฅ

๐Ÿ’ก ์‹ค์ „์—์„œ ์ž์ฃผ ์“ฐ๋Š” ์‹œ์ 

์ ์šฉ ์œ„์น˜์„ค๋ช…
Modal, Dialogํ‰์†Œ์—๋Š” ์•ˆ ์“ฐ๋‹ค๊ฐ€ ํ•„์š”ํ•  ๋•Œ๋งŒ ๋„์›€
Chart, Map์ดˆ๊ธฐ์— ๋ถˆ๋Ÿฌ์˜ฌ ํ•„์š” ์—†์Œ, ํด๋ฆญ ์‹œ ๋กœ๋”ฉ
๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€ ๋Œ€์‹œ๋ณด๋“œ๋ผ์šฐํŒ… ์ดํ›„์— ๋ถˆ๋Ÿฌ์˜ค๋ฉด ๋จ
3D ๋ Œ๋”๋ง, PDF ๋ทฐ์–ด ๋“ฑ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ ํฐ ๊ฒฝ์šฐ โ†’ ๋ถ„๋ฆฌ ํ•„์ˆ˜

๐Ÿ“ˆ ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ์–ผ๋งˆ๋‚˜ ํšจ๊ณผ๊ฐ€ ์žˆ๋‚˜?

โœ… ์ง์ ‘ ์ธก์ •ํ•œ ์˜ˆ์‹œ

  • Lazy ์ ์šฉ ์ „ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ: 1.2MB
  • Lazy ์ ์šฉ ํ›„ ์ดˆ๊ธฐ ๋ฒˆ๋“ค: 450KB
  • LCP (Largest Contentful Paint) ๊ฐœ์„ : 3.6s โ†’ 1.2s

โ†’ ๋ˆˆ์— ๋„๋Š” ์ดˆ๊ธฐ ๋กœ๋”ฉ ์†๋„ ํ–ฅ์ƒ
โ†’ ์‚ฌ์šฉ์ž ์ฒด๊ฐ ์„ฑ๋Šฅ ์ƒ์Šน


๐Ÿ› ๏ธ ์‹ค๋ฌด ์ ์šฉ ํŒ

  • React.lazy๋Š” client-side only
  • SSR์ด ํ•„์š”ํ•œ ํŽ˜์ด์ง€๋Š” next/dynamic ์‚ฌ์šฉ
  • fallback ์ปดํฌ๋„ŒํŠธ๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ์ขŒ์šฐํ•จ โ†’ ๋กœ๋”ฉ UI ๋””์ž์ธ ์ค‘์š”
  • ๋„ˆ๋ฌด ์ž์ž˜ํ•œ ์ปดํฌ๋„ŒํŠธ๊นŒ์ง€ ์Šคํ”Œ๋ฆฌํŒ…ํ•˜๋ฉด ์˜คํžˆ๋ ค ๋น„ํšจ์œจ์ ์ผ ์ˆ˜ ์žˆ์Œ

๐Ÿ“ ๋‚ด๊ฐ€ ๋А๋‚€ ์ 

์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…์€ ์ฒ˜์Œ์—” โ€œ๊ทธ๋ƒฅ ์ฝ”๋“œ ๋‚˜๋ˆ„๋Š” ๊ฑฐ์ง€ ๋ญโ€ ์ˆ˜์ค€์œผ๋กœ ๋ดค๋Š”๋ฐ,
์‹ค์ œ๋กœ ๋Œ€ํ˜• ํ”„๋กœ์ ํŠธ์—์„œ ์ดˆ๊ธฐ ๋กœ๋”ฉ ์†๋„ ์ฐจ์ด๊ฐ€ 3์ดˆ ์ด์ƒ ๋‚˜๋Š” ๊ฑธ ๋ณด๊ณ  ํ™• ์ฒด๊ฐํ–ˆ๋‹ค.
ํŠนํžˆ Next.js์—์„œ๋Š” ํŽ˜์ด์ง€ ๋‹จ์œ„๋กœ ์ž๋™ ์Šคํ”Œ๋ฆฌํŒ…๋„ ๋˜๋‹ˆ๊นŒ
๋” ์ ๊ทน์ ์œผ๋กœ dynamic()์„ ํ™œ์šฉํ•˜๊ฒŒ ๋๋‹ค.


๐Ÿš€ "์‚ฌ์šฉ์ž๋Š” ๋น ๋ฅด๊ฒŒ ๋ฐ˜์‘ํ•˜๋Š” ์•ฑ์„ ์›ํ•˜๊ณ ,
๊ทธ๊ฑด ์ฝ”๋“œ๋ฅผ ๋˜‘๋˜‘ํ•˜๊ฒŒ ๋‚˜๋ˆ„๋Š” ๋ฐ์„œ ์‹œ์ž‘๋œ๋‹ค."

profile
๊ฐœ๋ฐœ์ž๋กœ ์ทจ์—…์„ ์ค€๋น„ ์ค‘ ์ด๋ฉฐ, ์—ด์‹ฌํžˆ ๊ณต๋ถ€ ์ค‘ ์ž…๋‹ˆ๋‹ค!

0๊ฐœ์˜ ๋Œ“๊ธ€