2026/2/8 0:08:45
网站建设
项目流程
我请网络公司做的网站上的图片被当广告拦截了_怎么回事,代备案网站,机加工接单什么平台好,网站建设合同属于什么印花税最近在做一个堆叠式卡片列表#xff08;Stack Card List#xff09;。效果是挺好看的#xff0c;卡片层层堆叠#xff0c;吸顶效果也很丝滑。但是#xff0c;当数据量一上来#xff08;比如超过 100 条#xff09;#xff0c;就开始掉帧。在我的测试机上#xff0c;滑…最近在做一个堆叠式卡片列表Stack Card List。效果是挺好看的卡片层层堆叠吸顶效果也很丝滑。但是当数据量一上来比如超过 100 条就开始掉帧。在我的测试机上滑动起来会有一点明显的卡顿DevTools 里的火焰图也是特别是光栅线程绝大部分耗时超过了最低标准16ms很多。经过一顿排查和优化成功把 RasterGPU耗时从16ms降到了4ms左右实现了60fps/120fps满帧运行。现在来复盘一下我是如何一步步“拯救”这个页面的。第一个问题是为什么会卡首先我的布局不是普通的 ListView而是为了实现堆叠视差效果用 Stack Positioned for循环手写出来的。通过 Flutter DevTools 分析我发现了几个首要目标逻辑层全量渲染。原因是Stack 不像 ListView 自带懒加载Recycling。如果我有 100 条数据它就会傻傻地把 100 个 Widget 全部创建并绘制出来哪怕底下的 90 个都被压住看不见导致了极大的没有必要的性能消耗。渲染层GPU 也就是 Raster 线程爆炸。一开始因为要先赶完成度导致对与渲染性能没有太在意每一张卡片都加了BoxShadow高斯模糊。当多张卡片叠在一起GPU 就要对这块区域的像素重复计算多次模糊卷积直接算崩了。图层层Layer 太多。为了优化重绘我之前给每个卡片包了 RepaintBoundary结果导致图层过多合成开销反而变大了。第一步逻辑层优化 —— 手动实现“滑动窗口”既然 Stack 不会自动回收不可见的元素那我就手动编写修改为只画看得到的部分避免全部渲染出来导致性能浪费。修改前循环遍历所有数据生成 Widget。GPU 实际上在画整个长列表哪怕它们被堆叠在最底下。修改后引入了一个滑动窗口的概念。在 for 循环里加了两个判断关卡剔除顶部算出当前滚动位置大约对应第几个卡片。如果某个卡片被压在堆叠深处比如第 0-10 个直接 continue 跳过不渲染。限制数量设置一个 maxRealRenderCount比如 10。屏幕上最多只允许出现 10 个卡片超出的直接 break。// 伪代码逻辑 for (int i 0; i tasks.length; i) { // 1. 如果被压在最底下看不见 - 跳过 if (visualIndex firstRenderIndex) continue; // 2. 如果屏幕上已经画了够多了 - 停止 if (renderedCount 10) break; // ... 正常的渲染逻辑 }效果无论数据源有 100 条还是 1000 条系统永远只处理10 个Widget。性能复杂度从 O(N) 降到了 O(1)。第二步渲染层优化 —— LOD (细节层次) 阴影降级这是对 GPU 减负最大的一步。修改前所有卡片无论是否选中都带着 blurRadius: 20 的高斯模糊。需要注意的是Blur 是性能杀手计算量是指教级增长的。修改后我采用了一种LOD (Level of Detail)策略选中态保持设计稿的高质量阴影怎么华丽怎么来。列表态彻底关掉模糊(blurRadius: 0)改用 spreadRadius扩散或者 1.0 的微模糊来模拟阴影。boxShadow: [ if (isSelected) // 选中时奢华模糊 BoxShadow(color: Colors.black26, blurRadius: 25, offset: Offset(0, 10)) else // 列表时极速模式 (几乎0成本) BoxShadow(color: Colors.black12, blurRadius: 1.0, spreadRadius: 0) ]效果Raster 线程耗时瞬间从红色变回了蓝色。因为对于 GPU 来说画硬边矩形比画高斯模糊快了几百倍。第三步图层与构建优化这一步的目的是把 CPU 和显存的开销也降下来。移除 RepaintBoundary之前给每个 Item 包这个是为了隔离重绘但在整体滚动的列表中这导致了显存碎片化。去掉后整个列表合并为一个大图层GPU 合成更轻松。优化 AnimatedContainer卡片有缩放动画。为了防止动画过程中文字内容反复 Rebuild我把内容提取出来作为 child 传给 AnimatedContainer。原理Flutter 发现 child 引用没变就会复用之前的布局只重画背景色和形状。这让 UI 线程CPU几乎不耗时。最终成果经过这几步的优化逻辑上剔除了 90% 的无效渲染。图形上降低了 99% 的像素计算量。结构上减少了图层和 Widget 重建。结果UI 线程耗时 2msRaster 线程耗时 5ms帧率稳稳的 60fps / 120fps下面是优化前后的火焰图对比优化前优化后最近也是刚开始接触性能优化这方面主要是新来的Ui设计师喜欢使用大量的高斯模糊、圆角阴影这些性能杀手被逼无奈欢迎各位大佬提意见合适的会积极采纳的。