前端性能优化实战:从加载到渲染的全链路提速

news/2024/12/12 16:32:27/文章来源:https://www.cnblogs.com/yuanyanglu/p/18602911

"网站太慢了,用户都在抱怨!"上周,我接手了一个正在运行的电商项目,首屏加载时间竟然长达 8 秒。作为一个对性能有执念的前端开发者,这个数字让我夜不能寐。经过一周的优化,我们把首屏时间压缩到了 2 秒以内。今天,我想和大家分享这个过程中的实战经验。😊

性能问题诊断

首先,我们需要找出性能瓶颈在哪里。通过 Chrome DevTools 的 Performance 和 Network 面板,我发现了几个主要问题:

// 问题1:资源加载顺序不合理
// 之前的代码
<head><link rel="stylesheet" href="/styles/main.css"><script src="/js/analytics.js"></script><script src="/js/main.js"></script>
</head>// 问题2:图片资源没有优化
<img src="large-product-image.jpg" alt="product">// 问题3:大量的同步 JavaScript 执行
window.onload = function() {initializeEverything();setupEventListeners();loadThirdPartyScripts();
}

加载优化

1. 资源加载策略优化

首先,我们重新组织了资源的加载顺序:

<head><!-- 关键 CSS 内联 --><style>/* 首屏关键样式 */.header, .hero { /* ... */ }</style><!-- 非关键 CSS 异步加载 --><link rel="preload" href="/styles/main.css" as="style" onload="this.rel='stylesheet'"><!-- 延迟加载非关键 JavaScript --><script defer src="/js/main.js"></script><script async src="/js/analytics.js"></script>
</head>

2. 图片优化

我们实现了一个渐进式图片加载策略:

// components/ProgressiveImage.tsx
import { useState, useEffect } from 'react'export function ProgressiveImage({ src, alt, width, height }: ImageProps) {const [currentSrc, setCurrentSrc] = useState(getLowQualityUrl(src))useEffect(() => {const img = new Image()img.src = srcimg.onload = () => {setCurrentSrc(src)}}, [src])return (<imgsrc={currentSrc}alt={alt}width={width}height={height}loading="lazy"decoding="async"className="transition-opacity duration-300"/>)
}

3. 代码分割和懒加载

使用 webpack 和 React.lazy 实现智能代码分割:

// 路由级别的代码分割
const ProductList = React.lazy(() => import('./pages/ProductList'))
const ProductDetail = React.lazy(() => import('./pages/ProductDetail'))function App() {return (<Suspense fallback={<Loading />}><Routes><Route path="/products" element={<ProductList />} /><Route path="/products/:id" element={<ProductDetail />} /></Routes></Suspense>)
}

渲染优化

1. 虚拟列表实现

对于长列表,我们实现了虚拟滚动:

// components/VirtualList.tsx
function VirtualList({ items, rowHeight, visibleRows }: VirtualListProps) {const [scrollTop, setScrollTop] = useState(0)const startIndex = Math.floor(scrollTop / rowHeight)const visibleItems = items.slice(startIndex, startIndex + visibleRows)return (<div style={{ height: items.length * rowHeight }} onScroll={e => setScrollTop(e.currentTarget.scrollTop)}><div style={{ transform: `translateY(${startIndex * rowHeight}px)` }}>{visibleItems.map(item => (<div key={item.id} style={{ height: rowHeight }}>{item.content}</div>))}</div></div>)
}

2. 状态管理优化

我们使用了细粒度的状态更新策略:

// 优化前:整个组件树重渲染
const [productData, setProductData] = useState({list: [],filters: {},sorting: 'price'
})// 优化后:分离关注点
const [productList, setProductList] = useState([])
const [filters, setFilters] = useState({})
const [sorting, setSorting] = useState('price')

3. 缓存策略

实现了多层缓存机制:

// utils/cache.ts
const cache = new Map()export function withCache<T>(key: string,fetchFn: () => Promise<T>,ttl: number = 3600000 // 1小时
): Promise<T> {const cached = cache.get(key)if (cached && Date.now() - cached.timestamp < ttl) {return Promise.resolve(cached.data)}return fetchFn().then(data => {cache.set(key, { data, timestamp: Date.now() })return data})
}// 使用示例
const getProductData = async (id: string) => {return withCache(`product:${id}`,() => api.fetchProduct(id))
}

性能监控

为了持续监控性能,我们实现了性能指标收集:

// utils/performance.ts
export function collectMetrics() {const paint = performance.getEntriesByType('paint')const navigation = performance.getEntriesByType('navigation')[0]return {FCP: paint.find(p => p.name === 'first-contentful-paint')?.startTime,TTFB: navigation.responseStart - navigation.requestStart,TTI: performance.now(), // 简化版 TTI}
}// 定期上报性能数据
setInterval(() => {const metrics = collectMetrics()analytics.send('performance', metrics)
}, 60000)

优化成果

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

  • 首屏加载时间:8s → 2s
  • 首次内容绘制 (FCP):2.8s → 0.8s
  • 最大内容绘制 (LCP):4.5s → 1.5s
  • 页面交互延迟 (FID):300ms → 50ms

最让我欣慰的是收到用户的反馈:"网站变得超级快,用起来太舒服了!"这让所有的优化工作都变得值得。😊

写在最后

前端性能优化是一个持续的过程,没有一劳永逸的解决方案。关键是要:

  • 建立性能指标基线
  • 持续监控和优化
  • 在开发阶段就注意性能问题
  • 打造性能优化文化

有什么问题欢迎在评论区讨论,我们一起学习进步!

如果觉得有帮助,别忘了点赞关注,我会继续分享更多前端优化的实战经验~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/851451.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

转载:【AI系统】算子手工优化

在上一篇中,探讨了算子计算和调度的概念,并强调了高效调度策略在释放硬件性能和降低延迟方面的重要性。本文,我们将深入讨论手写算子调度时需要考虑的关键因素,并介绍一些著名的高性能算子库。 计算分析 在优化算子前,首先需要知道当前程序的瓶颈在哪里,是计算瓶颈还是访…

强化学习模型的训练和推理以及成员推断攻击的实现

Reinforcement_learning 2024年9月1日更新 在此教程中,我们将对强化学习模型及其原理进行一个简单的介绍,并实现一种强化学习模型的训练和推理过程,且至少支持3种数据集,目前支持数据集有:MNIST、fashionMNIST、CIFAR10等,并给用户提供一个详细的帮助文档。 目录 基本介绍…

ASE8N65S-ASEMI高压N沟道MOS管ASE8N65S

ASE8N65S-ASEMI高压N沟道MOS管ASE8N65S编辑:ll ASE8N65S-ASEMI高压N沟道MOS管ASE8N65S 型号:ASE8N65S 品牌:ASEMI 封装:TO-220F 最大漏源电流:8A 漏源击穿电压:650V 批号:最新 RDS(ON)Max:1.25Ω 引脚数量:3 沟道类型:N沟道MOS管 芯片尺寸:MIL 漏电流: 恢复时间:…

OCR识别智能采集终端-拍照抄表器-数采物联网水电气仪表采集

www.daq-iot.com SC-LP-CAM系列电池供电无线定时拍照摄像头抄表终端水表读表器是一款由数采物联推出的新型数据采集终端,可以用于快速抄表传统老旧机械仪表或无法直接通讯的仪表。它采用摄像直读方式,在设定的时间间隔内进行拍照,并将照片上传到服务器后进行分析识别,得…

testng+allure

1.坐标 <!--Allure报告依赖包--> <dependency> <groupId>io.qameta.allure</groupId> <artifactId>allure-testng</artifactId> <version>${allure.version}</version> <scope>test</scope> </dependency> …

【帆软Report】关于按钮控件的使用

在帆软使用过程中,会遇到一些需求,比如某个功能,某些页面要在特定情况下才可以使用,这篇主要是对按钮在特定情况下显示和隐藏的心得先说需求:有一个打分按钮,要求实现 当传入的状态编码是“1”的时候可以看到并且点击,其他状态编码时按钮无法使用并且隐藏。实现方法如下…

SOLIDWORKS二次开发参数化

如今企业开发新产品时,零件模型的建立及出图的速度是决定整个产品开发效率的关键。在企业的产品的开发到一定时期,很多的设计经过实际验证分析后,一些产品的大致持征已经确定,这时企业就希望能将该类产品系列化、参数化及标准化。于是,将模型设计中定量化的参数变量化就成…

转载:【AI系统】昇思MindSpore并行

本文将会介绍昇思MindSpore的并行训练技术,以及如何通过张量重排布和自动微分简化并行策略搜索,实现高效大模型训练。 大模型的带来 随着深度学习的发展,为了实现更高的准确率和更丰富的应用场景,训练数据集和神经网络模型的规模日益增大。特别是自然语言处理(Natural Lan…

转载:【AI系统】流水并行

在大模型的训练中,单个设备往往无法满足计算和存储需求,因此需要借助分布式训练技术。其中,模型并行(Model Parallelism, MP)是一种重要的方法。模型并行的基本思想是将模型的计算任务拆分到不同的设备上执行,以提高训练效率和处理更大规模的模型。模型并行主要分为朴素的…

单机milvusdb部署standalone-monitoring

环境:OS:Centos 7milvusdb:standalone 2.4.6 前提条件:已经部署好了milvusdb 1.下载相应文件https://github.com/milvus-io/milvus-docs/tree/v2.4.x下载整个软件包,解压后将milvus-docs-2.4.x\assets\standalone-monitoring这个目录单独拷贝出来 2.standalone-monitoring目录需…

CMDB(进阶篇):如何管理好一个CMDB

配置管理数据库(Configuration Management Database,简称CMDB)是IT运维管理中的一个核心组件,它存储了IT环境中的各种配置项信息及其相互关系。一个高效的CMDB不仅能提升运维效率,还能显著增强故障排查和系统变更管理的能力。然而,管理好一个CMDB并非易事,需要精心规划、…

IDEA 2024 加载 JRebel(2024.4.2)在线开启以及配置

今天在自己的IDEA 2024 版本上加载JRebel(2024.4.2),在线开启以及配置 1.安装:个人建议建议从idea插件市场下载,下载下来直接使用 2.激活 (1)填写激活网址 + 生成的 GUID,邮箱随便填写。GUID 在线生成网址:Create GUID online (2)配置网址列表,一个不行就换另一个,G…