修改后的 Demo 地址:demo2 复现步骤同上。 当通过 template 的方式使用自定义组件时,会存在内存泄露的情况。
自定义组件没有被销毁,导致存在内存泄露的情况?Demo 地址 问题描述 自定义组件实例没有被销毁,如果给组件的 properties 传递了大量数据(Demo 中是 500k),将快速占用内存。 复现步骤 1.打开 Demo,然后打开开发者工具的 Memory 面板,录取内存快照,关注构造函数:l。 [图片] 2.点击 Click 按钮 10 次(相当于渲染、隐藏自定义组件 foo 5 次),然后点击强制垃圾回收按钮,接着再次录取内存快照。 3.选中快照 Snapshot2,filter 设置为:Objects allocated between Snapshot1 and Snapshot2,并筛选构造函数:l。这时可以观察到内存占用大幅上升,其中新增的 5 个对象 l 引用了 32% 的内存。 [图片] 4.展开其中一个 l 对象,可以观察到其 __methodCaller 属性引用的是一个自定义组件实例,从而判断 l 对象跟自定义组件有关。再观察 l 对象中内存占比较大的字段分别是 __vtObj 与 __innerData,它们都分别引用着父组件传入的 json 属性(500k 大数据)。( l 对象的 Retainers 是一些循环引用或内部代码,很难再往下追查) [图片] 5.右键点击 l 对象,选择 Store as a global variable,把 l 对象放到控制台进行观察,发现 __vtObj 与 __innerData 属性引用的是独立的 json 对象。 [图片] 6.综上,推测自定义组件实例没有被销毁,如果给自定义组件的 properties 传递了大型数据,会导致内存泄露问题更明显。 环境信息 基础库:2.32.2复现环境:微信开发者工具(真机调试不支持堆栈 snapshot)
2023-07-31同遇到,有什么进展吗
微信小程序组件中循环输出ID会出现奇怪的前缀,什么情况?[图片]
2022-05-01这还不详细?看不到代码?
transitionend 事件不能冒泡?文档说 transitionend 事件可以冒泡,但实际测试不能冒泡: [图片] 例子: Page({ data: { offset: 20 }, handleParent () { console.log("index ote") }, handleChild () { console.log("ote") }, handleClick () { console.log("onClick offset") this.setData({ offset: this.data.offset === 20 ? 30 : 20 }) } }) <view bindtransitionend="handleParent"> <view style="transform: translate3d(0, {{offset}}px, 0);transition: transform 100ms" bindtap="handleClick" bindtransitionend="handleChild" > 点击一下 </view> </view> 运行结果: [图片]
2022-05-01官方有关注这个问题吗?
按路径更新的方式 setData,导致带 key 的列表渲染出错- 当前 Bug 的表现(可附上截图) 第一次点击按钮,list 渲染正常。dom 结构为: [图片] 第二次点击按钮,list 渲染错误。dom 结构为: [图片] - 预期表现 第二次点击按钮后,data-x 的值应该从上往下分别为 0~6,但此时却仍然是第一次渲染 list 时的 data-x。 证明这种情况下,按路径的方式 setData 时,列表属性值没有更新。 - 复现路径 1. 点击一次按钮,观察列表的 dom。 2. 第二次点击按钮,再观察列表 dom 的 data-x。 - 提供一个最简复现 Demo index.js [代码]Component({[代码][代码] [代码][代码]data: {[代码][代码] [代码][代码]list: [],[代码][代码] [代码][代码]i: 0[代码][代码] [代码][代码]},[代码][代码] [代码][代码]methods: {[代码][代码] [代码][代码]onButtonClick() {[代码][代码] [代码][代码]if[代码] [代码]([代码][代码]this[代码][代码].data.i === 0) {[代码][代码] [代码][代码]this[代码][代码].setData({[代码][代码] [代码][代码]'list[0]'[代码][代码]: { idx: [代码][代码]"0"[代码][代码], str: [代码][代码]"back off"[代码] [代码]},[代码][代码] [代码][代码]'list[1]'[代码][代码]: { idx: [代码][代码]"1"[代码][代码], str: [代码][代码]"now"[代码] [代码]},[代码][代码] [代码][代码]'list[2]'[代码][代码]: { idx: [代码][代码]"2"[代码][代码], str: [代码][代码]"point"[代码] [代码]},[代码][代码] [代码][代码]'list[3]'[代码][代码]: { idx: [代码][代码]"3"[代码][代码], str: [代码][代码]"simple"[代码] [代码]},[代码][代码] [代码][代码]'list[4]'[代码][代码]: { idx: [代码][代码]"4"[代码][代码], str: [代码][代码]"total"[代码] [代码]},[代码][代码] [代码][代码]'list[5]'[代码][代码]: { idx: [代码][代码]"5"[代码][代码], str: [代码][代码]"pity"[代码] [代码]},[代码][代码] [代码][代码]'list[6]'[代码][代码]: { idx: [代码][代码]"6"[代码][代码], str: [代码][代码]"name"[代码] [代码]},[代码][代码] [代码][代码]i: 1[代码][代码] [代码][代码]})[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]if[代码] [代码]([代码][代码]this[代码][代码].data.i === 1) {[代码][代码] [代码][代码]this[代码][代码].setData({[代码][代码] [代码][代码]'list[0].str'[代码][代码]: [代码][代码]"point"[代码][代码],[代码][代码] [代码][代码]'list[1].str'[代码][代码]: [代码][代码]"back off"[代码][代码],[代码][代码] [代码][代码]'list[2].str'[代码][代码]: [代码][代码]"simple"[代码][代码],[代码][代码] [代码][代码]'list[3].str'[代码][代码]: [代码][代码]"pity"[代码][代码],[代码][代码] [代码][代码]'list[4].str'[代码][代码]: [代码][代码]"name"[代码][代码],[代码][代码] [代码][代码]'list[5].str'[代码][代码]: [代码][代码]"total"[代码][代码],[代码][代码] [代码][代码]'list[6].str'[代码][代码]: [代码][代码]"now"[代码][代码],[代码][代码] [代码][代码]i: 2[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码][代码] [代码][代码]},[代码][代码] [代码][代码]anonymousFunc0(e) {[代码][代码] [代码][代码]console.log([代码][代码]'e: '[代码][代码], e.target.dataset.x)[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码][代码]})[代码] index.wxml [代码]<[代码][代码]block[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]button[代码] [代码]bindtap[代码][代码]=[代码][代码]"onButtonClick"[代码][代码]>Generate random items</[代码][代码]button[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]wx:key[代码][代码]=[代码][代码]"str"[代码] [代码]bindtap[代码][代码]=[代码][代码]"anonymousFunc0"[代码] [代码]wx:for[代码][代码]=[代码][代码]"{{list}}"[代码] [代码]data-x[代码][代码]=[代码][代码]"{{item.idx}}"[代码][代码]>{{item.str}}</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]</[代码][代码]view[代码][代码]>[代码][代码]</[代码][代码]block[代码][代码]>[代码]
2019-06-14