lunes, 27 de febrero de 2012

jQuery memory leaks in IE 6 and 7

Some years ago, while I was working for Digipro, I was assigned to the development of a control used to display digitalized images using only HTML and javascript. The previous control was developed using ActiveX controls and was having serious difficulties with the increse of security of IE.

Digipro has an application that is used to digitalize images, store them in a database and then query and display them. This application is used by several institutions here in Mexico, most of them banks and finantial institutions.

I started using jQuery for this project, and everything went really smoth and I learnt a lot. But while doing some testing I saw that the memory footprint of IE was growing each time I loaded a new image (about 1 Mb per load). One client noticed it and reported it, but at that time IE 8 went out and they upgraded and everything went fine from there so I never really investigated this bug.

Last week the development manager from Digipro called me because, for some clients, the application became slow and even unresponsive after about and hour using it. It turned out that these clients are still using IE 6 and IE 7 in most of their computers. The manager asked me to debug this component and help them correct this behavior.

I started installing and creating two virtual machines with XP Mode, one with IE 6 and the other with IE 7 to be able to reproduce the bug; and then mounting all the services and application in my development computer.

While using the application I noticed that the developers at Digipro were busy getting a lot of stuff into the component I developed and it have a lot of new functionality. The next thing I noticed was that the memory footprint if IE 7 was growing about 20 Mb each time a new image was loaded and it never went down until I closed the browser. WTF! 20 Mb! When this bug was reported to me (3 years ago) the memory grew less than 1 Mb per image.

After reading a lot of Memory Leaks of javascript in IE

I realized that I needed a tool to help me find them. So I downloaded DripsIEve, and IEJsLeaksDetector. All of them great applications.

The tools reported several leeks each time an image was unloaded and a new one was loaded. This step does a postback to the server and all controls of the page are re-created.

I was shocked to see that most of the leeks where related to jQuery functions. I was expecting to find some really nasty and obvious bugs in the code of the component.
So I started to unbind every event of every object I found. And the memory footprint started going down until it reached about 5 Mb per image. At that point, the only leaks that sIEve was reporting where related to the jQuery UI draggable plugin and I was having a hard time trying to remove them. So in a moment of despair I tried to select all objects and unbind all events from them.

I was really shocked to find out that sIEve was still reporting the same leaks, and more over, IEJSLeaksDetector was showing that the window object hasn't been disposed. And the memory kept growing about 4 Mb after each image load.

So I started looking on the web for this strange behavior and found several reports of it. Two of them where bug reports in the jQuery Bug Tracker. Tickets 6421 and 8863. The first one of them had a proposed solution and after implementing it, the leaks were gone.

So, after this weekend that almost was a nightmare I have decided to bill a lot more each time an application have to support IE 6 or IE 7.