当前位置: 首页 > news >正文

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

"这个页面怎么这么慢啊?" 产品经理小李站在我的工位旁,指着屏幕上的数据大屏抱怨道。我打开 Chrome DevTools 看了一眼,首屏加载时间确实有点吓人 - 足足用了 8 秒。作为一个追求极致体验的前端开发者,这个数字让我坐不住了。

回想起上周的性能检测会议,我们发现不少用户,特别是在移动端访问时,经常会遇到白屏、卡顿的问题。经过一周的深入优化,我们把首屏时间压缩到了 2 秒以内。今天就来分享这个优化过程中的实战经验。

问题分析

首先,我们需要建立一个完整的性能指标体系。通过 Chrome DevTools 和 Lighthouse,我们收集了关键的性能数据:

  • 首次内容绘制(FCP): 3.8s
  • 最大内容绘制(LCP): 8.2s
  • 首次输入延迟(FID): 280ms
  • 累积布局偏移(CLS): 0.28

这些数据都远远超出了 Google 推荐的标准。通过性能瀑布图,我们发现了几个主要问题:

  • 资源加载过重
  • 渲染阻塞严重
  • 代码执行效率低
  • 缓存策略不合理

优化策略

就像给汽车做全面保养一样,我们的优化工作也要从多个环节入手。

资源加载优化

首先是资源的瘦身和加载优化。就像整理行李箱一样,我们要决定什么东西是必须首屏带上的,什么可以延后再加载:

// 路由级别的代码分割
const routes = [{path: '/',component: () => import('./pages/Home'),loading: LoadingSpinner},{path: '/dashboard',component: () => import('./pages/Dashboard'),loading: LoadingSpinner}
]// 组件级别的按需加载
const Chart = lazy(() => import('./components/Chart'))// 图片资源的优化
function OptimizedImage({ src, alt }) {return (<picture><source srcSet={`${src}?w=400 400w, ${src}?w=800 800w`} sizes='(max-width: 600px) 400px, 800px' type='image/webp' /><img src={`${src}?w=800`} alt={alt} loading='lazy' decoding='async' /></picture>)
}

渲染性能优化

然后是渲染性能的优化。就像装修房子要讲究顺序一样,我们也要优化渲染的流程:

// 虚拟列表优化长列表渲染
function VirtualList({ items, rowHeight, visibleRows }) {const [scrollTop, setScrollTop] = useState(0)const containerRef = useRef(null)const startIndex = Math.floor(scrollTop / rowHeight)const endIndex = Math.min(startIndex + visibleRows, items.length)const visibleItems = items.slice(startIndex, endIndex)const totalHeight = items.length * rowHeightconst offsetY = startIndex * rowHeightreturn (<div ref={containerRef} style={{ height: visibleRows * rowHeight, overflow: 'auto' }} onScroll={e => setScrollTop(e.target.scrollTop)}><div style={{ height: totalHeight, position: 'relative' }}><div style={{ transform: `translateY(${offsetY}px)` }}>{visibleItems.map(item => (<div key={item.id} style={{ height: rowHeight }}>{item.content}</div>))}</div></div></div>)
}

缓存策略优化

接着是缓存策略的优化。就像超市的商品摆放一样,常用的东西要放在容易取到的地方:

// 服务端缓存配置
app.use(express.static('public', {maxAge: '1y',etag: true,lastModified: true})
)// 浏览器缓存策略
const cacheConfig = {// HTML - 不缓存'/': 'no-cache',// 静态资源 - 长期缓存'/static/': 'public, max-age=31536000, immutable',// API 响应 - 短期缓存'/api/': 'public, max-age=300, stale-while-revalidate=60'
}// 前端数据缓存
function useDataCache(key, fetcher) {const cache = useRef(new Map())const [data, setData] = useState(null)useEffect(() => {if (cache.current.has(key)) {setData(cache.current.get(key))return}fetcher().then(newData => {cache.current.set(key, newData)setData(newData)})}, [key])return data
}

代码执行优化

最后是代码执行效率的优化。就像优化生产流水线一样,我们要让代码运行更高效:

// 使用 Web Worker 处理复杂计算
const worker = new Worker('./calculator.js')function processData(data) {return new Promise((resolve, reject) => {worker.postMessage(data)worker.onmessage = e => resolve(e.data)worker.onerror = reject})
}// 使用 requestAnimationFrame 优化动画
function smoothScroll(target) {const start = window.pageYOffsetconst distance = target - startconst duration = 500let startTime = nullfunction animation(currentTime) {if (!startTime) startTime = currentTimeconst timeElapsed = currentTime - startTimeconst progress = Math.min(timeElapsed / duration, 1)window.scrollTo(0, start + distance * easeInOut(progress))if (timeElapsed < duration) {requestAnimationFrame(animation)}}requestAnimationFrame(animation)
}

效果验证

