[Vite + React] Preload๋ก ํฐํธ ์ต์ ํํ๊ธฐ
1. index.html์์ link ํ๊ทธ์ preload ์ถ๊ฐ
-> ๊ฐ์ฅ ๊ฐํธํ๊ณ ๋ณดํธ์ ์ธ ๋ฐฉ๋ฒ. ํ๋ก์ ํธ ๊ท๋ชจ๊ฐ ์๊ฑฐ๋ ํฐํธ ํ์ผ์ด ํ๋๊ฐ๋ผ๋ฉด ์๋์ผ๋ก link ํ๊ทธ๋ฅผ ์ถ๊ฐํ๋ฉด ๋จ
// index.html
<head>
<link
rel="preload"
href="src/assets/fonts/PretendardVariable.woff2"
as="font"
type="font/woff2"
crossorigin="anonymous"
/>
</head>
2. build ์ ๋์ ์ผ๋ก html ์ฃผ์ ํ๊ธฐ
createHtmlPlugin ์ฌ์ฉ์ํด vite-plugin-html ์ค์น
npm install -D vite-plugin-html
ํฐํธ ํด๋์์ ํ๋ฆฌ๋ก๋ํ ํฐํธ ์ ํ
// src/utils/fontPreload.ts
import { readdirSync } from 'fs'
import { resolve } from 'path'
import { HtmlTagDescriptor } from 'vite'
const fontsDirectory = resolve(__dirname, '../../src/assets/fonts')
console.log('fontsDirectory', fontsDirectory)
const fontFiles = readdirSync(fontsDirectory).filter(
(file) => file.endsWith('.woff2'),
)
export const injectFontsToHead: HtmlTagDescriptor[] = fontFiles.map((fontFile) => ({
injectTo: 'head',
tag: 'link',
attrs: {
rel: 'preload',
href: `src/assets/fonts/${fontFile}`,
as: 'font',
type: 'font/woff2',
crossOrigin: 'anonymous',
}
}))
vite.config.ts์์ src/util ํด๋์ ์ ๊ทผํ๋ ค๋ฉด tsconfig.node.json ํ์ผ์ include๋ถ๋ถ์ ํด๋น ํ์ผ์ ์ถ๊ฐํด์ผํจ
// tsconfig.node.json
{
"compilerOptions": {
...
},
"include": ["vite.config.ts", "src/utils/font.ts"]
}
vite.config.ts์์ injectFontsToHead ์ฝ๋ ์ฃผ์
// vite.config.ts
import { createHtmlPlugin } from 'vite-plugin-html'
import { injectFontsToHead } from './src/utils/font'
export default defineConfig({
plugins: [..., createHtmlPlugin({ inject: { tags: injectFontsToHead } })],
})
๋ ๋ฐฉ๋ฒ ์ฌ์ด์ ์ฑ๋ฅ ์ฐจ์ด๋ ์๋ ๊ฒ ๊ฐ๊ณ (๋ ๋ฐฉ๋ฒ ๋ชจ๋ 17~30ms ๋ด๋ก ๋ถ๋ฌ์ด) ํ๋ก์ ํธ ๊ด๋ฆฌ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ์ ํํ๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
vite ์ค์ ์ ๊ฑด๋๋ ๊ฑด ๊ท์ฐฎ์ง๋ง ํ๋ก์ ํธ๊ฐ ํฌ๊ณ ์์ฃผ ์ ๋ฐ์ดํธ ๋๋ค๋ฉด ์๋ํํด์ ์ฌ์ฉํ๋ ๊ฒ ํธํ ์๋ ์์ ๊ฒ ๊ฐ๋ค.
์ค์ํ ๊ฑด ๊ผญ ์ฒซ ํ๋ฉด์ ํ์์ ์ธ ํฐํธ๋ง ํ๋ฆฌ๋ก๋ฉํ๋ ๊ฒ!
์ฐธ๊ณ https://velog.io/@oo009pbh/Vite๋ฅผ-ํตํด-๋ค์ด๋ฐ์-ํฐํธ๋ฅผ-preloading-ํด๋ณด์