How to get similar behavior between the Garbage Collection of a Single-Page Application and a Multiple-Page Application?

37

I've been doing a lot of research on the web and stackoverflow communities, and I'm getting to the point of believing that SPAs take almost no advantage from the GC algorithm of today's browsers.

Our development team has been concerned with destroying useless objects in state transitions that could be causing some memory-leak, removing listeners, events linked to destroyed DOMs and all the possibilities we find on the internet. But it still has a kind of memory-leak on our SPA platform, which can be used for several hours continuously. The graph below represents the memory usage in 2 hours of SPA navigation:

Itwasajumpfrom40mbto700mbin2hours.Obviously,thereareactuallysomefeatureslikemapsandgraphicsthatjustifyhighmemoryconsumption,butevenreturningtosimplertasks,thememoryremainsthereforalongtimeuntiltheGCcomesandremovesunusedmemory.

IsthereanythingotherthanthethingsIlistedabovethatcanimproveGCinasingle-pageapplication?

WeknowthatGCcannotbecontrolledbytheclient(javascript),althoughtherearesomeeventsthattriggerthiscondition.Someuseractionslike:navigation,pageexchange,closingofwindowsandtabs,amongothers,whichinsomecasesdonothappeninaSPA.

HowcanIgetasatisfactoryresultwithmemorymanagementinaSPAsinceIdonothaveasmany"triggers" for GC activation as in a multi-page application?

    
asked by anonymous 28.04.2017 / 17:41

3 answers

7

(Note: OP's own answer is a great alternative, even better I would say. Check it out!)

Scheduled Refreshes with a Service Worker

It refreshes every 1 hour, and uses a service worker to serve the refresh of the page as fast as lightning. If the page is well implemented, with everything loading in the right order, it will not blink.

As a result, you can start using the service worker to implement an offline experience for your users. = D

To keep data between refreshes you will need to save all relevant user navigation data right before you refresh. In a React application with Redux for example, you could save the JSON of the application state to a sessionstorage , and reload it when the page reloads ... if the key is not there, it's because it's not a scheduled refresh, so was the user who gave refresh even, that is, how to maintain the default behavior of F5.

Unfortunately, I've looked for compatibility, and today (2017-08-03) you'll have to say goodbye to IE, Edge, Safari and Opera Mini.

You also have requirements to use service worker:

  • Does the page have to be served via HTTPS (or is it just the service worker's js? I have to test it)
  • MDN page says FF does not run service worker in anonymous mode

Refreshes in background

Another idea is to try to infer the level of user activity, or the activities that he is doing to find the best time to refresh. For example:

  • prevent refresh if user is typing
  • prevent refresh if text is selected on screen
  • etc.

I could still allow refresh only if the page is not active: window.onfocus and window.onblur .

You can combine this idea with the idea of the service worker too, to speed up the process.

    
04.08.2017 / 02:07
5

Refresh after some programmable trigger.

The big problem with SPA is that it never actually updates the document, changes are made in memory in a virtual way. It is common for programmers to develop codes and not worry about memory dump, and as a consequence can cause memory leaks, such as for example that function performed on a particular's '' hijack '' memory indefinitely.

Although target="_self" is browser default, its main behavior is to open a link in the same window of an iframe with frame or frameset / window. Because frame and frameset k tags are obsolete in HTML5 we no longer use target="_self" for this purpose, it now forces a link to open in a new document in the same window. Forcing the full page load, recreating all instances and all variables.

In SPA this behavior is ignored, and it shows an interesting behavior that is to force the reload when navigating through a link of state or virtual navigation, not sure as to the correct technical terms. Thus, within the current frameworks it is possible to measure the time the SPA navigation is taking place and this will trigger a trigger that will cause the next navigation to occur by renewing the document. Below I've created a simple javascript function that does the target switching under some conditions:

function alteraTarget() {
  var regex = /(^mailto:|^javascript:|#)/g;
  var links = document.querySelectorAll('a');
  var alterados = 0;
  for (var i in links) {
    var a = links[i];
    if (typeof a === "function" || regex.test(a.href) || a.target == "_blank") {
      continue;
    }
    a.target = "_self";
    alterados++
  }
  console.log(alterados, " Links alterados ");
}
<!DOCTYPE html>
<html>

<body>

  <h1>My First Heading</h1>

  <p><a href="mailto:[email protected]"> Não altera </a></p>
  <p><a href="javascript:void(0)"> Não altera </a></p>
  <p><a href="#id-elemento"> Não altera </a></p>
  <p><a href="#"> Não altera </a></p>
  <p><a href="http://google.com" target="_blank"> Não altera </a></p>
  <p><a href="/state"> Altera </a></p>
  <p><a href="!/state2"> Altera </a></p>
  <p><a href="http://google.com"> Altera </a></p>

  <button type="button" onclick="alteraTarget()">Alterar target!</button>
</body>

</html>

The solution is very similar to the one proposed by , and may even be used in conjunction with the ServiceWorker to promote a better user experience, but can be applied in many situations, such as:

Each framework and project should implement a rule, but the way to simulate this update and consequently will clear the memory is with the programmed state updates SPA.

    
04.08.2017 / 15:06
3

Sorry if I seem ignorant of this topic,

But to have a high wear and tear on memory, I think I should also analyze the way all this is being written, I'll give you an example, using var in javascript you create a global scope variable, so will occupy more memory, etc. Well you obviously know this much better than I do. But the point I want to get is: How much memory is being spent to store information in relation to the pages.

I worked with SPA and gnt was always looking to store large information in web storage.

All variables and objects are best handled with es2015 ie using const and let , so it gets stuck by block or function. even if I use var inside a block (the use of 'use stritcs' if I'm not mistaken helps tbm), it starts before all the code block inside the functions. Anyway, take a look if there is too much var and as you save the larger information, and try to put in web storage, BUT I BELIEVE that this is more angular problem than your code. just take a look at the source code and you will see a lot of that I commented up. Anyway if I understood the question well, I think this helps, otherwise, sorry ahahha. Hugs and good luck

    
01.08.2017 / 18:35