innerHTML and IE browser memory leak problem

Source: Internet
Author: User
Tags dojo toolkit

using sIEve scanning and filtering

If you are using JavaScript and Ajax techniques to develop WEB 2.0 applications, you are most likely to encounter a browser memory leak issue. If you have a single page application or a page to handle a lot of UI operations, the problem can be serious. In this article, you learn how to use the SIEve tool to detect and resolve memory leak issues, and this article also contains application examples and solutions for memory leak issues.

Brief introduction

In general, browser memory leaks are not a problem for Web applications. The user switches between pages, and each page switch causes the browser to refresh. Even if there is a memory leak on the page, the leak is lifted after the page switch. Because of the smaller range of leaks, it is often overlooked.

After the introduction of Ajax technology, the memory leak becomes a serious problem. On the Web 2.0 style page, users do not need to refresh the page frequently. Ajax technology is used to asynchronously update page content. In a special scenario, the entire Web application is built on a single page. In this case, the leak is accumulated and cannot be ignored.

In this article, learn how memory leaks occur and how to find the source of leaks through sIEve. Practical examples of these problems and solutions can help you explore the problem. You can download the sample source code for this article.

The experience of using JavaScript and the Dojo Toolkit can help you understand this article, but it is not required.

Back to top of page

Leak mode

IE, as the web Developer knows, is different from Firefox and other browsers. The memory leak patterns and problems discussed in this article are mainly for IE browser, but not limited to IE. The good method should be applicable to all browsers.

The topic of how IE manages memory is beyond the scope of this article, and more information is available in resources.

Because of the nature of JavaScript and the browser memory management of JavaScript and DOM objects, JavaScript coding inadvertently leads to a browser's memory leak. There are two common patterns that cause these leaks.

Circular references
Circular references are almost the root cause of each type of leak. In general, IE browsers can handle circular references and place them correctly in JavaScript environments. An exception occurs when a DOM object is introduced. When a JavaScript object references a DOM element and the properties of a DOM element reference a JavaScript object, the loop application occurs and causes the DOM node to leak. Listing 1 is a code sample that is typically used to demonstrate memory leak issues in an article. Listing 1. Leakage due to circular references
var obj = document.getElementById ("Someleakingdiv");d Ocument.getelementbyid ("Someleakingdiv"). Expandoproperty = obj;

To solve this problem, be sure to set NULL when you are ready to move the node out of the document expandoProperty .

