Try Catch Errors for many script components - JavaScript

I have a page that contains many script components (50+) and I am getting an error when using IE in some random instance (not happening in Chrome or Firefox).

"Not enough memory on line: 1"

I did a little google search too and found problems with IE that Chrome and FF handled differently. I would like to catch this error and know exactly what is the reason for this script error.

What would be the best way to use a global try-catch block for many script components? All of these script components are on the same page. Wait for your offers.

+3


source to share


3 answers


You might want to try it window.onerror

as a starting point. It must be added before the tags <script>

that load the components.

https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror

If this fails, you can try to reduce the components loaded in half until the error no longer occurs. Then profile the page (you may need to shrink it due to the need for profiling). Look for memory leaks as suggested by B.Bergie. If there is, in fact, a leak, it will most likely happen in all browsers, so you can take a snapshot in Chrome as well.



If that still doesn't provide anything interesting, the problem might be in one particular component that was not in the set of components you downloaded. Ideally, anytime this component is enabled, you see a problem. You can repartition the loaded components as long as you don't isolate the culprit.

Finally forgot to mention that your home base for all of this should be browser developer tools, for example. Chrome dev tools , or if unique to Edge, Edge debugger .

And FYI, Edge is a browser that crashes, but that doesn't mean the problem is missing from Chrome or FF.

+3


source


One important thing that is missing from your question is an error that occurs during page load or initialization, or if it happens after a while while viewing the page.

If, during load or initialization, this is likely due to the fact that your page contains too many components and uses much more memory than the browser is willing to accept (and IE is just the first to give up).

In this case, help does not help, but reduces the page size. One possible way is to create only the objects (components) that are currently visible (in the viewport), and once they exit the viewport, remove them from the JS and DOM again (replacing empty DIVs sized to fit the components).


In the event of an error while viewing the page, it could be caused by a memory leak. You can use Process Explorer to view the memory used by your browser and check if the memory is constantly increasing - indicating a memory leak.

Potentially a memory leak in Internet Explorer as it contains 2 separate garbage collectors (aka GC): one for DOM objects and the other for JS properties. Other browsers (FF, Webkit, Chromium, etc., not sure about Edge) only contain one GC for DOM and JS.

So when you create a circular reference between DOM object and JS object, IE GC cannot properly free memory and create a memory leak.

var myGlobalObject;

function SetupLeak()
{
  myGlobalObject = document.getElementById("LeakDiv");
  document.getElementById("LeakDiv").expandoProperty = myGlobalObject;

  //When reference is not required anymore, make sure to release it
  myGlobalObject = null;
}

      

After this code, it appears that the link has LeakDiv

been freed but LeakDiv

still links to myGlobalObject

in it expandoProperty

, which in turn links to LeakDiv

. In other browsers, their GC can recognize such a situation and release both myGlobalObject

, LeakDiv

but IE GCs cannot because they don't know if the referenced object is being used or not (because that's another GC responsibility).

Even less noticeable is the circular link created by the closure:



function SetupLeak()
{
    // The leak happens all at once
    AttachEvents( document.getElementById("LeakedDiv"));
}

function AttachEvents(element)
{
    //attach event to the element
    element.attachEvent("onclick", function {
            element.style.display = 'none';
    });
}

      

In this case, the property LeakedDiv

onclick

refers to the handler function

, the closure property element

refers to LeakedDiv

.

To fix these situations, you need to properly remove all references between DOM objects and JS variables:

function FreeLeak()
{
    myGlobalObject = null;
    document.getElementById("LeakDiv").expandoProperty = null;
}

      

And you might want to shrink (or remove completely) the gates created on DOM elements:

function SetupLeak()
{
    // There is no leak anymore
    AttachEvents( "LeakedDiv" );
}

function AttachEvents(element)
{
    //attach event to the element
    document.getElementById(element).attachEvent("onclick", function {
            document.getElementById(element).style.display = 'none';
    });
}

      


In both cases, using try-catch is not an option, as Out of memory can happen in random places in the code and even if you find one line of code where it happened the next time it could be in a different place. Process Explorer is the best chance to find situations where memory is increasing and tries to guess what might be causing it.

For example: if memory increases every time you open and close a menu (if you have one), you should watch it open and close and look for the situations described above.

+2


source


You can check your localStorage

before and after any components.

Something like:

function getLocalStorage() {
    return JSON.stringify(localStorage).length;
}

function addScript(src, log) {
    if(log){
        console.log("Adding " + src + ", local storage size: " + getLocalStorage());
    }
    var s = document.createElement( 'script' );
    s.setAttribute( 'src', src );
    document.body.appendChild( s );
}

function callFunction(func, log){
    if(log){
        console.log("Calling " + func.name + ", local storage size: " + getLocalStorage());
    }
    func();
}

try {
    addScript(src1, true);
    addScript(src2, true);
    callFunction(func1, true);
    callFunction(func2, true);
}
catch(err) {
    console.log(err.message);
}

      

Hope this helps you. Bye.

+1


source







All Articles