优化完成后,我们重新进行了性能测试:

  • 首次内容绘制(FCP): 1.2s
  • 最大内容绘制(LCP): 2.1s
  • 首次输入延迟(FID): 80ms
  • 累积布局偏移(CLS): 0.05

所有指标都达到了 Google 推荐的标准。最让我印象深刻的是用户的反馈:"现在打开页面的感觉,就像在用本地应用一样流畅。"

经验总结

性能优化就像是一场精细的手术,需要我们:

仔细诊断 - 通过各种工具找出性能瓶颈精准施治 - 针对具体问题选择合适的优化方案持续监控 - 建立性能监控体系,及时发现问题

写在最后

前端性能优化是一个永无止境的过程,就像园丁修剪花园一样,需要持续的维护和优化。正如那句老话说的:"慢一点,才能快一点。"我们要在开发过程中就注意性能问题,而不是等到问题出现才去解决。

有什么问题欢迎在评论区讨论,让我们一起探讨性能优化的最佳实践!

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

相关文章:

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

"这个页面怎么这么慢啊&#xff1f;" 产品经理小李站在我的工位旁,指着屏幕上的数据大屏抱怨道。我打开 Chrome DevTools 看了一眼,首屏加载时间确实有点吓人 - 足足用了 8 秒。作为一个追求极致体验的前端开发者,这个数字让我坐不住了。 回想起上周的性能检测会议,…...

pdf merge

在 Ubuntu 22.04 上&#xff0c;你可以使用以下命令行工具来合并多个 PDF 文件&#xff1a; 1. pdftk pdftk 是一个强大的 PDF 工具&#xff0c;支持合并、拆分和其他操作。安装和使用方法如下&#xff1a; sudo apt install pdftk pdftk file1.pdf file2.pdf cat output me…...

Python高性能web框架-FastApi教程:(3)路径操作装饰器方法的参数

