The issue of memory leakage with ng-grid and real-time data

My intention is to utilize ng-grid for visualizing high-frequency real-time data, but I am encountering issues with a memory leak. Interestingly, the memory leak does not occur when I opt for a simple HTML table with ng-repeat.

My tech stack includes node+express on the backend and AngularJS on the client side. For streaming real-time data from the server to a client-side table, I make use of socket.io.

To illustrate the memory problem, consider this simplified example:

I am sending 1500 messages per second, each message formatted as follows: {id: 1, name: “name”, time: “[current date/time string]”} After 4 minutes, the browser memory exceeds 400MiB, reaching over 1GiB after 10 minutes.

Testing has been conducted on Chrome and Firefox.

Below is the simplified example. Is there something incorrect in my approach? (Additional details provided at the end).

Server

var app = express();
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
io.of('/test').on('connection',  function (socket) {

    console.log('socket connection: /test');

    for (id=1; id<16; id++) {
        streamData(id);
    }

    function streamData(id) {
      setInterval(function () {
        socket.emit('updateData', {
            id: id, 
            name: "test"+id, 
            time: (new Date()).toString()
        });
      }, 10);
    }
});

Service using angular-socket-io

factory('testSocket', function(socketFactory) {
    return socketFactory({
        ioSocket:  io.connect('http://localhost/test')
    });
})

Controller

controller('NgGridTestCtrl', function ($scope, testSocket) {     
  var itemsObj = {};
  $scope.items = [];
  $scope.gridOptions = { 
      data: 'items',
      columnDefs: [{field:'id', displayName:'ID', width:'15%'}, 
                   {field:'name', displayName:'Name', width:'20%'},
                   {field:'time', displayName:'Date and Time', width:'65%'}],
      enableColumnResize: true    
  };

  testSocket.on('updateData', function(data) {
      itemsObj[data.id] = data;
      var values = [];
      angular.forEach(itemsObj, function(value, index) {
          this.push(value);
      }, values);

      // Data for ng-grid
      $scope.items = values;
  });

});

ngGrid Template

<div>
   <h1>ng-grid Table</h1>
   <div class="gridStyle" ng-grid="gridOptions"></div>   
</div>

Edited to include Plain Table Example

Using a plain table resolves the memory issue - the browser memory remains around 155MiB.

Controller

  controller('SimpleTableCtrl', function ($scope, testSocket) {
     $scope.items = {};
      testSocket.on('updateData', function(data) {
          $scope.items[data.id] = data;
      });      
  }).

Plain Table Template

<div>
  <h1>Simple Table with ng-repeat</h1>
  <table class="table">
    <thead>
      <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Time</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="item in items">
        <td>{{item.id}}</td>
        <td>{{item.name}}</td>
        <td>{{item.time}}</td>
      </tr>
    </tbody>
  </table>

Additional Observations

  1. The memory issue extends beyond ng-grid, also arising with the "NgGridTestCtrl" controller using the "plain table template" with ng-repeat.
  2. The problem does not surface (with ng-grid template and NgGridTestCtrl) if the data frequency is lower (500 milliseconds instead of 10 milliseconds interval in the streamData function).
  3. The memory problem persists (with plain table template and NgGridCtrl), even when lowering the data frequency (500 milliseconds instead of 10 milliseconds interval in the streamData function). The memory growth rate simply slows down, as expected.
  4. No memory problems are encountered with higher frequency data when utilizing the "SimpleTableCtrl" with "plain table template".
  5. I have yet to determine if ng-grid can effectively handle high-frequency data. Any insights on ng-grid's performance under such conditions?

Answer №1

Hey there! To address the memory leak issue, it's crucial to first identify where it originated from. One helpful tool for this task is "Heap Allocation" in Chrome:

Simply navigate to F12 -> Profiles -> Record Heap Allocation.

For more detailed information, check out this resource:

Object allocation tracking

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for Accessing a New Website Using the Floating Layer Close Button

How can I trigger the opening of a new browser window when a visitor clicks the close "x" on my floating layer ad? The close button is within an HTML link code ("a href"), but simply putting a URL in there does not seem to work. <script language=" ...

Printing Multiple Pages Using JavaScript and Cascading Style Sheets

Encountering difficulties displaying page numbers when printing multiple multipage reports Here is the provided HTML Format : <style type="text/css> body { counter-reset: report 1 page 0; } td.footer:after { counter-increment: page; content ...

Unlock the power of TypeScript's inheritance by utilizing static methods for type

