您的位置:首页 > 游戏 > 游戏 > 设计本接单_邢台做网站的价格_免费个人网页制作_小程序开发收费价目表

设计本接单_邢台做网站的价格_免费个人网页制作_小程序开发收费价目表

2024/12/27 5:20:06 来源:https://blog.csdn.net/ChengFengTech/article/details/144599587  浏览:    关键词:设计本接单_邢台做网站的价格_免费个人网页制作_小程序开发收费价目表
设计本接单_邢台做网站的价格_免费个人网页制作_小程序开发收费价目表

"这个列表页怎么这么卡?"产品经理皱着眉头看着我。作为一个接手海外电商项目的前端开发者,我深知性能问题的重要性。特别是在东南亚市场,很多用户使用的是中低端手机,网络条件也不太理想。

最近一个月,我带领团队对整个React应用进行了一次全面的性能优化,不仅解决了性能问题,还总结出了一套可复用的优化方案。今天就来分享这个过程中的实战经验。

性能问题分析

首先,我们用 Chrome DevTools 和 React DevTools 对应用进行了全面的性能分析。问题主要集中在这几个方面:

  1. 列表页面首次加载需要3秒以上
  2. 切换tab时明显卡顿
  3. 输入搜索关键词时,界面响应延迟
  4. 滚动大量商品时,帧率明显下降

通过 Performance 面板的记录,我们发现主要是这些原因导致:

// 示例:性能问题的代码模式
const ProductList = () => {const [products, setProducts] = useState([])const [filters, setFilters] = useState({})// 问题1:每次渲染都会重新创建函数const handleFilter = (newFilters) => {setFilters(newFilters)}// 问题2:没有做数据缓存const filteredProducts = products.filter(product => {return Object.entries(filters).every(([key, value]) => product[key] === value)})// 问题3:子组件没有做优化return (<div>{filteredProducts.map(product => (<ProductCard key={product.id} {...product} />))}</div>)
}

优化方案实施

1. 组件优化

首先是最基础的组件优化。我们使用 React.memo 和 useMemo 来避免不必要的重渲染:

// 优化后的 ProductCard 组件
const ProductCard = React.memo(({ id, name, price, image }) => {// 只有当props真正变化时才重新渲染return (<div className="product-card"><img src={image} alt={name} loading="lazy" /><h3>{name}</h3><p>{formatPrice(price)}</p></div>)
}, (prevProps, nextProps) => {// 自定义比较函数,只比较关键属性return (prevProps.id === nextProps.id &&prevProps.price === nextProps.price)
})// 优化列表渲染
const ProductList = () => {const [products, setProducts] = useState([])const [filters, setFilters] = useState({})// 缓存过滤函数const handleFilter = useCallback((newFilters) => {setFilters(newFilters)}, [])// 缓存过滤结果const filteredProducts = useMemo(() => {return products.filter(product => {return Object.entries(filters).every(([key, value]) => product[key] === value)})}, [products, filters])return (<div><FilterPanel onFilter={handleFilter} /><VirtualizedListitems={filteredProducts}renderItem={(product) => (<ProductCard key={product.id} {...product} />)}/></div>)
}

2. 数据处理优化

对于数据处理,我们采用了几个关键的优化策略:

// 1. 使用规范化的数据结构
interface NormalizedState {products: {byId: Record<string, Product>;allIds: string[];};categories: {byId: Record<string, Category>;allIds: string[];};
}// 2. 实现高效的数据查询
const useProductsQuery = (filters: Filters) => {const queryClient = useQueryClient()return useQuery({queryKey: ['products', filters],queryFn: () => fetchProducts(filters),// 实现数据预加载placeholderData: () => {// 使用已有数据作为占位return queryClient.getQueryData(['products'])},// 智能缓存策略staleTime: 5 * 60 * 1000, // 5分钟cacheTime: 30 * 60 * 1000 // 30分钟})
}// 3. 优化状态更新
const useProductsStore = create((set) => ({products: [],setProducts: (newProducts) => {set((state) => ({products: produce(state.products, (draft) => {// 使用 Immer 进行高效的不可变更新draft.push(...newProducts)})}))}
}))

3. 渲染优化

为了解决长列表渲染的问题,我们实现了虚拟滚动:

const VirtualizedList = ({ items, renderItem, itemHeight = 200 }) => {const containerRef = useRef<HTMLDivElement>(null)const [visibleRange, setVisibleRange] = useState({ start: 0, end: 10 })const onScroll = useCallback(() => {if (!containerRef.current) returnconst { scrollTop, clientHeight } = containerRef.currentconst start = Math.floor(scrollTop / itemHeight)const end = Math.min(start + Math.ceil(clientHeight / itemHeight),items.length)setVisibleRange({ start, end })}, [itemHeight, items.length])// 只渲染可见区域的项目const visibleItems = useMemo(() => {return items.slice(visibleRange.start, visibleRange.end)}, [items, visibleRange])return (<div ref={containerRef}style={{ height: '100vh', overflow: 'auto' }}onScroll={onScroll}><div style={{ height: items.length * itemHeight }}><div style={{ transform: `translateY(${visibleRange.start * itemHeight}px)`}}>{visibleItems.map(renderItem)}</div></div></div>)
}

4. 网络优化

最后,我们还对网络请求进行了优化:

// 1. 实现请求去重和缓存
const requestCache = new Map()const fetchWithCache = async (url: string, options = {}) => {const cacheKey = `${url}-${JSON.stringify(options)}`if (requestCache.has(cacheKey)) {return requestCache.get(cacheKey)}const promise = fetch(url, options).then(res => res.json())requestCache.set(cacheKey, promise)try {const result = await promisereturn result} finally {// 5分钟后清除缓存setTimeout(() => {requestCache.delete(cacheKey)}, 5 * 60 * 1000)}
}// 2. 实现数据预加载
const prefetchNextPage = (currentPage: number) => {const nextPage = currentPage + 1// 预加载下一页数据fetchWithCache(`/api/products?page=${nextPage}`, {priority: 'low' // 使用低优先级请求})
}

优化效果

经过这一系列优化,我们取得了显著的效果:

  1. 首屏加载时间从3秒减少到1.2秒
  2. 列表滚动帧率稳定在60fps
  3. 搜索响应时间从500ms减少到100ms
  4. 内存占用减少40%

最让我欣慰的是收到用户的反馈:"现在浏览商品太流畅了!"这让之前的努力都值得了。

经验总结

React性能优化不是一蹴而就的,需要从多个层面系统地思考和实施:

  1. 组件层面:合理使用 memo、useMemo、useCallback
  2. 数据层面:规范化数据结构,实现高效的状态管理
  3. 渲染层面:采用虚拟滚动,延迟加载
  4. 网络层面:请求优化,数据预加载

写在最后

性能优化是一个持续的过程,不是一次性的工作。通过这次优化,我不仅解决了具体的性能问题,更重要的是建立了一套可持续的性能优化方法论。

如果你也在做React应用的性能优化,欢迎在评论区分享你的经验,让我们一起进步!

如果觉得这篇文章对你有帮助,别忘了点个赞 👍

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com