实现 React 应用中字体与图片完全预加载后再展示页面的完整方案

8次阅读

实现 React 应用中字体与图片完全预加载后再展示页面的完整方案

通过 react 的 `` 结合资源预加载策略(如 `preload`、`font-face` 控制、图片懒加载拦截),可在首屏渲染前确保字体、关键图片等资源就绪,避免 fout/foit 和破碎图像问题。

在客户端渲染(CSR)的 react 应用中,浏览器默认按 html 解析顺序逐步加载 css、字体和图片,导致未样式化文本(FOUT)、不可见文本(FOIT)或占位图闪烁等问题。单纯依赖 并不能自动预加载字体或图片——它仅对 React.lazy() 动态导入的组件支持 Suspense 的异步数据源(如 Relay、React Query v5+) 生效。因此,需组合以下三层策略实现真正“全资源就绪后才显示页面”:

✅ 1. 关键字体:使用 + font-display: optional

public/index.html

中预加载核心字体,并禁用不可见文本回退:

       

⚠️ 注意:font-display: optional 要求浏览器在 100ms 内完成加载,否则跳过渲染字体——这正符合“全就绪再显示”的前提。

✅ 2. 关键图片:用 loading=”eager” + 自定义 ImageLoader 拦截

避免 实现 React 应用中字体与图片完全预加载后再展示页面的完整方案 的默认行为。创建一个可 Suspense 的

组件:

// components/PreloadedImage.tsx import { useState, useEffect, Suspense } from 'react';  interface PreloadedImageProps extends Omit, 'src'> {   src: string; }  export function PreloadedImage({ src, ...props }: PreloadedImageProps) {   const [isLoaded, setIsLoaded] = useState(false);   const [error, setError] = useState(false);    useEffect(() => {     const img = new Image();     img.src = src;     img.onload = () => setIsLoaded(true);     img.onerror = () => setError(true);   }, [src]);    if (!isLoaded && !error) {     throw promise.resolve(); // 触发 Suspense fallback   }    return @@##@@; }

路由入口处包裹

// app.tsx import { Suspense } from 'react'; import { BrowserRouter, Routes, Route } from 'react-router-dom';  function App() {   return (            Loading assets... 

text=ZqhQzanResources