In my TypeScript project, I have two classes: BaseModel and HotelModel. The HotelModel extends the BaseModel class, which provides static methods like findById, all, etc. export default class BaseModel { private collection:string _id:string | undefine ...

From AngularJS to Spring Framework Controller

I'm relatively new to working with angularjs. Currently, I have a checkbox in one of my views <input id="{{fields[3].name}}" type="checkbox" value="{{fields[3].name}}" ng-checked="selection.indexOf(fields[3].name) > -1" ng-click="toggleSelecti ...

React issue: parent state becoming unresponsive when updating during input onChange event

I am currently working on a large form that consists of at least 50 input fields. I have developed a function within the form component to store the input values in the form's state: PARENT FUNCTION saveToState(details) { const { company } = thi ...

What is the most stylish method for merging a removeCartItem function with an addCartItem function?

Is there a way to combine these functions into a more concise and elegant piece of code? While the current setup works fine, it feels redundant to have two large functions that essentially do the same thing. const modifyCartItem = (cartItems, productToMo ...

Exploring the possibility of detecting page scrolling in Javascript by clicking on scroll bars

I have implemented a unique feature on my page that allows users to scroll up and down using custom buttons I created. This functionality is achieved by smoothly transitioning between anchor points on the page using jQuery's animate function. However ...

Having issues with my AngularJS application not updating as expected

After creating a custom service to store all search parameters, I can easily access them from any part of my code. This ensures that the search parameters are always accurate. Below is the definition of the custom service: App.factory('filterService& ...

Tips for updating property values when calling a TypeScript function

Hello everyone, I am looking to convert a snippet of JavaScript code into TypeScript. JavaScript function newState(name){ var state ={ name : name, age : 0 } return state } function initStates() { this.JamesStat ...

Tips for retrieving values from numerous checkboxes sharing the same class using jQuery

Currently, I am struggling with getting the values of all checkboxes that are checked using jquery. My goal is to store these values in an array, but I am encountering difficulties. Can anyone provide me with guidance on how to achieve this? Below is what ...

Apply CSS styles when the text exceeds the size of the textbox

Is there a way to create a textbox that scrolls on hover only if the text is longer than the textbox itself? Check out my attempt here: https://jsfiddle.net/SynapticError/wqh4ts3n/35/ The text should scroll on hover if it's longer than the textbox. ...

Using Angular 8, remember to not only create a model but also to properly set it

hello Here is a sample of the model I am working with: export interface SiteSetting { postSetting: PostSetting; } export interface PostSetting { showDataRecordAfterSomeDay: number; } I am trying to populate this model in a component and set it ...

Handling Errors in Asynchronous Functions with JavaScriptLet's explore the best practices for

I am a beginner in javascript and recently delved into async/await. After going through various resources, I gained a basic understanding. However, while experimenting with some code examples, I encountered unexpected results which left me puzzled about wh ...

Firebase Error: Page Not Found

I recently set up an Angular2 application and added Firebase using npm. I successfully imported it into my app.component.ts without any errors showing up in my text editor. The package.json file also indicates that Firebase is installed correctly. However ...

What is the process for linking an HTML document to another HTML document within a div using jQuery?

Check out my HTML code: <!DOCTYPE html> <html> <head> <title>Hilarious Jokes!</title> <meta charset="utf-8"> <link href="final%20project.css" rel="stylesheet"> <script src=" ...

Assistance Required for Making a Delicious Cookie

Within my interface, there are two buttons displayed - one is labeled yes while the other is called no. <input type="button" name="yes" onclick="button()"> <input type="button" name="no"> In order to enhance user experience, I am looking to i ...

Looking to incorporate CGST and SGST into the Subtotal using JQuery?

I have come across this particular HTML Code in an Invoice: <tr> <td colspan="3" class="blank"></td> <td colspan="2" class="total-line">Subtotal Rs.</td> <td td class="t ...

Extracting HTML elements between tags in Node.js is a common task faced

Imagine a scenario where I have a website with the following structured HTML source code: <html> <head> .... <table id="xxx"> <tr> .. </table> I have managed to remove all the HTML tags using a library. Can you suggest w ...

Prevent users from deleting options in Autocomplete by disabling the backspace key

I am currently working on implementing the Autocomplete component from Material-Ui library to allow users to select multiple options, but I want to restrict them from directly removing any of those options. One issue I've encountered is that users ca ...

Tips for shuffling the sequence of EJS variables

I am currently working on creating a quiz that consists of multiple choice questions. In order to display the Question, Correct Answer, and 3 other wrong options, I am utilizing EJS variables. The format will be similar to the following example: Question: ...