참고
React 기반 프레임워크는 종종 리소스 로딩을 대신 처리해주므로, 이 API를 직접 호출할 필요가 없을 수 있어요. 자세한 내용은 프레임워크 문서를 참고하세요.
preload를 사용하면 사용할 것으로 예상되는 스타일시트, 폰트, 외부 스크립트 같은 리소스를 미리 가져올 수 있어요.
preload("https://example.com/font.woff2", {as: "font"});
preload는 브라우저에게 "이 리소스를 미리 다운로드해둬"라고 알려주는 기능이에요. 실제로 사용하기 전에 미리 다운로드를 시작해서 나중에 필요할 때 즉시 사용할 수 있어요!
preload(href, options)리소스를 미리 로드하려면, react-dom에서 preload 함수를 호출하세요.
import { preload } from 'react-dom';
function AppRoot() {
preload("https://example.com/font.woff2", {as: "font"});
// ...
}
preload 함수는 브라우저에게 주어진 리소스를 다운로드하기 시작해야 한다는 힌트를 제공하며, 이는 시간을 절약할 수 있어요.
href: 문자열이에요. 다운로드하고 싶은 리소스의 URL이에요.options: 객체예요. 다음 속성들을 포함해요:as: 필수 문자열이에요. 리소스의 유형이에요. 가능한 값은 audio, document, embed, fetch, font, image, object, script, style, track, video, worker예요.crossOrigin: 문자열이에요. 사용할 CORS 정책이에요. 가능한 값은 anonymous와 use-credentials예요. as가 "fetch"로 설정되었을 때 필수예요.referrerPolicy: 문자열이에요. 페칭할 때 보낼 Referrer 헤더예요. 가능한 값은 no-referrer-when-downgrade(기본값), no-referrer, origin, origin-when-cross-origin, unsafe-url이에요.integrity: 문자열이에요. 진위를 확인하기 위한 리소스의 암호화 해시예요.type: 문자열이에요. 리소스의 MIME 타입이에요.nonce: 문자열이에요. 엄격한 Content Security Policy를 사용할 때 리소스를 허용하기 위한 암호화 nonce예요.fetchPriority: 문자열이에요. 리소스를 페칭하는 상대적 우선순위를 제안해요. 가능한 값은 auto(기본값), high, low예요.imageSrcSet: 문자열이에요. as: "image"일 때만 사용해요. 이미지의 소스 세트를 지정해요.imageSizes: 문자열이에요. as: "image"일 때만 사용해요. 이미지의 크기를 지정해요.preload는 아무것도 반환하지 않아요.
preload 호출은 단일 호출과 같은 효과를 가져요. preload 호출은 다음 규칙에 따라 동일한 것으로 간주돼요:href를 가지면 동일한 것으로 간주되지만, 예외가 있어요:as가 image로 설정된 경우, 두 호출이 동일한 href, imageSrcSet, imageSizes를 가지면 동일한 것으로 간주돼요.preload를 호출할 수 있어요: 컴포넌트를 렌더링하는 동안, Effect 안에서, 이벤트 핸들러 안에서 등등.preload는 컴포넌트를 렌더링하는 동안 또는 컴포넌트 렌더링에서 시작된 비동기 context에서 호출할 때만 효과가 있어요. 다른 모든 호출은 무시될 거예요.컴포넌트나 그 자식들이 특정 리소스를 사용할 것을 알고 있다면, 컴포넌트를 렌더링할 때 preload를 호출하세요.
import { preload } from 'react-dom';
function AppRoot() {
preload("https://example.com/script.js", {as: "script"});
return ...;
}
브라우저가 스크립트를 즉시 실행하기를 원한다면(단순히 다운로드만 하는 게 아니라), 대신 preinit을 사용하세요. ESM 모듈을 로드하고 싶다면, preloadModule을 사용하세요.
사용 시나리오:
import { preload } from 'react-dom';
function VideoPlayer() {
// 비디오 플레이어 스크립트를 미리 다운로드
preload("https://cdn.example.com/video-player.js", {as: "script"});
return <div id="video-container">Loading player...</div>;
}
import { preload } from 'react-dom';
function AppRoot() {
preload("https://example.com/style.css", {as: "style"});
return ...;
}
스타일시트를 즉시 문서에 삽입하기를 원한다면(브라우저가 단순히 다운로드만 하는 게 아니라 즉시 파싱하도록), 대신 preinit을 사용하세요.
사용 시나리오:
import { preload } from 'react-dom';
function AdminPanel() {
// 관리자 패널 스타일을 미리 다운로드 (조건부로 사용될 수 있음)
preload("https://cdn.example.com/admin-styles.css", {as: "style"});
return <div>Admin Panel</div>;
}
import { preload } from 'react-dom';
function AppRoot() {
preload("https://example.com/style.css", {as: "style"});
preload("https://example.com/font.woff2", {as: "font"});
return ...;
}
스타일시트를 미리 로드한다면, 스타일시트가 참조하는 모든 폰트도 미리 로드하는 것이 현명해요. 그렇게 하면 브라우저가 스타일시트를 다운로드하고 파싱하기 전에 폰트 다운로드를 시작할 수 있어요.
사용 시나리오:
import { preload } from 'react-dom';
function AppRoot() {
// 스타일시트와 해당 폰트를 함께 미리 로드
preload("https://cdn.example.com/theme.css", {as: "style"});
preload("https://cdn.example.com/roboto-regular.woff2", {as: "font"});
preload("https://cdn.example.com/roboto-bold.woff2", {as: "font"});
return <div>App Content</div>;
}
폰트를 미리 로드하는 것은 특히 중요해요! 폰트 파일은 크기가 크고, 스타일시트가 로드되기 전까지는 브라우저가 폰트가 필요한지 모르기 때문에, FOUT(Flash of Unstyled Text)나 FOIT(Flash of Invisible Text)를 방지할 수 있어요.
import { preload } from 'react-dom';
function AppRoot() {
preload("/banner.png", {
as: "image",
imageSrcSet: "/banner512.png 512w, /banner1024.png 1024w",
imageSizes: "(max-width: 512px) 512px, 1024px",
});
return ...;
}
이미지를 미리 로드할 때, imageSrcSet과 imageSizes 옵션은 브라우저가 화면 크기에 맞는 적절한 크기의 이미지를 가져오는 데 도움을 줘요.
사용 시나리오:
import { preload } from 'react-dom';
function ProductPage({ productId }) {
// 제품 상세 이미지를 미리 로드 (반응형 이미지)
preload(`/products/${productId}/hero.jpg`, {
as: "image",
imageSrcSet: `/products/${productId}/hero-sm.jpg 640w, /products/${productId}/hero-md.jpg 1280w, /products/${productId}/hero-lg.jpg 1920w`,
imageSizes: "(max-width: 640px) 640px, (max-width: 1280px) 1280px, 1920px",
fetchPriority: "high" // 중요한 이미지는 높은 우선순위로
});
return <div>Product Details</div>;
}
외부 리소스가 필요한 페이지나 state로 전환하기 전에 이벤트 핸들러에서 preload를 호출하세요. 새 페이지나 state를 렌더링하는 동안 호출하는 것보다 더 일찍 프로세스를 시작할 수 있어요.
import { preload } from 'react-dom';
function CallToAction() {
const onClick = () => {
preload("https://example.com/wizardStyles.css", {as: "style"});
startWizard();
}
return (
<button onClick={onClick}>Start Wizard</button>
);
}
실제 활용 예시:
import { preload } from 'react-dom';
function ProductCard({ product }) {
const handleMouseEnter = () => {
// 마우스를 올렸을 때 상세 페이지 리소스를 미리 로드
preload(`/api/products/${product.id}`, {
as: "fetch",
crossOrigin: "anonymous"
});
preload(`/products/${product.id}/gallery.css`, {as: "style"});
};
const handleClick = () => {
navigate(`/product/${product.id}`);
};
return (
<div
onMouseEnter={handleMouseEnter}
onClick={handleClick}
>
<h3>{product.name}</h3>
<p>{product.price}</p>
</div>
);
}
위 예시에서:
preload를 사용하기 좋은 경우:
preinit 대신 preload를 사용해야 하는 경우: