towxml icon indicating copy to clipboard operation
towxml copied to clipboard

反复销毁创建towxml组件出现内存泄露问题

Open jyuuroku16 opened this issue 11 months ago • 2 comments

问题现象

在按需渲染列表情况下,towxml反复销毁重建,出现内存泄露问题

代码片段(因代码片段1M限制,需自行添加towxml)

微信开发者工具代码片段

图示

Image

代码示例

index.wxml-

<!--index.wxml-->
<scroll-view scroll-y show-scrollbar="{{false}}" style="width: 100%; height: 100%;" type="custom">
  <sticky-section>
    <sticky-header>
      <navigation-bar title="ChatKitDemo" back="{{false}}" color="black" background="red"></navigation-bar>
    </sticky-header>
    <!-- <image class="latex" mode="aspectFit" src="http://latex.codecogs.com/gif.latex?r=%5Csqrt%7Bx^2+y^2%7D"></image> -->
    <list-builder type="dynamic" list="{{list}}" childCount="{{list.length}}">
      <view slot:item slot:index id="{{item.id}}" class="cell" style="height: {{index % 2 === 0 ? 'auto' : item.height + 'px'}}; background-color: {{item.color}};">
        <block wx:if="{{index % 2 === 0}}">
          <markdown-item content="{{markdownContent}}" />
          <!-- <rich-text nodes="{{htmlStr}}" /> -->
        </block>
        <block wx:else>
          list item {{index}} 
        </block>
      </view>
    </list-builder>
  </sticky-section>
</scroll-view>

index.wxss

.cell {
  justify-content: center;
  align-items: center;
}

index.ts

// index.ts

import { generateList } from "../../utils/util"

// 获取应用实例
const app = getApp<IAppOption>()

Component({
  properties: {
    htmlStr: {
      type: String,
      value: `<h2>微信小程序 Skyline 渲染引擎</h2>`
},
    markdownContent: {
      type: String,
      value: `## 什么是 Markdown

**Markdown** 是一种方便记忆、书写的纯文本标记语言,用户可以使用这些标记符号以最小的输入代价生成极富表现力的文档:譬如您正在阅读的这份文档。它使用简单的符号标记不同的标题,分割不同的段落,**粗体** 或者 *斜体* 某些文字。

**更多详见** [http://www.markdown.cn/](http://www.markdown.cn/)


## Markdown TodoList

- [ ] 一起去旅行
- [ ] 跟同学聚会
- [x] 晚上十点足球比赛
- [x] 测试用例撰写

## 公式

行内数学公式$x = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}.$ 演示。公式单引号演示\${X}''$。LaTeX是一种基于TeX的文档排版系统,把大片排版的格式细节隐藏在若干样式之后,以内容的逻辑结构统帅纷繁的格式,遂成为现在最流行的科技写作——尤其是数学写作的工具之一。

$$
       \\frac{1}{(\\sqrt{\\phi \\sqrt{5}}-\\phi) e^{\\frac25 \\pi}} =
         1+\\frac{e^{-2\\pi}} {1+\\frac{e^{-4\\pi}} {1+\\frac{e^{-6\\pi}}
          {1+\\frac{e^{-8\\pi}} {1+\\ldots} } } }
$$

$$
    \\left( \\sum_{k=1}^n a_k b_k \\right)^{\\!\\!2} \\leq
     \\left( \\sum_{k=1}^n a_k^2 \\right) \\left( \\sum_{k=1}^n b_k^2 \\right)
$$`,
    },
  },
  data: {
    list: generateList(2000),
    displayContent: '',
  },
  methods: {
    getUserProfile() {
      // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗
      wx.getUserProfile({
        desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
        success: (res) => {
          console.log(res)
        }
      })
    },
    onTap() {
      // 
    },
    onLoad() {
      
    }
  },
})

markdown-item.wxml

<!--components/markdown-item.wxml-->
<towxml nodes="{{article}}" />

markdown-item.ts

// components/markdown-item.ts
const app = getApp<IAppOption>()

Component({

  /**
   * 组件的属性列表
   */
  properties: {
    content: {
      type: String,
      value: '',
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    article: {},
  },

  observers: {
    'content': function(content) {
      if (!content) return;
      
      let obj = app.towxml(content, 'markdown');

      this.setData({
        article: obj
      });
    }
  },

  /**
   * 组件的方法列表
   */
  methods: {
  },
})

jyuuroku16 avatar Mar 07 '25 09:03 jyuuroku16

验证了没有内存泄露的问题

不断的 setData 使用本身就会存在问题的。

微信文档上有说明。 https://developers.weixin.qq.com/miniprogram/dev/framework/performance/tips/runtime_setData.html

你也可以继续做一下尝试

只在第一次的时候解析 markdown ,并将对象保存起来。

之后不断清空再设置已经解析好的对象数据(由于towxml解析库只做了第一次解析,这里的内存数据上涨就不再是towxml导致的,而是微信的渲染机制导致的)。

sbfkcel avatar Mar 11 '25 06:03 sbfkcel

在ws流式返回数据的时候不断调用towxml方法,会引起严重的性能问题,这个问题遇到没呢

waangyong avatar Aug 06 '25 02:08 waangyong