๊ตฌ๊ธ์ ์กฐ์ฌ์ ์ํ๋ฉด ํ์ด์ง๊ฐ 3์ด ์์ ๋ก๋ฉ๋์ง ์๋๋ค๋ฉด 53% ์ฌ์ฉ์๊ฐ ๋ ๋๊ณ , ๋ก๋ฉ ์๊ฐ์ด ๊ธธ์ด์ง์๋ก ์ดํ๋ฅ ์ด ๋์ด๋๋ค๊ณ ํ๋ฉฐ ์ด๋ฅผ 3์ด ๋ฒ์น์ด๋ผ๊ณ ํ๋ค. ์ด๋ ๊ฒ ์ฒซ ์ธ์(?)์ด ์ค์ํ ๊ฒ ๊ฐ๋ค. ์นํ์ด์ง์ ์ฒซ ์ธ์์ด ์ข์ผ๋ ค๋ฉด ์ฑ๋ฅ์ ์ข๊ฒ ์ ์งํ๋ ์ ๋ฐ์ ๐ฅ
์น์ ์ฑ๋ฅ์ ์ต์ ํํ ์ ์๋ ๋ถ๋ถ์ ํฌ๊ฒ 2๊ฐ์ง๋ก ๋๋ ์ ์๋ค.
์ด๋ ๊ฒ ์ค๋ช ์ผ๋ก๋ง ๋ด์๋ ๋ก๋ฉ ์ฑ๋ฅ ์ต์ ํ๊ฐ ๋ฌด์์ธ์ง, ๋ ๋๋ง ์ฑ๋ฅ ์ต์ ํ๊ฐ ๋ฌด์์ธ์ง ์ ๊ฐ์ด ์ ์จ๋ค. ๊ฐ๊ฐ ์ต์ ํ๋ฅผ ํ๋ ๋ฐ์ ์ด๋ค ๋ฐฉ๋ฒ์ด ์๋์ง ์์๋ณด์๊ตฌ์ ~๐ก
๋ธ๋ผ์ฐ์ ๊ฐ ์๋จ๋ถํฐ ์ฐจ๋ก๋๋ก ๋ด๋ ค๊ฐ๋ฉฐ ๋ก๋๋๋ค. ๋ธ๋ผ์ฐ์ ๋ก๋ ์, HTML๊ณผ CSS์ด ๋์์ ํ์ฑ๋๋๋ฐ ์ด๋ Script ํ์ผ์ ๋ง๋๋ค๋ฉด HTML๊ณผ CSS ํ์ฑ์ ๋ฉ์ถ๊ณ , JS ํ์ฑ์ ์์ํ๋ค. ์ด์ฒ๋ผ HTML ํ์ฑ์ ์ฐจ๋จํ๋ ์์๋ฅผ Block Resource(๋ธ๋ก ์ฐจ๋จ ๋ฆฌ์์ค)๋ผ๊ณ ํ๋ค.
๊ทธ๋ฐ๋ฐ Block Resource๊ฐ ์ ๋ก๋ฉ ์ฑ๋ฅ๊ณผ ๊ด๋ จ ์์ฃ ? ๐ค
๊ทธ๋ฅ JS ํ์ฑ ํ๊ณ HTML ๋ค์ ํ์ฑํ๋ฉด ๋๋๊ฑฐ ์๋๊ฐ?
HTML๊ณผ CSS๋ ์ฐ๋ฆฌ๊ฐ ๋ณด๋ ์๊ฐ์ ์ธ ๋ถ๋ถ์ ๊ตฌํํ๊ธฐ ๋๋ฌธ์ ๋ธ๋ผ์ฐ์ ๋ก๋ ์, ๋น ๋ฅด๊ฒ ๊ทธ๋ ค์ง์๋ก ์ข๋ค. ๋ฐ๋ผ์ CSS๋ head ๋ด์์ import ํ๋ค.
๋ธ๋ผ์ฐ์ ๋ HTML, CSS๋ฅผ ํ์ฑํ๊ณ ์์ด๋ Script ํ๊ทธ๋ฅผ ๋ง๋๋ฉด ํ์ฑ์ ์ค์งํ๊ธฐ ๋๋ฌธ์, HTML๊ณผ CSS์ ๋ก๋๊ฐ ๋๋๊ณ Script๊ฐ ๋ค์ด์ค๋ ๊ตฌ์กฐ๋ก ํ๋๊ฒ ์ข๋ค. ๋ฐ๋ผ์ Script ํ๊ทธ๋ก ์คํ๋๋ JS๋ ์ผ๋ฐ์ ์ผ๋ก body ํ๊ทธ๋ฅผ ๋ซ๊ธฐ ์ ๋งจ ํ๋จ์ ์์น์ํจ๋ค.
media attribute์ ๋จ๋ง๊ธฐ ์ ํ์ ๋ฐ๋ผ ์กฐ๊ฑด๋ณ๋ก CSS ๋ถ๋ฌ์์, ๋ถํ์ํ ๋ธ๋กํน์ ๋ฐฉ์งํ ์ ์๋ค.
<link href="style.css" rel="stylesheet" />
<link href="print.css" rel="stylesheet" media="print" />
<link href="mobile.css" rel="stylesheet" media="width:790px" />
async์ defer ์์ฑ์ Script ํ์ผ์ ๋น๋๊ธฐ๋ก ๋ค์ด๋ก๋ ํ๊ฒ ํด์ค๋ค. ์ฆ, HTML ํ์ฑ ์ค์ Script๋ฅผ ๋ง๋๋ ํ์ฑ์ ๋ฉ์ถ์ง ์๊ณ Script๋ฅผ ๋ค์ด๋ก๋ ํ ์ ์๋ค.
HTML ํ์ฑ๋์ Script๋ ๊ฐ์ด ๋ค์ด๋ก๋ ๋๋ค. Script๋ ๋ค์ด๋ก๋ ํ ์ฆ์ ์คํ๋๋ฉฐ, HTML์ ์คํ๋๋ ๋์ ์ค์ง๋์๋ค๊ฐ ์คํ์ด ๋๋๋ฉด ๋ค์ ํ์ฑ๋๋ค.
ํ์ง๋ง asynk Script๋ ๋ค์ด๋ก๋๋ฅผ ๋ง์น๋ฉด ์ฆ์ HTML ํ์ฑ์ ๋ฉ์ถ๊ณ Script ํ์ผ์ ํด์ํ๋ค. ๋๋ฌธ์ asynk ์์ฑ์ผ๋ก ํ์ผ์ ๋ถ๋ฌ์จ๋ค๊ณ ํด๋, ์คํฌ๋ฆฝํธ์ ํด์์ด ์ผ๋ง๋ ์ค๋ ๊ฑธ๋ฆด์ง ๋ชจ๋ฅธ๋ค. ๋ฐ๋ผ์ asynk ์คํฌ๋ฆฝํธ๋ ์คํ ์์๊ฐ ๋ณด์ฅ๋์ง ์๋๋ค.
<!-- large.js ๋ ๋ก๋๋๋๋ฐ 5์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค -->
<script src="large.js" async></script>
<!-- small.js ๋ ๋ก๋๋๋๋ฐ 1์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค -->
<script src="small.js" async></script>
์๋๋ ์์์ ๋ฐ๋ผ large.js๊ฐ ๋จผ์ ์คํ๋์ด์ผ ํ์ง๋ง, ๋จผ์ ๋ก๋ ๋๋ ์คํฌ๋ฆฝํธ์ธ small.js๊ฐ ์คํ๋๋ฏ๋ก ์คํฌ๋ฆฝํธ์ ์์๊ฐ ๋ณด์ฅ๋์ง ์๋๋ค !!!
HTML ํ์ฑ๋์ Script๋ ๊ฐ์ด ๋ค์ด๋ก๋ ๋๋ค. Script๋ ๋ค์ด๋ก๋ ํ ์ฆ์ ์คํ๋๋ asynk Script์๋ ๋ค๋ฅด๊ฒ, ๋ชจ๋ DOM์ด ๋ก๋๋ ํ์ ์คํ๋๋ค.
<!-- large.js ๋ ๋ก๋๋๋๋ฐ 5์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค -->
<script src="large.js" async></script>
<!-- small.js ๋ ๋ก๋๋๋๋ฐ 1์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค -->
<script src="small.js" async></script>
defer Script๋ ๋ก๋๊ฐ ๋ ๋นจ๋ฆฌ๋ Script๊ฐ ์๋๋ผ๋, ํญ์ ์์์ ๋ฐ๋ผ์ ์คํ๋๋ฏ๋ก ์์๊ฐ ๋ณด์ฅ๋๋ค.
picture ํ๊ทธ๋ img ํ๊ทธ์ ๋ํด ์ฌ๋ฌ๊ฐ์ ๋ฐ์ํ ์ด๋ฏธ์ง๋ฅผ ์ ๊ณตํ๋ source ํ๊ทธ๊ฐ ํฌํจ๋ ๋ถ๋ชจ ์์์ด๋ค. picture ํ๊ทธ๋ source ํ๊ทธ๋ฅผ ์ด์ฉํ ๋ฐ์ํ ์ด๋ฏธ์ง๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋์ญํญ์ ์ ์ฝํ๊ณ ํ์ด์ง ๋ก๋ ์๊ฐ ๋จ์ถ์ ์ํด ์ฐ์ธ๋ค.
<picture>
<source srcset="small.jpg" media="(max-width: 768px)">
<source srcset="large.jpg" media="(min-width: 769px)">
<img src="fallback-image.jpg" alt="image">
</picture>
source ํ๊ทธ ๋๋ img ํ๊ทธ ๋ ์ค ํ๋๋ ์์ด์ผ ํ๋ค.
source ํ๊ทธ, img ํ๊ทธ ๋ ๋ค ์์ ๊ฒฝ์ฐ, img ํ๊ทธ๊ฐ ๋์ค์ ์์นํด์ผ ํ๋ค. => source ํ๊ทธ ์ค ์ด๋ ๊ฒ๋ ๋ฐ์ํ์ผ๋ก ์ ๊ณตํ ์ ์๋ ๊ฒฝ์ฐ img ํ๊ทธ์ ์ด๋ฏธ์ง ์ ๊ณต!
img ํ๊ทธ๋ฅผ ์ญ์ ํ ๊ฒฝ์ฐ, alt ์์ฑ์ด ์์ผ๋ฏ๋ก ์น ์ ๊ทผ์ฑ์ด ๋จ์ด์ง๋ฉฐ source ํ๊ทธ ์ค ์ ๊ณตํ ์ด๋ฏธ์ง๊ฐ ์๋ค๋ฉด fallback ์ด๋ฏธ์ง๋ก ์ฌ์ฉํ ์ ์๋ค.
์ผํ๋ชฐ ์น ํ์ด์ง์ฒ๋ผ ์ด๋ฏธ์ง๊ฐ ๋ง์ด ํ์ํ ์๋น์ค์์ ์ฌ์ฉ์ ์ฒซ ํ๋ฉด์ ๋ณด์ด๋ ์ด๋ฏธ์ง๋ง ์์ฒญํ๊ณ , ์ฌ์ฉ์๊ฐ ์คํฌ๋กค์ ํตํด ๋ด๋ ค์ผ ๋ณด์ด๋ ์ด๋ฏธ์ง๋ ์ง์ฐ ๋ก๋ฉ์ ํตํด ๋ฆฌ์์ค ์์ฒญ์ ์ค์ผ ์ ์๋ค.
<!-- auto๋ default ๊ฐ์ผ๋ก, loading ์์ฑ์ ์ ์ด ๊ฒ๊ณผ ๊ฐ์ -->
<img src="image.jpg" loading="auto" alt>
<!-- lazy๋ ์ฌ์ฉ์๊ฐ ๋ณด์ด๋ ๋ถ๋ถ๋ง ๋จผ์ ์ถ๋ ฅํ๊ณ , ๋ณด์ด์ง ์๋ ๋ถ๋ถ์ ์ฌ์ฉ์๊ฐ ์คํฌ๋กค ์ ์ถ๋ ฅ๋จ -->
<img src="image.jpg" loading="lazy" alt>
<!-- eager์ ๋ณด์ด๋ , ์ ๋ณด์ด๋ ์ด๋ฏธ์ง๋ฅผ ๋ก๋ํ๋ค.-->
<img src="image.jpg" loading="eager" alt>
์คํ๋ผ์ดํธ ์ด๋ฏธ์ง๋, ์ฌ๋ฌ๊ฐ์ ์ด๋ฏธ์ง๋ฅผ ํ๋์ ์ด๋ฏธ์ง๋ก ํฉ์ณ ๊ด๋ฆฌํ๋ ์ด๋ฏธ์ง์ด๋ค. ์ด๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฏธ์ง๋ฅผ ๋ค์ด๋ฐ๊ธฐ ์ํ ์๋ฒ ์์ฒญ์ ์ค์ผ ์ ์๊ธฐ ๋๋ฌธ์ ์น ํ์ด์ง์ ๋ก๋ฉ ์๊ฐ์ ์ค์ผ ์ ์๋ค.
์ด๋ฏธ์ง ํ์์ webp์ผ๋ก ๋ณํํ๋ฉด .jpg, .png๋ณด๋ค ํ์ผ์ ํฌ๊ธฐ๋ฅผ ์ต์ 25~30% ์ค์ผ ์ ์์ผ๋ฉฐ, ์์ถ์๋ ์ฉ์ดํ๋ค. ๋ฐ๋ผ์ ๊ธฐ์กด ์ด๋ฏธ์ง ํ์์ ๋นํด ๋ก๋ ์๋๊ฐ ๋ ๋น ๋ฅด๋ค.
๋ชจ๋ ๋ฒ๋ค๋ฌ ์นํฉ(Webpack)์ ์ฌ์ฉํด์ css์ js ๋ชจ๋์ ํ๋์ ํ์ผ๋ก ๋ณํฉํ๋ ๋ชจ๋ ๋ฒ๋ค๋ง์ ํตํด ๋ฆฌ์์ค ์์ฒญ์ ์ค์ผ ์ ์๋ค.
๐ Before- ๋ฒ๋ค๋ง ์
<head>
<link href="main.css" rel="stylesheet">
<link href="sub.css" rel="stylesheet">
</head>
<body>
...
<script async src="main.js" type="text/javascript"></script>
<script async src="sub.js" type="text/javascript"></script>
</body>
๐ After- ๋ฒ๋ค๋ง ํ
<head>
<link href="budle.css" rel="stylesheet">
</head>
<body>
...
<script async src="bundle.js" type="text/javascript"></script>
</body>
HTML ์์์ style์ ์์ฑํ๋ฉด Reflow๋ฅผ ๊ณ์ ๋ฐ์์์ผ ๋ ๋๋ง ์๋ฃ ์์ ์ ๋ฆ์ถ๋ค.
<div style="margin: 10px;"></div>
DOM ํธ๋ฆฌ๋ ๊ฐ๋ฒผ์์ผ ๊ณ์ฐ์ด ๋น ๋ฅด๋ค. ๋ถํ์ํ div, wrap๋ ์ญ์ ํด์ค์ผ ํ๋ค.
๐ Reflow
๋ ๋๋ง ์์ง์ ์ํด์ ๋ธ๋ผ์ฐ์ ๊ฐ ๊ทธ๋ ค์ง ๋, Layout(reflow) ๋จ๊ณ๊ฐ ์๋ค. ์ด ๋จ๊ณ์์ ๋ธ๋ผ์ฐ์ ๋ ํ๋ฉด ์ ์ฒด์ ํฌ๊ธฐ๋ ์คํฌ๋กค ์์น ๋ฑ์ ์์๋ฅผ ๊ณ ๋ คํ๋ค.
๋ฐ๋ผ์ ํ๋ฉด์ ๋๋น, ๋์ด, ์์น ๋ฑ์ ์ํฅ์ ์ฃผ๋ CSS ์์ฑ์ ๋ณ๊ฒฝํ๋ ๊ฒฝ์ฐ, Layout ๋จ๊ณ๋ถํฐ ๋ค์ ๊ทธ๋ ค์ง๊ฒ ๋๋ค. ์ด ๋จ๊ณ๋ฅผ Refolw๋ผ๊ณ ํ๋ค.
position, width, height, margin, padding , display , top, left, right, bottom, box-sizing, border-color, text-align, border, border-width, font-family, float, font-size, font-weight, line-height, vertical-align ...
๐ Repaint
Paint ๋จ๊ณ๋ Layout ๋จ๊ณ๋ฅผ ํตํด ํ๋ฉด์ ๋ฐฐ์น๋ ์์๋ค์๊ฒ ์์ ์
ํ๋ ๋จ๊ณ์ด๋ค. ๋ ์ด์์์ ์ํฅ์ ์ฃผ์ง ์๋ ์์ฑ์ ๋ณ๊ฒฝํ๋ฉด Layout ๋จ๊ณ๋ฅผ ์คํตํ๊ณ Paint ๋จ๊ณ๋ถํฐ ๋ค์ ์ํํ๊ฒ ๋๋ค. ์ด ๋จ๊ณ๋ฅผ Repaint๋ผ๊ณ ํ๋ค.
๋ฐ๋ผ์ Reflow๊ฐ ์ผ์ด๋๋ฉด ๋ธ๋ผ์ฐ์ ๊ฐ ์ ์ฒด ํฝ์ ์ ๋ค์ ๊ณ์ฐํด์ผ ํ๊ธฐ ๋๋ฌธ์ Repaint ์์ฑ์ ์ฌ์ฉํ์ฌ ์คํ์ผ์ ์์ฑํ๋ฉด ์ฑ๋ฅ์ ๋์ผ ์ ์๋ค.
color, border-style, visibility, background, background-color, background-image, background-position , background-repeat, background-size, text-decoration, outline, outline-style, outline-color, outline-width, border-radius, box-shadow ...
๋ถํ์ํ CSS๋ ํฌ๋กฌ lightHouse๋ฅผ ํตํด ํ์ธํ ์ ์๋ค.
์ ํ์๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ํ์!
CSS๊ฐ ๋ณต์กํ ์๋ก Layout์ ๊ทธ๋ฆฌ๋ ๋ฐ์ ๋ง์ ์๊ฐ์ด ์์๋๋ค.
<!-- โ ์ ์ข์ ์-->
.parent .parent_child{
...
}
<!-- โญ ์ข์ ์-->
.parent_child{
...
}
์ ๋๋ฉ์ด์ ์ ์ฌ๋ฌ์ฅ์ ์ด๋ฏธ์ง๋ฅผ ์ฐ์์ ์ผ๋ก ๋ณด์ฌ์ค์ ์์ง์ด๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๊ฒ ํ๋ ๊ฒ์ด๋ค. ๊ทธ๋ ๋ค๋ฉด ์ ๋๋ฉ์ด์ ์ ์ฑ๋ฅ์ด ๋จ์ด์ง๋ค๋ ๊ฒ์ ๋ญ๊น? ๋ฐ๋ก ์ ๋๋ฉ์ด์ ์ด ๋ถ๋๋ฝ๊ฒ ๋ค์์ฅ์ผ๋ก ์ด์ด์ง๋ ๊ฒ์ด ์๋ ๋๋ ๋๊ฒจ ๋ณด์ด๋ '์ํฌ ํ์'์ด ๋ํ๋ ๋ ์ฑ๋ฅ์ด ๋จ์ด์ง๋ค๋ ์๋ฏธ์ด๋ค.
๊ทธ๋ผ ์ ๋๋ฉ์ด์ ์ ์ฑ๋ฅ์ ์ด๋ป๊ฒ ๊ฐ์ ํ๋์ฉ? ๐ค
- CSS ์์ฑ ์ค์๋ GPU์ ๋์์ ๋ฐ์ ์ ์๋ ์์ฑ์ด ์๋๋ฐ, ๊ทธ ์ค ๋ํ์ ์ธ ์์ฑ์ transform๊ณผ opacity๊ฐ ์๋ค. transform์ Reflow์ Repaint๋ฅผ ๋ฐ์์ํค์ง ์๊ธฐ ๋๋ฌธ์ ๋ ๋๋ง ์๋๋ฅผ ํฅ์์ํฌ ์ ์๋ค. (GPU๋ ์ปดํจํฐ ๊ทธ๋ํฝ ์ฒ๋ฆฌ ์ฅ์น์ด๋ค!)
๋ฐ๋์ ์์ด์ผ ํ ์ฝ๋๊ฐ ์๋๋ผ๋ฉด ์ ๊ฑฐํ๊ณ , ํจ์๊ฐ ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ์ป๊ธฐ๊น์ง ํ์ํ ๋จ๊ณ๊ฐ ์๋๋ผ๋ฉด ๋จ์ํํด์ผ ํ๋ค.
๋ง์ฝ, ์ฝ๋๋ฅผ ์ค์ผ ์ ์๋ค๋ฉด ๋ ์คํํ ์ ์๋์ง ํ์ธํ๋ค. ์๋ฅผ๋ค๋ฉด ๋ฐ๋ณต๋ฌธ์์ ๋๊น์ง ๊ฐ์ ์ป์ง ์์๋ ๋๋ค๋ฉด, break๋ฅผ ํตํด ๋น ์ ธ๋์์ผ ํ๋ค.
JS์ ๋ณ์๋ ๋คํ์ฑ์ ๊ฐ๋๋ค. ๋ฐ๋ณตํด์ ์ฌ์ฉํด์ผ ํ๋ ์ซ์๊ฐ ์๋๋ผ๋ฉด ๊ตณ์ด ๋ณ์๋ก ์ ์ธํด์ ์ฐ์ง ์๋ ๊ฒ์ด ์ข๋ค.
const x=2, y=4;
mutifly(x,y);
// 1% ๋ ๋น ๋ฆ
mutifly(2,4);
๋๋ถ๋ถ์ ๋ฆฌ์กํธ ํ์ผ์ Webpack ๋ฑ์ ์ฌ์ฉํด์ ํ์ผ์ ๋ฒ๋ค๋งํ์ฌ ํ๋๋ก ๋ฌถ๋๋ค. ๋ค๋ง, ์ด ํฌ๊ธฐ๊ฐ ์ปค์ง๋ฉด ์ฑ๋ฅ์ ์
์ํฅ์ ๋ผ์น๊ฒ ๋๋ค. ์ด๋ Code Splitting์ ์ฌ์ฉํ๋ค. ๋ฒ๋ค ํ์ผ์ ์ฝ๋๋ฅผ ๋ถํ ํ์ฌ ๋ชจ๋ ์ฝ๋๋ฅผ ํ ๋ฒ์ ๋ถ๋ฌ์ค์ง ์๊ณ ์ฌ์ฉ์๊ฐ ํ์๋ก ํ ๋์ ํ์ํ ์ฝ๋๋ง ๋ถ๋ฌ์ค๋ ๊ฐ๋
์ด๋ค.
(+) Code Splitting์ SPA์ ์ฑ๋ฅ์ ํฅ์์ํค๋ ๋ฐฉ๋ฒ์ด๋ค. SPA๋ ์ด๊ธฐ ์คํ ์ ๋ก๋ฉ ์๋๊ฐ ์ง์ฐ๋ ์ ์๋ค. ์ด๋ Code Splitting์ ์ฌ์ฉํ๋ฉด ์๋ ๊ฐ์ ๊ณผ SEO์ ๋์์ด ๋๋ค.
Code Splitting์ ์ด๋ป๊ฒ ์ฐ๋์ง์? ๐ค
1. dynamic import() ๊ตฌ๋ฌธ ์ฌ์ฉ
Code Splitting์ ๋์ ํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ import() ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๐ Before- ์ ์ ๋ถ๋ฌ์ค๊ธฐ (static import)
import { add } from './math';
console.log(add(16, 26));
๐ After- ๋์ ๋ถ๋ฌ์ค๊ธฐ (dynamic import)
import('./math').then((math)=> {
console.log(add(16, 26));
}
dynamic import ๊ตฌ๋ฌธ์ ํจ์๋ฅผ ํธ์ถํ๋ ๋ฌธ๋ฒ ํํ์ด์ง๋ง, import๋ ํจ์๊ฐ ์๋๋ค !! ๋ํ static import๋ ๋งจ ์๋จ์ ์์นํด์ผ ํ์ง๋ง, dynamic import๋ ์ฝ๋์ ์์น์ ์๊ด ์์ด ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค.
2. React.lazy ์ฌ์ฉ
React์์ ์ปดํฌ๋ํธ ํ์ผ์ ์ ์ํ๊ณ dynamic import๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
์ด๋ฐ ์ํฉ์์ ์ปดํฌ๋ํธ๋ฅผ ๋์ ์ผ๋ก ๋ถ๋ฌ์ค๊ธฐ ์ํด์ React.lazy๋ฅผ ์ฌ์ฉํ๋ค.
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
React.laz๋ import() ๊ตฌ๋ฌธ์ ๋ฐํํ๋ ์ฝ๋ฐฑํจ์๋ฅผ ์ธ์๋ก ๋ฐ๋๋ค. ๋์ ๋ถ๋ฌ์ค๊ธฐ๋ก ๋ถ๋ฌ์์ง๋ ๋ชจ๋์ 1. ReactComponent๋ฅผ ํฌํจํ๋ฉฐ 2. default export๋ฅผ ๊ฐ์ง ๋ชจ๋์ด์ด์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ ๋ถ๋ฌ์จ ์ปดํฌ๋ํธ๋ฅผ ๋ฐํํ๋ค.
React.lazy๋ก ๋ถ๋ฌ์จ ์ปดํฌ๋ํธ๋ ๋จ๋ ์ผ๋ก ์ฐ์ผ ์ ์๊ณ , React.Suspense ์ปดํฌ๋ํธ๋ก ํ์์์ ๋ ๋๋ง๋์ด์ผ ํ๋ค. ๊ทธ๋ฆฌ๊ณ Suspense๋ lazy ์ปดํฌ๋ํธ๊ฐ ๋ก๋๋๋ ๋์ Loding ... ์ด๋ผ๋ ํ๋ฉด์ ๋ณด์ฌ์ค๋ค.(๊ทธ๋์ ์ง์ฐ๋ก๋ฉ์ด๋ผ ๋ถ๋ฅด๋ ๊ฒ ...!! ๐ฒ) ์ด๋ fallback prop๋ ํ์์ด๋ค !!
Code Splitting์ ์ด๋์ ์ฐ๋์ง์? ๐ค
React ๊ณต์๋ฌธ์์ ์ฝ๋ ๋ถํ ํญ๋ชฉ์ ์ํ๋ฉด, Router ๋ฐ๋ก ์๋์ Suspense๋ฅผ ์์น์ํค๊ณ , Route๋ก ๋ณด์ฌ์ค ์ปดํฌ๋ํธ๋ค์ React.lazy๋ก ๋ถ๋ฌ์ฌ ๊ฒ์ ๊ถ์ฅํ๊ณ ์๋ค.
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Suspense>
</Router>
);