Back to Blog

我们怎么把拼团页的 setData 卡顿从1.2s压到120ms

2026/10/142 min read
我们怎么把拼团页的 setData 卡顿从1.2s压到120ms

我们怎么把拼团页的 setData 卡顿从1.2s压到120ms

去年给客户做拼团页,上线第三天崩溃率突然涨到17%,查了两天才发现是 setData 里写了 for 循环。

性能优化:setData 与长列表

性能问题总是最隐蔽。小程序架构是逻辑层和视图层分离的,每次 setData 都要走一遍 JSON 序列化,开销很大。

小程序开发避坑 - 插图 1

那个拼团页的问题出在商品详情页。用户快速滑动时,页面卡得不行。用开发者工具的 Performance 面板一抓,发现滚动事件触发了全量数据更新,主线程被频繁阻塞,UI 渲染严重滞后。

怎么修?三点措施:只更新必要字段(比如 this.setData({'list[0].name': 'newName'})),别全量替换;大量数据用分片加载或虚拟列表,别一次性塞进去;touchmove 这类高频事件必须节流,不能每帧都 setData。

后来引入了虚拟列表。实测滚动1000条商品时,内存峰值从120MB压到30MB,首屏渲染快了一倍多。

样式陷阱:rpx 与布局

小程序样式和 Web 不太一样,坑不少。

我之前做个支付表单,在不同真机上宽度和间距全部错位。排查很久才发现,布局里混用了 px 和 rpx,且样式嵌套过深。rpx 是按屏幕宽度换算的,不同分辨率设备表现会有差异,累积起来就炸了。

教训是:主要布局统一用 rpx;嵌套层级别超过三层;利用 page 或 component 选择器隔离样式。另外,border-box 模型虽然默认开启,但在老机型上可能有问题,重置样式时最好显式写上 box-sizing: border-box。

组件封装

组件封装不好,后期维护要命。

我封装通用表单组件时总结了三条原则:properties 要加 validate 校验,传 number 进来直接 console.warn 并 fallback;内部状态变更通过统一接口暴露,别让父组件直接操作子组件数据;父子组件别循环引用,否则容易加载死锁。

// components/my-component/index.js
Component({
  properties: {
    value: {
      type: String,
      value: '',
      observer: 'onValueChange'
    }
  },
  data: {
    internalValue: ''
  },
  methods: {
    onValueChange(newVal) {
      this.setData({ internalValue: newVal });
    },
    handleChange(e) {
      const { value } = e.detail;
      this.setData({ value });
      this.triggerEvent('change', { value });
    }
  }
});

排查技巧

遇到奇怪问题,我的排查顺序:先看开发者工具内存占用和 WXML 节点数,定位泄漏或膨胀;再看网络请求时序,避免重复请求;最后检查生命周期,确认 onLoad、onShow 里有没有资源没释放。

记得有一次页面切换卡顿,内存分析显示有泄漏。最终定位到一个异步回调里的 setTimeout 没清理,对象没法被垃圾回收。现在看到 setTimeout 就手抖。

原文出处

本文首发于 我们怎么把拼团页的 setData 卡顿从1.2s压到120ms — https://lyxq.com.cn/en/blog/miniprogram-development-pitfalls-guide

转载或引用请注明出处,商业使用请联系作者获得授权。