You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 9应用处理MQTT消息运行5分钟后页面无响应如何解决?

问题核心根因

你代码中存在两个核心逻辑缺陷直接导致长时间运行卡顿:

  1. series数组初始化后固定为5个元素,你全程仅修改已有元素的name/value属性,永远不会触发series.length>50的判断,旧数据清理逻辑完全失效
  2. 每次收到MQTT消息都全量拷贝multi数组触发ngx-charts全量重绘,若MQTT推送频率高(比如每秒多次),会持续触发Angular全局变更检测,同时matTable也会伴随每次变更检测全量重绘,运行时间越长性能损耗越严重

优化方案

1. 修复数据更新逻辑,减少不必要的重绘

ngx-charts采用OnPush变更检测策略,仅当数据引用变更时才会重绘,无需每次全量拷贝整个multi数组,仅更新修改后的系列引用即可:

bindView(currentSecond: number, data) {
    // 原有按秒区间更新series元素的逻辑保持不变
    if (currentSecond <= 12) {
        this.multi[0].series[0].name = 5;
        this.multi[0].series[0].value += data.rx;
        this.multi[1].series[0].name = 5;
        this.multi[1].series[0].value += data.tx;
    } else if (currentSecond > 12 && currentSecond <= 24) {
        this.multi[0].series[1].name = 10;
        this.multi[0].series[1].value += data.rx;
        this.multi[1].series[1].name = 10;
        this.multi[1].series[1].value += data.tx;
    } else if (currentSecond > 24 && currentSecond <= 36) {
        this.multi[0].series[2].name = 15;
        this.multi[0].series[2].value += data.rx;
        this.multi[1].series[2].name = 15;
        this.multi[1].series[2].value += data.tx;
    } else if (currentSecond > 36 && currentSecond <= 48) {
        this.multi[0].series[3].name = 20;
        this.multi[0].series[3].value += data.rx;
        this.multi[1].series[3].name = 20;
        this.multi[1].series[3].value += data.tx;
    } else if (currentSecond > 48 && currentSecond <= 60) {
        this.multi[0].series[4].name = 25;
        this.multi[0].series[4].value += data.rx;
        this.multi[1].series[4].name = 25;
        this.multi[1].series[4].value += data.tx;
    }
    // 仅更新修改后的series引用,避免全量重绘
    this.multi[0] = {
        ...this.multi[0],
        series: [...this.multi[0].series]
    };
    this.multi[1] = {
        ...this.multi[1],
        series: [...this.multi[1].series]
    };
    this.multi = [...this.multi];
    // 若你确实需要累积更多数据点,修改长度判断阈值为适配你业务的数值,比如>10就清理旧数据
    // if (this.multi[0].series.length > 10) {
    //     this.multi[0].series.splice(0, 5);
    //     this.multi[1].series.splice(0, 5);
    // }
}

2. 限流MQTT消息处理频率

用RxJS操作符限制消息处理频率,避免高频推送导致频繁重绘,比如设置每秒最多处理1次消息:

import { throttleTime } from 'rxjs/operators';

subscribingToMQTT() {
    // 先清理已存在的订阅,避免重复订阅
    if (this._mqttSubscriber) {
        this._mqttSubscriber.unsubscribe();
    }
    this._mqttSubscriber = this.mqttService
        .observe(`myTopic`)
        .pipe(throttleTime(1000)) // 1000ms即1秒,可根据业务需要调整
        .subscribe(
            (jsonLiveData: IMqttMessage) => {
                let _data = jsonLiveData.payload.toString();
                // 生产环境移除console打印,避免日志累积占用内存
                // console.log('Live Data: ', _data);
                this.JSONLiveData = this.IsJsonString(`[${_data}]`);
                this.bindTxRxData(this.JSONLiveData[0]);
            },
            (error) => {
                console.log('Something went wrong while fetching live data from MQTT');
            }
        );
}

3. 优化Angular变更检测

给当前组件添加OnPush变更检测策略,减少不必要的全局变更检测触发:

import { ChangeDetectionStrategy, Component } from '@angular/core';

@Component({
    selector: 'your-component-selector',
    templateUrl: './your-component.component.html',
    styleUrls: ['./your-component.component.css'],
    changeDetection: ChangeDetectionStrategy.OnPush // 新增这行
})

同时给matTable添加trackBy函数,避免每次数据变更全量重绘所有表格行:

<!-- matTable 增加trackBy配置 -->
<table mat-table [dataSource]="dataSource" [trackBy]="trackByIndex">
  <!-- 列定义保持不变 -->
</table>
// component.ts 新增trackBy方法
trackByIndex(index: number) {
    return index;
}

如果matTable的数据是持续累积的,也要添加长度限制,比如仅保留最近100条记录,超过则删除最旧的条目,避免表格行数无限增长。

4. 优化ngx-charts渲染配置

关闭不必要的动画,减少渲染开销:

<ngx-charts-line-chart [scheme]="colorScheme" [legend]="legend"[results]="multi"
   [gradient]="gradient" [xAxis]="showXAxis" [yAxis]="showYAxis" [legend]="showLegend"
   [legendTitle]="title" [showXAxisLabel]="showXAxisLabel"
   [showYAxisLabel]="showYAxisLabel" [xAxisLabel]="xAxisLabel" [yAxisLabel]="yAxisLabel"
   [autoScale]="autoScale" [animations]="false"> <!-- 关闭动画 -->
</ngx-charts-line-chart>

内容的提问来源于stack exchange,提问作者naksh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 15:09:00