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; } }
二、优化加载速度的具体方案
前端侧优化
- 本地缓存数据:如果数据不会频繁更新,把请求结果存在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); } }
- 图片懒加载:给卡片里的图片添加
loading="lazy"属性,只在图片进入视口时加载:
<img src={card.image} alt={card.title} loading="lazy" />
- 请求重试机制:针对偶尔的网络波动,手动实现重试逻辑:
async function fetchCards(retryCount = 2) { try { // ... 原有请求代码 } catch (e) { if (retryCount > 0) { return fetchCards(retryCount - 1); } alert('加载失败:' + (e as Error).message); } }
后端侧优化(关键,加载慢大多源于后端瓶颈)
- 优化SQL查询:
- 避免使用
SELECT *,只查询需要的字段(比如SELECT id, title, price, image FROM products) - 给高频查询字段(如id、分类字段)添加数据库索引
- 数据量较大时实现分页,前端仅请求第一页数据,滚动到底部再加载下一页(后端接收
page和limit参数)
- 避免使用
- 启用Gzip压缩:在PHP接口开头添加代码,压缩响应内容以减少传输体积:
<?php ob_start("ob_gzhandler"); // 开启Gzip压缩 header('Content-Type: application/json'); // 数据库查询与返回逻辑 ?>
- 缓存查询结果:用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); ?>
- 服务器配置优化:升级服务器带宽、优化PHP-FPM配置,或把静态资源(如图片)放到CDN加速。
内容的提问来源于stack exchange,提问作者Maxs Grater
相关产品推荐
相关产品推荐

