ASP.NET MVC 3 Single-Page Application Using Javascript / jQuery AJAX: Memory Issues and Separate DOMs

I recently created a single-page ASP.NET MVC 3 with JS / jQuery UI (on top of an HTML view), the general idea of ​​working with Javascript is given below. I encounter problems with GC that do not free memory and leave a large number of elements (24,000 for the largest form, 15-20k and 1k depending on which form is loaded / unloaded) in the Detached DOM (can be viewed in the Chrome developer tools Heap Profiler).

var MainApp = function () { var meBase = this; this.activeObject = undefined; this.someFunc = function (val1, val2, etc) { //Some operation here } this.GetView(x, y, z) { if (meBase.activeObject != null) { meBase.BustActive(x, y, z); } else { if (condition) { //Load static html via $.get } else { switch (activeObjectSelector) { case CASEHERE: self.activeObject = new SomeObject(); self.activeObject.BeginInit(); break; case ..... } } } } this.BustActive = function (x, y, z) { if (meBase.activeObject.Destroy()) { meBase.activeObject = null; meBase.GetView(x, y, z); } } } var SomeObject = function () { var meBase = this; this.Bindings = []; this.Container = "#somecontainer"; //Some Properties this.Unbind = function () { $("#Somecontainer .bound").each(function () { if ($(this)["click"] && $.isFunction($(this)["click"])) { $(this).unbind('click'); } if ($(this)["blur"] && $.isFunction($(this)["blur"])) { $(this).unbind('blur'); } if ($(this)["change"] && $.isFunction($(this)["change"])) { $(this).unbind('change'); } if ($(this)["mouseenter"] && $.isFunction($(this)["mouseenter"])) { $(this).unbind('mouseenter'); } if ($(this)["mouseleave"] && $.isFunction($(this)["mouseleave"])) { $(this).unbind('mouseleave'); } }); //iterate through meBase.Bindings to remove any 'special' bindings such as 'live/die' } this.MapEvents = function () { //For Example $("#Somecontainer #element").click(meBase.SomeAction).addClass('bound'); // create object with removal function for 'special' bindings such as 'live/die' // and push it into meBase.Bindings; } this.InitUI = function () { //Setup tabs, datepickers, etc } this.Destroy = function () { meBase.Unbind(); //remove object fields and methods delete meBase.someProp; $(meBase.Container).empty(); delete meBase.BeginInit; delete meBase.InitUI; delete meBase.MapEvents; delete meBase.SomeAction; delete meBase; return true; } this.SomeAction = function () { //Do something productive..hopefully } this.ProcessView = function (data) { $("#MainContainer").fadeOut(150, "swing", function () { $(this).empty().append(data); }); } this.LoadView = function () { $.ajax({ url: '/somewhere/something', type: 'GET', success: meBase.ProccessView, error: SomeGlobalObject.LogAjaxError }); } this.BeginInit = function () { //Load pages via ajax meBase.LoadView(); meBase.InitUI(); meBase.MapEvents(); return true; } } 

I tried iterating with javascript to remove events and elements in the .Destroy () function, and this significantly reduced the number of elements left in a separate DOM compared to $ (container) .empty () or $ (container) .remove () . But my memory never collects back, it constantly grows during each loading / unloading. There are drops at random intervals, but not the amount I would expect. Is it normal for so many elements to stay the same, or is there some kind of fundamental problem with how my code works?

Thanks for taking the time to read this!

First post, please be careful ...

+4
source share
1 answer

Recently, I also created single-page applications in .Net MVC3. I suspect that your problems are caused by the fact that Microsoft, in its attempts to keep developers from JS and C #, twists around Javascript and JQuery on your page rather badly.

The best advice I can give you is that you need to drop all Microsoft cruft files and create the html / js part of your application, as if it were completely platform independent. This means that you will mainly use M in MVC, and you will need enough Cs to control your Mrs. If View is all HTML and Javascript, life becomes much easier. Here's how to get started:

  • Remove any pre-packaged server codes, including Razor or ASPX pages.
  • Switching to static HTML files, static JS files
  • (optional) Use Require.js to manage your JS dependencies (read the docs carefully, at first it seems weird but incredibly powerful)
  • (Optional) Use Spine.js to give your JS code some structure.
  • (optional) Use Handlebars.js for your client template engine

Require and Spine quickly became my favorite tools for creating single-page applications. They give you very powerful and flexible tools to help you manage the increased amount of Javascript code that you will write in any one-page application.

After your client code is completely disconnected from Microsoft's attempts to destroy Javascript, you can focus on your data, which should use JSON-based support services in MVC3. You can get help with this here and here .

Good luck

+1
source

Source: https://habr.com/ru/post/1401462/


All Articles