We are using JET for an internal application that sees heavy long-term use. Users are regularly using the application over the entirety of their 12 hour shifts. It's also not uncommon for some of the users to have multiple tabs open at that same time to make jumping between screens or sessions easier. What we've been noticing is that the application gradually slows down over the course of a user's shift. The database and REST performance has been stable in all cases we've investigated, but what we often see is the browser (Edge in our case) consuming large amounts of RAM on the user's machine (one example was up to 2GB on fairly mediocre hardware). Closing the browser and reopening the app restores performance to early levels. So, we've narrowed the root cause down to being something within the JET client application.
One thing I've seen is that ojModules (view/viewModel pairs) are being retained in memory, even when the user is not using that screen anymore. Our application has dozens of screens that users will navigate to and from throughout their shift, so these retained modules will add up over time. Many of the screens include tables of search results, so keeping this data between page switches makes sense, but there are cases where we could release the memory. For example, we use a dynamic tab component to allow users to quickly navigate back to a page they've visited already. If they close the dynamic tab, we can assume that they are done with it and release all of the memory allocated to it.
My initial thought was to use requirejs.undef() to undefine the associated RequireJS module, as that appeared to be what was holding the module in memory. Unfortunately, this has actually caused an even greater memory leak issue. It did correctly remove the RequireJS reference to the JavaScript module, but there were other references pointing to that module, so it was not getting GC'd. When navigating back to the page, RequireJS is creating another instance of the viewModel because it doesn't see one defined.
One time visiting the page:
Three times visiting the page:
One other thing I noticed regarding memory usage is that it appears as though the total Memory used by our application increases every time the page is refreshed (though the JS Heap doesn't seem to change much). Here's the usage on first load:
After one refresh (doing nothing else):
After the fifth refresh:
Does anyone out there have experience troubleshooting memory leak issues like those described above? Any hints or tips on what stuff we should be looking at to resolve this? I've been attempting to use the DevTools Memory tab to resolve memory leaks in the JS Heap space, but I'm having trouble deciphering the data and identify the causes.