Closed Package
Closures can cause leaks, because they inadvertently cause circular references. When a closure is present, the variables of the parent function are always referenced. The life cycle of a variable goes beyond the scope of the function and can cause disclosure if improperly handled. Listing 2 shows a leak caused by a closure, which is a common coding style for JavaScript. Listing 2. Leaked closures
   "text/javascript"function() {    var obj = document.getElementById ("element");    This creates a closure over "element"    //and would leak if not handled properly.    function (EVT) {        alert ("Leak the Element DIV");};    }; </script>"element">leaking div</div></body> 

If you use sieve-as a tool to detect orphaned nodes and memory leaks-you will find that the elements DIV have been referenced two times. One of these references is held by the closure (the anonymous function is assigned to the onclick event) and is not detected even if you delete the node. If you delete a node after your application element , the JavaScript reference still holds the orphaned node. This orphaned node will cause a memory leak.

It is important to understand why closures produce circular references. The diagram in the article, "Memory leaks when revisiting Internet Explorer", clearly illustrates this problem and is illustrated in Figure 1.

One way to solve the problem is to delete the closure.

Figure 1. Create a loop-referenced closure between the DOM and JavaScript

Back to top of page

SIEve Introduction

SIEve is a tool to help detect memory leaks. You can download SIEve and access documents from resources. The main sIEve window is shown in Figure 2.

Figure 2. SIEve main Window

This tool is useful when you click Show in use. You will see all the DOM nodes used, including the increased or decreased references to orphaned nodes and DOM nodes.

Figure 3 is a sample view. The reasons for the leaks are as follows:

    • Orphaned nodes, in orphan This column is labeled "YES".
    • An incorrect reference to the DOM node is added, and blue is displayed.

Use SIEve to find the compromised nodes and see the code to fix them.

Figure 3. SIEve: Using a DOM node to locate a compromised node using SIEve

Use the following steps to detect a compromised node.

    1. Start sIEve through the URL of your Web application.
    2. Click Scan now to find all the DOM nodes used in the current document (optional).
    3. Click Show in use to view all DOM nodes. Here, all nodes will be identified in red (new entry) because you are just beginning.
    4. Use some of the features of the Web application to test for leaks.
    5. Click Scan now to refresh the DOM node used (optional).
    6. Click Showin use. Now, the view contains some interesting information. An orphaned node can be found here, or the exception reference to a DOM node is increasing.
    7. Analyze the report and check your code.
    8. Repeat step 4-8, if necessary.

SIEve cannot find out all the leaks in your application, but it can identify the leaks caused by child nodes. Other information, such as ID and outerhtml, can help you identify the compromised node. Review the code that controls the leaking node and make changes accordingly.

Back to top of page

Application examples

This section contains more examples that can cause memory leaks. While these examples and best practices are based on the Dojo Toolkit, most of the examples are valid in normal JavaScript programming.

Although there are many ways to clean up, the most common approach is to remove the DOM and JavaScript objects to avoid memory leaks. The remainder of this section will be built on the pattern described earlier.

The following example includes a Web site that you can create. You can also remove the network widget from the Web page. These actions are performed on a single page, and the page is not refreshed. Listing 3 shows the widgets defined in the Dojo class, which will appear frequently in later articles.

Listing 3. Mywidget class
NULL function (container) {this. Container = container; this. ID = Dojox.uuid.generateRandomUuid ();  This this. ID, InnerHTML: ' mywidget ' +this 'function() {this]. Container.removechild (Dojo.byid (this. ID));});

Listing 4 shows the main page for manipulating these widgets.

Listing 4. The HTML of the site
"Text/javascript" src="js/dojo/dojo/dojo.js"></script><script type="Text/javascript"> Dojo.registermodulepath ("Leak.sample", "... /.. /leak/sample ");d ojo.require (" Leak.sample.MyWidget "); widgetarray = []; function Createwidget () {var container = Dojo.byid ("Widgetcontainer");  varNew leak.sample.MyWidget (container); Widgetarray.push (widget);} function Removewidget () {var widget = Widgetarray.pop (); Widget.destroy ();} </script>"Widgetcontainer"></div ></body>
Use Dojo.destroy () or Dojo.empty ()

At first glance, the problem does not seem to matter. The widget is created and stored in the array. They pop out of the array and are removed. The DOM node is also detached from the document. But if you use SIEve to track create widget and remove widget manipulate the differences, you will find that each widget node becomes an orphaned node, which can lead to a memory leak. Figure 42 shows an example of creating and deleting widgets.

Figure 4. Disclosure of Widget Nodes

This situation may be an IE bug. Even if you create an element and attach it to a document, then immediately use parentNode.removeChild() Delete. The orphaned node still exists.

You can use dojo.destroy() or dojo.empty() to clean up DOM nodes. Dojo executes dojo.destroy(<domNode>) to delete nodes that have been deleted elsewhere, and then destroys them. Dojo will also create a node to collect this garbage. This removes the node you want to delete. (see Dojo Source code for implementation details.) Listing 5 shows how to fix the problem.

Using Listing 5. Usedojo.destroy()To delete the DOM node
# # Change the Destroy () method of MyWidget.jsdestroy:function () {Dojo.destroy (Dojo.byid (This.id));}

Using SIEve authentication, you will find that Dojo creates an empty (garbage) when the component is first deleted DIV  . In subsequent additions and deletions, no DOM node becomes an orphaned node, so the leak will not occur again.

Invalidates JavaScript references to DOM nodes

It is a good practice to invalidate JavaScript references to DOM nodes when cleaning. In Listing 3, the destroy method cannot invalidate the JavaScript reference to the DOM node ( this.domNode, this.container ). In most cases, this situation does not cause a memory leak, but when you work in a more complex application, other objects may reference your widget, and problems may occur.

Suppose other libraries you don't know are available, keep a reference to your widget, and for some reason, it can't be erased. Deleting a widget causes the referenced DOM node to become an orphaned node. Listing 6 shows the changes.

Listing 6. HTML for Web site: Add more objects (widgetRepo) to accommodate widgets
Widgetarray = [];widgetrepo = {}; function Createwidget () {var container = Dojo.byid ("Widgetcontainer");  varNew leak.sample.MyWidget (container); Widgetarray.push (widget); widgetrepo[widget.id] = widget;}

Now try adding or removing components, and then use SIEve to detect memory leaks. Figure 5 shows the orphaned nodes of the widget DIV, as well as the ever-increasing widgetContainer div references. In the Refs column, the widgetContainer DIV should have only one reference in the document.

Figure 5. Orphaned nodes

The solution is to invalidate the DOM node reference during the cleanup process, as shown in Listing 7. It may be a good practice to add some invalid statements, as this will not affect the original functionality.

Listing 7. Invalidates the DOM reference
function () {Dojo.destroy (Dojo.byid (this. ID));  This null;  This null;}
Disconnecting events and canceling topic subscriptions

With Dojo, another way to avoid a memory leak is to disconnect the event you are connected to and cancel the topic you subscribed to. Listing 8 shows an example of a connection and disconnect event

With JavaScript programming, it is generally recommended that you break the event before removing the DOM node from the document. Use the following APIs to connect and disconnect events on different browsers.

    • For IE: attachEvent anddetachEvent
    • For other browsers: addEventListener andremoveEventListener
Listing 8. Dojo.connect and Dojo.disconnect
function (container) {//... old code here-clickhandler= Dojo.connect (This thisfunction() {//... old Code Heredojo.disconnect (this. clickhandler);}

In Dojo, you can also establish a connection in a component by subscribing to and publishing a topic. It executes as Observer mode. In this case, the best way to avoid a memory leak is to do a cleanup when you cancel the topic subscription. Use the following APIs for both of these methods:

    • Dojo.subscribe (/*string*/topic,/*function*/function)
    • Dojo.unsubscribe (/*string*/topic)
Set InnerHTML

If you are not careful in how you use JavaScript settings innerHTML , you may cause IE memory leaks. (See Resources for details.) Listing 9 shows a scenario that could cause IE memory leaks.

Listing 9. InnerHTML leaks on IE
1. An orphan node should is in the Documentvar Elem = document.createelement ("DIV");//2. Set the node ' s InnerHTML with an DOM 0 event wiredelem.innerhtml = "<a onclick= ' alert (1) ' >leak</a>";//3. Attach the Orphan node to the Documentdocument.body.appendChild (Elem);

The code types shown above are common in WEB 2.0 applications, so be careful. The solution is to ensure that the node innerHTML is not an orphaned node before it is set. Listing 10 is a fix to the code in Listing 9.

Listing 10. Fix InnerHTML leaks
var elem = document.createelement ("DIV");//Now the node is no longer a leaf node document.body.appendChild (elem); elem.innerhtml = "<a onclick= ' alert (1) ' >no leak</a> ';

Back to top of page

Conclusion

It is easy to identify patterns that cause browser memory leaks, and it is difficult to find the root cause of the problem in your application source code. SIEve can help you find most of the leaks caused by orphaned nodes. This article describes the memory leaks that can be caused by just a tiny bit of negligence in JavaScript coding. The best practices that are described in this article can help you prevent leaks.

Back to top of page

Download
Description name size
This article source code Mywidget.zip 1KB

innerHTML and IE browser memory leak problem

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.