路径操作装饰器方法的参数 1. 定义带有参数的POST请求路由 app.post(/items,tags[这是items测试接口],summary这是items测试的summary,description这是items测试的description,response_description这是items测试的response_description) def test():return {items: items数据…...

怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev

本文引用怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev 在 vscode 设置项中配置 gopls 的 ui.navigation.importShortcut 为 Definition 即可。 "gopls": {"ui.navigation.importShortcut": "Definition" }ui.navigation.i…...

bean创建源码

去字节面试&#xff0c;直接让人出门左拐&#xff1a;Bean 生命周期都不知道&#xff01; spring启动创建bean流程 下面就接上了 bean生命周期 doGetBean Object sharedInstance this.getSingleton(beanName); sharedInstance this.getSingleton(beanName, new ObjectF…...

axfbinhexelf文件区别

0 Preface/Foreword axf,bin,hex,elf四个都能存在于嵌入式软件领域。 1 文件介绍 嵌入式软件中常见的文件包含&#xff1a; axf&#xff0c;包含调试信息&#xff0c;文件最大。调试信息放在机器码前面。elfhex&#xff0c;包含地址信息&#xff0c;文件内容较大。bin&#x…...

ABAP时间戳与日期时间转换及时区处理

一、时间戳转换为日期时间 1. 基本转换 CONVERT TIME STAMP <fs_back>-lastchangedatetime TIME ZONE sy-zonloINTO DATE DATA(lv_date)TIME DATA(lv_time).2. 解决8小时时差问题的方案 方案1&#xff1a;直接使用UTC时区&#xff08;推荐&#xff09; CONVERT TIME …...

#渗透测试#漏洞挖掘#红蓝攻防#护网#sql注入介绍01

免责声明 本教程仅为合法的教学目的而准备&#xff0c;严禁用于任何形式的违法犯罪活动及其他商业行为&#xff0c;在使用本教程前&#xff0c;您应确保该行为符合当地的法律法规&#xff0c;继续阅读即表示您需自行承担所有操作的后果&#xff0c;如有异议&#xff0c;请立即停…...

Flink是什么?Flink技术介绍

官方参考资料&#xff1a;Apache Flink — Stateful Computations over Data Streams | Apache Flink Flink是一个分布式流处理和批处理计算框架&#xff0c;具有高性能、容错性和灵活性。以下是关于Flink技术的详细介绍&#xff1a; 一、Flink概述 ‌定义‌&#xff1a;Fli…...

DETR-ResNet-50:Facebook的革命性目标检测模型

在计算机视觉领域&#xff0c;DETR&#xff08;DEtection TRansformer&#xff09;模型&#xff0c;由Facebook推出&#xff0c;已成为一项具有革命性的技术。DETR-ResNet-50作为一种结合了Transformer和ResNet-50骨干网络的端到端目标检测模型&#xff0c;凭借其出色的性能和创…...

0002.基于springboot +layui二手物品交易平台

适合初学同学练手项目&#xff0c;部署简单&#xff0c;代码简洁清晰&#xff1b; 注:当前项目架构使用前后端未分离哦&#xff01; 一、系统架构 前端&#xff1a;layui| html 后端&#xff1a;springboot | mybatis-plus 环境&#xff1a;jdk1.8 | mysql | maven 二、代…...

【游戏设计原理】7 - 加德纳的多元智能理论

虽然多元智能理论是对认知方式的分类&#xff0c;但它也可以为游戏设计提供丰富的思路和策略&#xff0c;帮助设计师创建更具吸引力、包容性和多样性的游戏。通过理解不同玩家的认知方式和优势&#xff0c;我们可以更精准地设计游戏的元素和玩法&#xff0c;使其能够吸引广泛的…...

React Image Crop——在React应用中轻松实现图片裁剪功能

React Image Crop是一个用于在React应用程序中裁剪和调整图像的库。它提供了一个简单而强大的界面&#xff0c;允许用户选择和调整裁剪区域&#xff0c;并生成裁剪后的图像。 什么是React Image Crop&#xff1f; React Image Crop是一个开源的React组件&#xff0c;用于在浏览…...

深度对比:Ubuntu 与 CentOS 系统的异同点解析

一、历史背景与发展路线 1.1 Ubuntu 的发展历程 诞生时间&#xff1a;2004 年&#xff0c;由 Canonical 公司发布。定位&#xff1a;致力于成为“用户友好的 Linux”&#xff0c;强调桌面和服务器端的广泛适用性。社区支持&#xff1a;拥有全球最大的开源社区之一&#xff0c…...

操作系统内存管理

内存 内存被设计用来存储数据&#xff0c;以便程序在执行之前能够先被加载到内存中&#xff0c;进而被CPU高效地处理。这一机制有效地缓解了CPU与硬盘之间存在的速度差异和矛盾&#xff0c;确保了数据处理流程的顺畅进行。 一、内存管理 1. 进程运行的基本原理 在深入探讨内…...

数据链路层(Java)(MAC与IP的区别)

以太网协议&#xff1a; "以太⽹" 不是⼀种具体的⽹络, ⽽是⼀种技术标准; 既包含了数据链路层的内容, 也包含了⼀些物理 层的内容. 例如: 规定了⽹络拓扑结构, 访问控制⽅式, 传输速率等; 例如以太⽹中的⽹线必须使⽤双绞线; 传输速率有10M, 100M, 1000M等; 以太…...

图像像素如何排列?是如何存储到diocm里面?读取到内存中是如何存储?

图像像素的排列和存储在DICOM&#xff08;Digital Imaging and Communications in Medicine&#xff0c;医学数字成像和通信&#xff09;文件中遵循特定的标准。DICOM 是一种国际标准&#xff08;ISO 12052&#xff09;&#xff0c;用于处理、存储、打印和传输医学影像信息。 …...

HDR视频技术之七:逆色调映射

HDR 技术近年来发展迅猛&#xff0c;在未来将会成为图像与视频领域的主流。当前 HDR 内容非常短缺&#xff0c;限制了 HDR 视听节目的广泛应用。逆色调映射(Inverse Tone Mapping)应运而生&#xff0c;它是一种用来将 SDR 源信号转换为 HDR 源信号的技术&#xff0c;可以应用于…...

12.10深度学习_经典神经网络_GoogleNet自我理解

为了更清晰地展示 GoogLeNet 中每个卷积层及其相关参数&#xff0c;我们可以将这些信息整理成表格形式。这不仅有助于理解每一层的输入和输出尺寸&#xff0c;还能直观地看到卷积核的数量、大小、步长以及填充方式等关键参数。以下是 GoogLeNet 前几层&#xff08;包括两个卷积…...

漫谈 Vercel Serverless 函数

我们需要明白什么是 Serverless。顾名思义&#xff0c;Serverless 并不是没有服务器&#xff0c;而是 “不需要你管理服务器”。就像你去超市买东西&#xff0c;不用自己去种菜、养鸡&#xff0c;直接挑选、付款就好。Vercel 的 Serverless 函数也是类似的&#xff0c;它帮你自…...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

ubuntu搭建nfs服务centos挂载访问

在Ubuntu上设置NFS服务器 在Ubuntu上&#xff0c;你可以使用apt包管理器来安装NFS服务器。打开终端并运行&#xff1a; sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享&#xff0c;例如/shared&#xff1a; sudo mkdir /shared sud…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

生成 Git SSH 证书

&#x1f511; 1. ​​生成 SSH 密钥对​​ 在终端&#xff08;Windows 使用 Git Bash&#xff0c;Mac/Linux 使用 Terminal&#xff09;执行命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" ​​参数说明​​&#xff1a; -t rsa&#x…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

LabVIEW双光子成像系统技术

双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制&#xff0c;展现出显著的技术优势&#xff1a; 深层组织穿透能力&#xff1a;适用于活体组织深度成像 高分辨率观测性能&#xff1a;满足微观结构的精细研究需求 低光毒性特点&#xff1a;减少对样本的损伤…...