You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js如何实现页面展示前预加载数据并添加加载器

Next.js 重资源页面预加载实现方案

你原来写的固定2秒延时方案有本质缺陷:网络环境好的时候用户会白白等待固定时长,拖慢首屏体验;网络差的时候2秒倒计时结束资源还没加载完成,页面展示后还是会出现图片空白、布局偏移的问题,根本达不到“资源全加载完再展示页面”的需求。
正确的实现逻辑是以资源实际加载状态为判断依据,不硬编码等待时长,具体实现如下。

核心实现思路

  • 页面初始状态默认展示自定义加载器
  • 页面挂载后,并行拉取页面所需的接口数据、监听所有首屏图片的加载状态
  • 所有核心资源加载完成后,再切换展示正式页面内容
  • 可配置极短的最小加载时长(通常300ms即可),避免资源加载过快时加载器闪一下就消失的体验问题

可直接复用的代码实现

import { useState, useEffect } from 'react'
import PageLayout from '@/components/PageLayout'
import AboutHero from '@/components/AboutHero'

const AboutPage = () => {
  const [pageReady, setPageReady] = useState(false)

  useEffect(() => {
    // 加载页面接口数据
    const loadCoreData = async () => {
      // 替换成你自己的页面数据请求逻辑,比如拉取关于页的文案、配置信息
      // const pageData = await fetch('/api/about').then(res => res.json())
    }

    // 等待所有首屏图片加载完成
    const waitForImagesLoad = () => {
      return new Promise((resolve) => {
        const allImgs = Array.from(document.images)
        const pendingImgs = allImgs.filter(img => !img.complete)

        // 没有待加载图片直接返回
        if (pendingImgs.length === 0) return resolve(true)

        let loadedCount = 0
        const onSingleImgDone = () => {
          loadedCount++
          if (loadedCount === pendingImgs.length) resolve(true)
        }

        pendingImgs.forEach(img => {
          // 加载成功、失败都标记为完成,避免单张图异常卡住整个页面
          img.addEventListener('load', onSingleImgDone, { once: true })
          img.addEventListener('error', onSingleImgDone, { once: true })
        })
      })
    }

    const initPage = async () => {
      await loadCoreData()
      await waitForImagesLoad()
      // 最小展示300ms加载器,避免闪烁
      await new Promise(resolve => setTimeout(resolve, 300))
      setPageReady(true)
    }

    initPage()
  }, [])

  return pageReady ? (
    <PageLayout headProps={{ title: "We are Laugh - About" }}>
      <AboutHero />
    </PageLayout>
  ) : (
    // 替换成你的自定义加载器组件
    <div className="fixed inset-0 flex items-center justify-center bg-white">
      <div>页面加载中...</div>
    </div>
  )
}

export default AboutPage

关键优化注意事项

  • 如果你使用Next.js自带的next/image组件,记得给首屏可见的图片加上priority属性,标记为高优先级加载资源,避免被默认懒加载策略影响,导致首屏图片没被提前加载
  • 不要用window.onload事件作为页面就绪的判断标准,这个事件会等待页面所有第三方脚本、埋点资源、非首屏资源全部加载完才触发,会让用户等待不必要的时长
  • 图片加载失败一定要做兜底处理,不要因为单张资源异常就把用户永久卡在加载页
  • 如果你用Next.js 13+的App Router模式,可以配合内置的loading.tsx文件和路由预加载能力实现,在用户点击路由跳转时就开始加载目标页资源,资源就绪后再完成路由切换,体验更流畅

内容的提问来源于stack exchange,提问作者Emiliano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 06:36:16