4

I am having the following observable arrays in my view model:

  VM.ListingData([]);
  VM.ResumeListingData([]); 

ListingData will hold 20 columns x 100 rows of parsed JSON object. I am binding a grid using ResumeListingData in the following way in the AJAX success method:

// To initially bind 10 records
R1ViewModel.ResumeListingData([]);
R1ViewModel.ListingData([]);
R1ViewModel.ListingData(JSON.parse(data.ResumeListing));//data.ResumeListing contains the JSON string returned from server through the ajax request
$.each(R1ViewModel.listingData(), function (index, item) {
                        if (index < 10) {
                            R1ViewModel.ResumeListingData.push(item);
                            return true;
                        }
                        return false;
                    });

Then I am calling the following bindNextItems function at the end of AJAX success:

// To bind rest of the items
       bindNextItems: function () {
            VM.SetIntervalRef(setInterval(function () {
                VM.ResumeListingData.push(VM.ListingData()[VM.SetIntervalCount()]);
                VM.SetIntervalCount(VM.SetIntervalCount() + 1);
                if ($('#rightTable tr').length == VM.listingData().length) {
                    clearInterval(VM.SetIntervalRef());
                }                    
            }, 1));
        }

Now when I load the page for the first time and when I check browser memory usage in windows task manager it is around 250MB(tested in firefox). As I do some actions like searching, paging, filter, sorting etc on each of these actions 100 rows are returned from server, the memory usage of browser grows steadily and during my testing it reached up to 950MB of memory usage. I am not using any computed observables or using a manual subscription with both ResumeListingData and ListingData observable arrays. Just clearing them both using [] and assigning values in the above mentioned way when any action is performed.

Where can be the issue? I have faced this problem for the first time so are there any tools to monitor browser memory?

I am using setInterval to bind 100 rows with a delay so that the browser doesn't hang when binding the table. Is there any alternate better way to do this? Any other performance optimized way to push items into an observable array?

seadrag0n
  • 848
  • 1
  • 16
  • 40
  • It doesn't sound like an issue specifically with the observableArray to me but an issue with referencing each one of the objects somewhere that is preventing the garbage collection from getting the items out of memory. I could be wrong but my thought is you are probably keeping a referencing either in your view model or in the DOM to the objects that were previously contained in the observableArray and therefore those references are never being removed. Usually a subscriber or computed like you mentioned is the culprit if it is never disposed of properly, but there are certainly other ways. – PW Kad Oct 28 '14 at 15:22
  • Are you using a grid plugin ( like koGrid ) or are you building the DOM manually ( ie using foreach ) ? – Robert Slaney Oct 31 '14 at 03:16
  • I don't know about FF but Chrome's javascript profiler can tell you what a javascript object's GC root is – Robert Slaney Oct 31 '14 at 03:19
  • @RobertSlaney I am using native `Knockout` `foreach` binding – seadrag0n Oct 31 '14 at 10:10
  • Which version of KnockoutJS are you using? It may be worth checking the [KnockoutJS changelog](https://github.com/knockout/knockout/releases), as there have been a couple of memory leak fixes (at least one of which relates to `foreach` / `template` binding, which may be related). – Conan Feb 12 '17 at 11:44
  • AFAIK on every setInterval run the observableArray changes and the view will be redrawed, so this might even be less performant to initialy wait to draw all rows, also you will have all rows in two observableArrays which doubles the payload, you might be better of with limiting and paging your results or just show some loading-indicator while "browser hangs" – john Smith Oct 24 '19 at 06:39
  • Also i think, there might be an issue that when you push an object from vm. ListingData to vm.ResumeListingData it still references the object in vm.ListingData which may lead to unperformant observable – john Smith Oct 24 '19 at 06:42
  • so maybe try to completely ommit the vm.ListingData , use a "normal" variable to store the parsed JSON and iterate over it instead of observableArray – john Smith Oct 24 '19 at 06:47

0 Answers0