32์ผ์ฐจ๋ถํฐ 34์ผ์ฐจ๋ ์ฑ๋ฅ์ต์ ํ
์ ๋ํด์ ๊ณต๋ถํ ์์ ์ด๋ค.
์ฝ๋์ ์์ ์ฑ, ํ์ฅ์ฑ(์ปดํฌ๋ํธ ๋ง๋ค์ด์ ๊ฐ์ ธ๋ค ์ฐ๋ ๊ฒ), ์ฑ๋ฅ, ์ ์ง๋ณด์์ฑ๊น์ง ๊ณ ๋ คํด์ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฅ๋ ฅ์ด ๊ฐ๋ฐ์๋ก์ ํ์ํ ๋ฅ๋ ฅ์ด๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ต์ ํ
๋ ์ค์ํ ํํธ๋ผ๊ณ ํ ์ ์๋ค.
๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ด ๋ง์์ง์๋ก ์ฑ๋ฅ์ ์ ํ๋๋ค. ๋ฐ๋ผ์ ๋ฆฌ๋ ๋๋ง์ ์ค์ฌ์ค ํ์๊ฐ ์๋ค.
const containerPage = ()=>{
console.log("์ปจํ
์ด๋๊ฐ ๋ ๋๋ง ๋ฉ๋๋ค.")
let countLet = 0
const [countState,setCountState] = useState(0)
const onClickCountLet = ()=>{
console.log(countLet+1)
countLet += 1
}
const onClickCountState = ()=>{
console.log(countState+1)
setCountState(countState+1)
}
return(
<div>
<div>================<div>
<h1>์ด๊ฒ์ ์ปจํ
์ด๋ ์
๋๋ค.</h1>
<div> ์นด์ดํธ(let): {countLet} </div>
<button onClick={onClickCountLet}> ์นด์ดํธ(let) +1 ์ฌ๋ฆฌ๊ธฐ! </button>
<div> ์นด์ดํธ(state): {countLet} </div>
<button onClick={onClickCountState}> ์นด์ดํธ(state) +1 ์ฌ๋ฆฌ๊ธฐ! </button>
<div>================<div>
</div>
)
}
export default containerPage
์์ ์ฝ๋๋ฅผ ์คํ์์ผ์ let
๋ฒํผ์ ๋๋ฅด๋ฉด ์ฝ์ ๊ฐ์ ์ฌ๋ผ๊ฐ์ง๋ง ๋ฆฌ๋ ๋๋ ์ผ์ด๋์ง ์์ "์ปจํ
์ด๋๊ฐ ๋ ๋๋ง ๋ฉ๋๋ค."๋ผ๋ ์ฝ์์ด ์ฐํ์ง ์๊ณ ์์ผ๋ฉฐ, ํ๋ฉด์๋ ๊ณ์ 0์ด ๋ํ๋๋ค. ํ์ง๋ง state
๋ฒํผ์ ๋๋ฅด๋ฉด ๋ฆฌ๋ ๋๋ง์ด ์ผ์ด๋๊ณ ์ซ์๊ฐ ์ฌ๋ผ๊ฐ๋ countLet์ด 0์ผ๋ก ์ด๊ธฐํ๋๋ค. ์ฆ, useState
๋ฅผ ์ ์ธํ ๋ชจ๋ ๊ฐ์ด ๋ค์ ๊ทธ๋ ค์ง๋ค.
๋ค์์ผ๋ก ์๋ ํ์ผ์ ๋ง๋ค์ด์ ์ ํ์ด์ง์ import๋ฅผ ํด๋ณด์.
// ์์ ํ์ผ
const MemoizationPresenterPage = ()=>{
console.log("ํ๋ฆฌ์ ํฐ๊ฐ ๋ ๋๋ง ๋ฉ๋๋ค.")
return(
<div>
<div>================<div>
<h1>์ด๊ฒ์ ํ๋ฆฌ์ ํฐ ์
๋๋ค.</h1>
<div>================<div>
</div>
)
}
export default MemoizationPresenterPage
// ๋ถ๋ชจ ํ์ผ
return(
// ์๋ต
<div>================<div>
<MemoizationPresenterPage/>
</div>
)
}
export default containerPage
์ด์ ์๋ก๊ณ ์นจ์ ํ๋ฉด ์ฝ์์ โ์ปจํ ์ด๋๊ฐ ๋ ๋๋ง ๋ฉ๋๋ค.โ ์ โํ๋ฆฌ์ ํฐ๊ฐ ๋ ๋๋ง ๋ฉ๋๋ค.โ ๊ฐ ์ฐํ๋ค.
๊ทธ๋ฐ๋ฐ ๋ถ๋ชจ์ state๋ฅผ ๋ฐ๊พธ๋ฉด ์์ ํ์ผ์์๋ ๋ฆฌ๋ ๋๋ง์ด ์ผ์ด๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ๊ต์ฅํ ๋นํจ์จ์ ์ด๋ค. ์ด ๋ถ๋ถ์ ์ต์ ํ ํ๊ธฐ ์ํด์ react developer tools๋ฅผ ์ค์นํด์ ์ดํด๋ณด์.
react developer tools ์ค์น ํ ๊ฐ๋ฐ์ ๋๊ตฌ์ profiler ํญ ํ์ฉํ๊ธฐ
profiler์์ ๋นจ๊ฐ์์ผ๋ก ๋ฐ์ค ์น ์ค์ ์ ๋ ๋๋ง๋ ๋์์ผ ๋ ์์ญ์ ํ์ํด์ฃผ๋ ์ค์ ์ด๋ค. ์ฒดํฌ๋ฅผ ํ ํ์ state
์นด์ดํธ ๋ฒํผ์ ๋๋ฅด๋ฉด ๋ถ๋ชจ์ ์์ ์์ญ์ด ๋์์ ๋ ๋๋ง ๋์์์ ๋ณผ ์ ์๋ค. ๋ฐ๋ฉด let
์นด์ดํธ ๋ฒํผ์ ๋๋ฅด๋ฉด ์๋ฌด์ผ๋ ์ผ์ด๋์ง ์๋๋ค. ์ฆ, ๋ฒํผ์ ๋๋ฌ๋ ๋ ๋๋ง์ด ์ผ์ด๋์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
๋ถํ์ํ ๊ฐ๋ค์ด ์ง์์ ์ผ๋ก ๋ค์ ๋ง๋ค์ด์ง๋ ์๋๋ก ์ ์ง์์ผ์ฃผ๋ hooks๊ฐ ์๋ค! ๋ฐ๋ก useMemo()
์ useCallback()
์ด๋ค. ๋ ๊ฐ์ง๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ๋ค.
import { useCallback, useMemo, useState } from "react";
// useCallback, useMemo๋ react์์ importํด์ค์ผ ํจ
import MemoizationWithChildPage from "./02-child";
export default function MemoizationPage(): JSX.Element {
console.log("์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง ๋์์ต๋๋ค.");
let countLet = 0;
const [countState, setCountState] = useState(0);
// 1. useMemo๋ก ๋ณ์ ๊ธฐ์ต
const aaa = useMemo(() => Math.random(), []);
console.log(aaa);
// 2. useCallback์ผ๋ก ํจ์ ๊ธฐ์ต
const onClickCountLet = useCallback((): void => {
console.log(countLet + 1);
countLet += 1;
}, []);
// 3. useCallback์ผ๋ก ํจ์ ๊ธฐ์ต => state ์ฌ์ฉ ์ฃผ์
const onClickCountState = useCallback((): void => {
// console.log(countState + 1);
setCountState((prev) => prev + 1);
}, []);
return (
<>
<div>=========================</div>
<h1>์ ๋ ๋ถ๋ชจ ์ปดํฌ๋ํธ ์
๋๋ค!!!</h1>
<div>์นด์ดํธ(let): {countLet}</div>
<button onClick={onClickCountLet}>์นด์ดํธ(let) +1 ์ฌ๋ฆฌ๊ธฐ</button>
<div>์นด์ดํธ(state): {countState}</div>
<button onClick={onClickCountState}>์นด์ดํธ(state) +1 ์ฌ๋ฆฌ๊ธฐ</button>
<div>=========================</div>
{/* memo์์๋ props๊ฐ ์์กด์ฑ๋ฐฐ์ด ์ญํ ์ ํจ */}
<MemoizationWithChildPage qqq={countState} />
</>
);
}
useCallback
์ผ๋ก ํจ์๋ฅผ ๊ฐ์ธ๋ฉด ํด๋น ํจ์๋ฅผ ๋ค์ ๋ถ๋ฌ์ค์ง ์๊ณ , ์ด์ ์ ๋ถ๋ฌ์๋ ํจ์๋ฅผ ์คํ์ํค๊ฒ ๋๋ค. state๊ฐ ์๋ ํจ์๋ useCallback์ผ๋ก ๊ฐ์๋๋ ์นด์ดํธ ๋ฒํผ์ ํด๋ฆญํด๋ ์นด์ดํธ๊ฐ ๊ณ ์ ๋๋ค.
์ฌ๊ธฐ์ ํจ์๋ ๋ค์ ๋ถ๋ฌ์ค์ง ์์ง๋ง ๊ฐ์ ์ฌ๋ ค์ฃผ๊ณ ์ถ์ ๋, prev
๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค!
์ฐธ๊ณ ! useCallback์ ์ฐ์ง ๋ง์์ผ ํ ๋
์์กด์ฑ ๋ฐฐ์ด์ ์ธ์๊ฐ 1~2๊ฐ๋ณด๋ค ๋ง์์ง ๋๋ ์ฐจ๋ผ๋ฆฌ ๋ฆฌ๋ ๋๋ฅผ ํ๋๊ฒ์ด ์ ์ง ๋ณด์์๋ ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ค. ์ฑ๋ฅ์ด ์กฐ๊ธ์ด๋๋ง ์ข์์ง๋ ๊ฒ๋ณด๋ค๋ ์ ์ง๋ณด์๊ฐ ํธ๋ฆฌํ ํธ์ด ํจ์ฌ ์ข๋ค. ๋ฐ๋ผ์ ์์กด์ฑ ๋ฐฐ์ด์ ์ธ์๊ฐ 2๊ฐ๋ฅผ ์ด๊ณผํ ๋๋ ๊ทธ๋ฅ ๋ฆฌ๋ ๋๋ฅผ ํด์ฃผ๋๊ฒ ์ข๋ค!
memo๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํ ์ ์๋ค.
import {memo} from "react" // memo๋ react์์ import
const MemoizationPresenterPage = ()=>{
console.log("ํ๋ฆฌ์ ํฐ๊ฐ ๋ ๋๋ง ๋ฉ๋๋ค.")
return(
<div>
<div>================<div>
<h1>์ด๊ฒ์ ํ๋ฆฌ์ ํฐ ์
๋๋ค.</h1>
<div>================<div>
</div>
)
}
export default memo(MemoizationPresenterPage)
์ด์ state ์นด์ดํธ๋ฅผ ํด๋ฆญํ๋ฉด ํ๋ฆฌ์ ํฐ๋ ๋ ๋๋ง์ด ๋์ง ์์์ ์ฝ์์ ์ฐํ์ง ์๋๋ค.
map๊ณผ memo๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋จ๊น? ์๋๋ ์ฐจ๋ก๋๋ก ๋ถ๋ชจํ์ผ๊ณผ ์์ํ์ผ์ด ์๋ค. Word๋ผ๋ ์์ํ์ผ์ memo๋ฅผ ํ๋ค.
// ๋ถ๋ชจํ์ผ
import { useState } from "react"
import Word from "./02-child"
export default function MemoizationParentPage(){
const [data,setData] = useState("์ฒ ์๋ ์ค๋ ์ ์ฌ์ ๋ง์๊ฒ ๋จน์์ต๋๋ค.")
const onClickChange = ()=>{
setData("์ํฌ๋ ์ค๋ ์ ๋
์ ๋ง์๊ฒ ๋จน์์ต๋๋ค.")
}
return(
<>
{data.split("").map((el)=>(
<Word key={index} el={el}/>
))}
<button>์ฒด์ธ์ง</button>
</>
)
}
// ์์ํ์ผ
import { memo } from "react"
export default function Word(props: any){
console.log("์์์ด ๋ ๋๋ง ๋ฉ๋๋ค!",props.el)
return <span>{props.el}</span>
}
export default memo(Word)
๋ถ๋ชจํ์ผ๋ก ์ ์ํด์ ์ฒด์ธ์ง ๋ฒํผ์ ๋๋ฅด๋ฉด, data ๊ฐ๊ณผ setData ๊ฐ์์ ๋ค๋ฅธ ๊ฐ๋ง ์ฝ์์ ์ฐํ๋ ๊ฒ์ ์ ์ ์๋ค. "์ํฌ๋"
, "์ ๋
์"
, "๋ง์๊ฒ"
๋ง ์ฐํ๋ค.
๋ง์ฝ, key๊ฐ์ uuid
๋ก ์ค์ ํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
import { useState } from "react"
import Word from "./02-child"
import {v4 as uuidv4} from "uuid"
export default function MemoizationParentPage(){
const [data,setData] = useState("์ฒ ์๋ ์ค๋ ์ ์ฌ์ ๋ง์๊ฒ ๋จน์์ต๋๋ค.")
const onClickChange = ()=>{
setData("์ํฌ๋ ์ค๋ ์ ๋
์ ๋ง์๊ฒ ๋จน์์ต๋๋ค.")
}
return(
<>
{data.split("").map((el)=>(
<Word key={uuidv4} el={el}/>
))}
<button>์ฒด์ธ์ง</button>
</>
)
}
uuid
๋ฅผ ์ฌ์ฉํ๋ฉด memo๋ฅผ ํด๋, key ์์ฒด๊ฐ ๋งค๋ฒ ๋ณ๊ฒฝ๋์ด props๋ก ๋์ด๊ฐ๊ธฐ ๋๋ฌธ์ setData ๋ฌธ์ฅ์ ๋ชจ๋ ๋จ์ด๊ฐ ๋ฆฌ๋ ๋๋ง๋๋ค. ๋ฐ๋ผ์ uuid๋ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ ์ด๋ํ๋ฏ๋ก ํ์ํ ์ํฉ์์๋ง ์ฃผ์ํด์ ์ฌ์ฉํด์ผ ํ๋ค.
๋ธ๋ผ์ฐ์ ์์ ๋ ๋๋ง์ ์ด๋ค ์์๋ก ์ผ์ด๋ ๊น?
๋จผ์ ํ๋ฉด์ ๊ทธ๋ ค์ฃผ๋๋ฐ ํ์ํ ๋ฆฌ์์ค(html, css, js)๋ฅผ ๋ค์ด๋ก๋ ํ๋ค. ๊ทธ๋ฆฌ๊ณ HTML๊ณผ CSS์์ ํ๋ฉด์ ๋ ๋ํด์ผ ํ ์์๋ค์ ๊ตฌ๋ถํ ํ ๋ ๋๋์ด์ผ ํ HTML,CSS ์์๋ฅผ ํฉ์ณ ํ๋ฉด์ ๊ทธ๋ ค์ฃผ๊ฒ ๋๋ค.
์ด์ด์ ํ๋ฉด์ ๊ทธ๋ ค์ค๋ ํด๋น ์์๋ค์ด ์ด๋ ์์น์ ๋์ผ์ง ๋จผ์ ๊ทธ๋ ค์ฃผ๋ Layout Reflow
์ ํด๋น ์์๋ค์ ์์น ํ๋ Paint Repaint
๊ณผ์ ์ด ๋ฐ์ํ๋ค.
์ฐธ๊ณ ! ๋ ๋ํธ๋ฆฌ
๋ ๋ํธ๋ฆฌ๋ ์ต์ข ์ ์ผ๋ก ๋ธ๋ผ์ฐ์ ์ ํ๊ธฐ๋ ์์๋ค์ด๋ค.
๋ ๋๋ง ์ ํ๋ฉด์ ๋ ๋ํด์ผ ํ๋ ์์๋ฅผ ๊ตฌ๋ถํ๋ ์์ ์ ํ๋ค๊ณ ํ๋๋ฐ, ์ด ๋ HTML์ ์์๋ฅผ ๊ตฌ๋ถํ ์ ์๋๋ก ๋์์ฃผ๋ ๊ฒ์ด DOM(Document Object Model), CSS์์๋ฅผ ๊ตฌ๋ถํ ์ ์๋๋ก ๋์์ฃผ๋ ๊ฒ์ด CSSOM(CSS Object Model)์ด๋ค.
์ด๋ ๊ฒ DOM๊ณผ CSSOM์ด ํฉ์ณ์ง๊ฒ์ด ๋ฐ๋ก ๋ ๋ํธ๋ฆฌ๋ค.
์ฆ 2๋ฒ๊ณผ์ ๊ณผ 3๋ฒ๊ณผ์ ์ด ํฉ์ณ์ง 4๋ฒ๊ณผ์ ์ ๊ฒฐ๊ณผ๋ฌผ์ด ๋ ๋ํธ๋ฆฌ๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
reflow๋ ๋ ๋๋ง๋์ด์ผ ํ ์์๋ค์ ํ๋ฉด ์ ์์น๋ฅผ ๊ทธ๋ ค์ฃผ๋ ๊ณผ์ ์ด๊ณ , repaint๋ ์์น๋ฅผ ์ก๊ณ ๋ ์ดํ ์์น ์ ํด์ฃผ๋ ๊ณผ์ ์ด๋ค. Reflow๊ฐ Repaint๋ณด๋ค ๋ ์ค๋ ๊ฑธ๋ฆฐ๋ค!
๊ฒ์๊ธ ๋ชฉ๋ก ์กฐํ ํ์ด์ง์ ์ ์ํ์ ๋, ๊ฒ์๊ธ ๋ชฉ๋ก์ด ์๊ณ , ํ์ด์ง๋ฅผ ์ด๋ํ๋ ๋ฒํธ๊ฐ ๋ชฉ๋ก ์๋์ ์์นํ๋ค๊ณ ํ์.
์ฒ์ ํ์ด์ง๋ฅผ ์ ์ํ์ ๋ ๋ชฉ๋ก์ ์กฐํํด์ค๋ฉด์ ๋ฐ์ดํฐ๊ฐ ๋น์ด์๋ค๊ฐ ๋์ค์ ๋ฐ์ดํฐ๊ฐ ๋ค์ด์จ๋ค. ๋ฐ์ดํฐ๊ฐ ๋น์ด์์ ๋์๋ ํ์ด์ง๋ฅผ ์ด๋ํ๋ ๋ฒํธ๊ฐ ์๋จ์ ์๋ค๊ฐ, ๋ฐ์ดํฐ๊ฐ ๊ทธ ์๋ฅผ ๋น์ง๊ณ ๋ค์ด์ค๋ฉด์ ํ์ด์ง ์ด๋ ๋ฒํธ๊ฐ ์๋์ชฝ์ผ๋ก ์ด๋ํ๊ณ ์ต์ข ํ๋ฉด์ด ๊ทธ๋ ค์ง๋ค.
์ด ๋ถ๋ถ์ด UI์์ผ๋ก ์์์ง ์๋ค. ๋ฐ๋ผ์ ๊ฒ์๊ธ ๋ชฉ๋ก์ ๋์ด๋ฅผ ๊ณ ์ ์์ผ์ฃผ๊ณ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋๋ก ํด๋ณด์.
// import ์๋ต
const FETCH_BOARDS = gql`
query fetchBoards($page: Int) {
fetchBoards(page: $page) {
_id
writer
title
contents
}
}
`;
export default function StaticRoutedPage() {
const { data, refetch } = useQuery<
Pick<IQuery, "fetchBoards">,
IQueryFetchBoardsArgs
>(FETCH_BOARDS);
console.log(data?.fetchBoards);
const onClickPage = (event: MouseEvent<HTMLSpanElement>) => {
void refetch({ page: Number(event.currentTarget.id) });
};
return (
<>
{/* ์์ ๋ฐฐ์ด 10๊ฐ๋ฅผ ์์ฑํ์ฌ, ๋ฐ์ดํฐ๊ฐ ์์ ๋๋ ๋์ด 30px์ ์ ์งํ์ฌ reflow ๋ฐฉ์ง */}
{(data?.fetchBoards ?? new Array(10).fill(1)).map((el) => (
<div key={el._id} style={{ height: "30px" }}>
<span style={{ margin: "10px" }}>{el.writer}</span>
<span style={{ margin: "10px" }}>{el.title}</span>
</div>
))}
{new Array(10).fill(1).map((_, index) => (
<span key={index + 1} id={String(index + 1)} onClick={onClickPage}>
{index + 1}
</span>
))}
</>
);
}
prefetch
๋ ๋ค์ ํ์ด์ง์์ ์ฐ๋ ค๊ณ ๋ฏธ๋ฆฌ ๋ฐ๋ ๊ฒ์ด๋ฉฐ, ํ์ฌ ํ์ด์ง๋ฅผ ๋ชจ๋ ๋ฐ์์จ ์ดํ ์ ์ผ ๋์ค์ ๋ค์ด๋ก๋ ํด์ค๊ฒ ๋๋ค. prefetch๋ฅผ ์ด์ฉํ๋ฉด ํ์ด์ง๊ฐ ์ด๋ํด๋ ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ฐ๋ก ๋ณด์ฌ์ฃผ๋ ๊ฒ์ด ๊ฐ๋ฅํ๋ค.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>ํ๋ฆฌํ์น</title>
<!-- ํ๋ฆฌํ์น: ๋ค์ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ ๋ค์ด๋ก๋ ๋ฐ์ผ๋ฏ๋ก, ๋ฒํผ ํด๋ฆญ์ ํ์ด์ง์ด๋ ๋น ๋ฆ -->
<link rel="prefetch" href="board.html" />
</head>
<body>
<a href="board.html">๊ฒ์ํ์ผ๋ก ์ด๋ํ๊ธฐ</a>
</body>
</html>
preload
๋ ํ์ฌ ํ์ด์ง์์ ์ธ ์ด๋ฏธ์ง๋ค์ ๋ชจ๋ ๋ค์ด๋ก๋ ๋ฐ์๋๋ ๊ฒ์ด๋ค.
<!DOCTYPE html>
<html lang="ko">
<head>
<title>ํ๋ฆฌ๋ก๋</title>
<!-- ํ๋ฆฌ๋ก๋: ํ ๋ฒ์ 6๊ฐ์ฉ ๋ฐ์์ค๋ฏ๋ก, bodyํ๊ทธ์ ์ด๋ฏธ์ง๋ ๊ฐ์ฅ ๋ง์ง๋ง์ ๋ค์ด๋ก๋ -->
<!-- ๋์ ๋ณด์ด๋ ์ด๋ฏธ์ง๋ฅผ ๋จผ์ ๋ค์ด๋ก๋ ๋ฐ์์ ๋ณด์ฌ์ฃผ๊ณ , ํด๋ฆญํ๋ฉด ์คํ๋๋ JS๋ ๋์ค์ ๋ฐ์์ค๊ธฐ. ๋ฐ๋ผ์, DOMContentedLoaded ์ดํ, Load๊น์ง ์๋ฃ๋๋ ์ต์ข
๋ก๋ ์๊ฐ์ด ๋ ์งง์์ง -->
<link rel="preload" as="image" href="./dog.jpeg" />
<!-- ์ผ๋ฐ๋ก๋ -->
<link rel="stylesheet" href="./index.css" />
<script src="index1.js"></script>
<script src="index2.js"></script>
<script src="index3.js"></script>
<script src="index4.js"></script>
<script src="index5.js"></script>
<script src="index6.js"></script>
</head>
<body>
<img src="./dog.jpeg" />
</body>
</html>
์์ ๊ฐ์ด ์ ์ด์ฃผ๋ฉด, ์ด๋ฏธ์ง๋ฅผ index.html๋ฅผ ๋ฐ์์ฌ๋ css์ js๋ณด๋ค ๋จผ์ ๋ฐ์์ค๊ฒ ๋๋ค.