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

ReactJS中如何加速请求元素的页面显示?

解决React页面加载后端元素延迟显示的问题

一、先添加预加载状态(即时反馈用户)

首先给组件加上加载状态,在数据返回前显示骨架屏占位,避免页面空白:

修改后的请求代码:

import { useState, useEffect } from 'react';
import axios from 'axios';

interface ICard {
  // 你的卡片类型定义
  id: number;
  title: string;
  price: string;
  image: string;
}

const CardList = () => {
  const [cards, setCards] = useState<ICard[]>([]);
  const [isLoading, setIsLoading] = useState(true); // 新增加载状态

  useEffect(() => {
    fetchCards();
  }, []);

  async function fetchCards() {
    try {
      setIsLoading(true);
      const response = await axios.get<ICard[]>(
        `http://localhost:8080/backend/products.php`,
        {
          responseType: 'json',
          headers: {
            'Content-Type': 'application/json',
          },
        }
      );
      setCards(response.data || []);
    } catch (e) {
      alert('加载数据失败:' + (e as Error).message);
      setCards([]);
    } finally {
      setIsLoading(false); // 无论成败都结束加载状态
    }
  }

  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: '1rem', padding: '1rem' }}>
      {isLoading ? (
        // 生成6个骨架屏占位,数量可根据布局调整
        Array.from({ length: 6 }).map((_, idx) => (
          <div key={idx} style={{
            width: '250px',
            padding: '1rem',
            borderRadius: '8px',
            background: '#f0f0f0',
            animation: 'pulse 1.5s infinite ease-in-out'
          }}>
            <div style={{
              width: '100%',
              height: '180px',
              borderRadius: '4px',
              background: '#e0e0e0',
              marginBottom: '0.8rem'
            }}></div>
            <div style={{
              height: '16px',
              background: '#e0e0e0',
              borderRadius: '4px',
              marginBottom: '0.5rem'
            }}></div>
            <div style={{
              height: '16px',
              width: '60%',
              background: '#e0e0e0',
              borderRadius: '4px'
            }}></div>
          </div>
        ))
      ) : (
        cards.map(card => (
          <div key={card.id} style={{
            width: '250px',
            border: '1px solid #eee',
            borderRadius: '8px',
            overflow: 'hidden'
          }}>
            <img src={card.image} alt={card.title} style={{ width: '100%', height: '180px', objectFit: 'cover' }} />
            <div style={{ padding: '0.8rem' }}>
              <h3 style={{ margin: '0 0 0.5rem' }}>{card.title}</h3>
              <p style={{ margin: 0, color: '#666' }}>{card.price}</p>
            </div>
          </div>
        ))
      )}
    </div>
  );
};

export default CardList;

骨架屏动画CSS(可放到全局样式或组件内style标签)

@keyframes pulse {
  0% { opacity: 0.6; }
  50% { opacity: 1; }
  100% { opacity: 0.6; }
}

二、优化加载速度的具体方案

前端侧优化

  1. 本地缓存数据:如果数据不会频繁更新,把请求结果存在localStorage,下次页面加载先读缓存,再后台更新:
async function fetchCards() {
  try {
    setIsLoading(true);
    // 优先读取本地缓存
    const cached = localStorage.getItem('cardsCache');
    if (cached) {
      setCards(JSON.parse(cached));
    }
    // 发起请求更新最新数据
    const response = await axios.get<ICard[]>(`http://localhost:8080/backend/products.php`);
    const newData = response.data || [];
    setCards(newData);
    localStorage.setItem('cardsCache', JSON.stringify(newData));
  } catch (e) {
    alert('加载失败:' + (e as Error).message);
  } finally {
    setIsLoading(false);
  }
}
  1. 图片懒加载:给卡片里的图片添加loading="lazy"属性,只在图片进入视口时加载:
<img src={card.image} alt={card.title} loading="lazy" />
  1. 请求重试机制:针对偶尔的网络波动,手动实现重试逻辑:
async function fetchCards(retryCount = 2) {
  try {
    // ... 原有请求代码
  } catch (e) {
    if (retryCount > 0) {
      return fetchCards(retryCount - 1);
    }
    alert('加载失败:' + (e as Error).message);
  }
}

后端侧优化(关键,加载慢大多源于后端瓶颈)

  1. 优化SQL查询:
    • 避免使用SELECT *,只查询需要的字段(比如SELECT id, title, price, image FROM products)
    • 给高频查询字段(如id、分类字段)添加数据库索引
    • 数据量较大时实现分页,前端仅请求第一页数据,滚动到底部再加载下一页(后端接收page和limit参数)
  2. 启用Gzip压缩:在PHP接口开头添加代码,压缩响应内容以减少传输体积:
<?php
ob_start("ob_gzhandler"); // 开启Gzip压缩
header('Content-Type: application/json');

// 数据库查询与返回逻辑
?>
  1. 缓存查询结果:用Redis或PHP文件缓存,将数据库查询结果缓存5-10分钟,避免每次请求都查询数据库:
<?php
$cacheKey = 'products_list';
$cacheExpire = 300; // 缓存5分钟
$cachedData = apc_fetch($cacheKey); // 使用APC缓存,也可替换为Redis

if (!$cachedData) {
  // 执行数据库查询
  $result = mysqli_query($conn, "SELECT id, title, price, image FROM products");
  $data = mysqli_fetch_all($result, MYSQLI_ASSOC);
  apc_store($cacheKey, $data, $cacheExpire); // 存入缓存
} else {
  $data = $cachedData;
}

echo json_encode($data);
?>
  1. 服务器配置优化:升级服务器带宽、优化PHP-FPM配置,或把静态资源(如图片)放到CDN加速。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 18:50:28