ajax memory leak - javascript

I am experiencing a slow memory leak in both IE and Firefox using a combination of ASP.NET AJAX and jQuery. My scenario is very similar to the one described here : Preventing AJAX memory leaks except using jquery and asp.net AJAX, not protyotype: I have a webpage displaying data in an UpdatePanel that is refreshed every 60 seconds using a timer. in the AJAX javascript pageLoad function that is called on every "partial postback", I re-bind events because they are lost in the asp.net partial postback:
function pageLoad(sender, args) {
$("#item").unbind();
$("#item").hover(
function() {
// do something
},
function() {
// do something
});
}
so this is called every 60 seconds. Could this alone be the cause of a memory leak?

Do this instead:
$(function() { //.ready shortcut...
$("#item").live("hover",
function() {
// do something
},
function() {
// do something
});
});
Note, this requires jQuery 1.4.1, but acts entirely different in terms of memory. It attaches to the entire DOM watching for the event to bubble instead of attaching a new event to every object your're inserting every 60 seconds.

Yes, it could be.
The first thing to try would be to take the two functions defined there (if possible) and place them in a higher level so that they are only defined once.

Related

What If document.ready won't work

Every JavaScript developer sooner or later faced with case when page elements unavailable in document.onready event. It's happens because onready fired to soon, especially when most of the page parts loaded dynamically (with AJAX). I work with Drupal 7 now. Drupal does not provide Ajax callback, it's seems to be you need to write custom callbacks.
And my question is: what is the most appropriate solution for that case?
Usually I apply
jQuery(document).ready(function(){
setTimeout(function tmr(){
//Wait for any or task specific element will be available
if (jQuery('.bxslider').length) {
//Code here
do_code();
} else
setTimeout(tmr, 1000);
}, 10);
Or better write a callback? Or no different at all?
Attach your js behaviors like this:
Drupal.behaviors.nameOfYourModule= {
attach: function (context, settings) {
// your code here
}
};
This way your code will be executed on every request including AJAX requests.
For more information see this blog post on the subject.

How do I add a load icon to a page that just processes javascript code?

I use Ajax load icons all the time for when I do ajax requests.
I want to know if it's possible to accomplish the same thing with just regular javascript code. For example:
$('button').on('click', function(){
showLoadingBar();
longProcess();
hideLoadingBar();
});
longProcess() is just a function that can take 1-3 seconds to process (it does a lot of calculations and manipulates the DOM but doesn't do any ajax requests).
Right now, the browser halts/freezes during these 1-3 seconds, so what I would rather do is show a loading icon during this time. Is this possible? The code I have above pretty much ignores showLoadingBar().
The DOM won't be updated until the current Javascript process ends, so you can't do it just like that. You can however use setTimeout to get around that:
showLoadingBar();
setTimeout(function() {longProcess(); hideLoadingBar(); }, 1);
What happens above, in case it isn't clear, is that showLoadingBar is executed, then a timeout is set up. The current process will then end and allow the DOM to update with the loading bar, before the timeout is invoked, very shortly after. The handler executes your heavy function and when it's done, hides the loading bar again.
The following will give you control over the action on click. What this means is you can disable the clicking ability till it has finished running. But also i've including setTimeout which returns control to the browser (thus removing that annoying "lockup" feeling) and in the timeout function we preform our long process then re-enable the button! VIOLA!
function startProc() {
var $this = $(this);
$this.off("click", startProc);
showLoadingBar();
setTimeout(function() {
longProcess();
hideLoadingBar();
$('button').on('click', startProc);
});
}
$('button').on('click', startProc);
Dude,
Use the .bind method, which in this case is performed so:
$('button').bind('click', function(){
showLoadingBar();
longProcess();
hideLoadingBar();
});

Run js when document is changed?

I tried looking for the answer, and this is my first post, so bear with me if I mess up in some way.
Basically my problem is this: I'm writing an extension for Chrome that uses jQuery. I have another extension that makes a timed $.ajax() request every 10 seconds. I need to find a way to run my code every time that timed ajax request and its callback function completes. Setting a timer for my own script can be done, although that's rather half-assed and doesn't work as well.
The problem can be illustrated thus:
//extension 1
function timedFunc() {
setTimeout(doStuff, 10000);
};
timedFunc();
//extension 2
//code to be run every time doStuff completes
I feel like there may be a very elementary solution to this problem but I appreciate the help.
There is (was) an event called DOMSubtreeModified.
But it has been deprecated so at tho moment there are really only workarounds available.
Why is the DOMSubtreeModified event deprecated in DOM level 3?
I can't advise on using this event as it hasn't even been implemented in all browsers.
But what you can do (easily) is just trigger you own event with all your ajax call!
Example:
fire your event when (any) ajax call completes:
$(document).ajaxComplete(function() {
$(document).trigger('domChanged');
}
and listen to it:
$(document).on('domChanged',function() {
alert("i changed the DOM tree!");
});
btw:
taken that you just want to react to ajax calls compleing... just use the .ajaxComplete() event:
http://api.jquery.com/ajaxComplete/
i didn't really understand what you are trying to say but i did understand your question in the title so here is my modest answer:
// a global variable for the documents content
var content=document.documentElement.innerHTML;
// return true if the document content has changed
function documentChanged(){
return content==document.documentElement.innerHTML;
}

Is there any overhead to having multiple $(document).ready with jQuery 1.8.1

I have code like this:
$(document).ready(function () {
$('.accessLink')
.bind('click', accessLinkClick);
$('#logoutLink')
.click(function (e) {
window.location = $(this).attr('data-href')
});
});
Functionality for each part of my site is divided into a number of small files and when the site is deployed these are mimified and joined up.
Each of these small files which number up to ten wait on $(document).ready. Can anyone tell me if there is much overhead in doing this. Splitting my code into functional areas has meant the code looks easy to maintain but I am just wondering about overhead now that I am using jQuery 1.8.1
Update:
Based on the answers I started to code like this:
$(document).ready(function () {
accessButtons(); // login, register, logout
layoutButtons();
themeButtons(); // theme switcher, sidebar, print page
});
with each function then coded as:
function accessButtons() {
$('.accessLink')
.bind('click', accessLinkClick);
$('#logoutLink')
.click(function (e) {
window.location = $(this).attr('data-href')
});
};
Here's the difference between 10 $(document).ready() calls versus one that then calls 10 initialization functions.
With the 10 calls, you get:
10 calls to $(document).
10 calls to the .ready() method.
One event listener for the DOM ready event
When the DOM ready event fires, it then cycles through an array of callbacks and calls each callback passed to .ready().
If you have one $(document).ready() that then called all 10 of your initialization functions, you would have this:
1 call to $(document).
1 call to the .ready() method.
One event listener for the DOM ready event
When the DOM ready event fires, it then calls your one ready handler.
Your ready handler then calls the 10 initialization function calls.
So, the difference is approximately the time it takes to construct 9 extra jQuery objects and make 9 extra .ready() method calls. In extreme cases this could be noticeable, but it is unlikely that you would see a difference in practice.
If the code needs to be executed in order, then they should in the same dom ready callback function, otherwise, you could divide them into different dom ready callback.
Only use the .ready() function to wrap all code that needs to be run once ALL other code is loaded and once the page is ready. If you have any libraries that can run on their own and do not need to do anything with the DOM then you shouldn't need to put them into a ready call.
Performance goes down when using many $(document).ready() calls, but it doesn't seem to be too bad, and on some browsers it doesn't seem to affect performance very much at all. The linked page has test results for several popular browsers when using $() to modify a large DOM.
Due to the performance issue, I personally create separate functions for each page. So instead of having $(document).ready() run multiple times, you just fire a function on each page. This way, i tend to generally have $(document).ready() only run twice, once for globals, then once for the particular page.
function ContactForm() {
$(function () {
// Contact form page specific stuff.
});
}
In my View (by the sounds of your question, im assuming you're using MVC), what i do is add the following:
#section scripts {
#Scripts.Render("~/bundles/ContactForm")
<script type="text/javascript">ContactForm();</script>
}

Testing whether an event has happened after a period of time in jQuery

I'm writing a script for a form-faces xforms product that is keyed off an event built into form faces. The event is called 'xforms-ready'. I have define 'startTime' as happening as soon as the document in 'ready'. What I want the script to do is warn the user that it is taking too long before the 'xforms-ready' happens, say if it's been 6 seconds since 'startTime'. I can easily do things when the 'xforms-ready' event happens using the code below:
new EventListener(document.documentElement,
"xforms-ready",
"default",
function() {
var endTime = (new Date()).getTime();
}
);
however the warning will want to happen before 'endTime' is defined. So I guess I want something that works like this:
If 6 seconds has passed since startTime and endTime is not yet defined do X
or possibly more efficiently:
If 6 seconds has passed since startTime and 'xforms-ready' has not yet happened do X
Can anyone suggest a way of doing this?
You can do this with setTimeout. (Complete example below.) In jQuery's ready handler, set a function to be called in six seconds via setTimeout, and in your xforms ready handler, cancel that via clearTimeout if it hasn't happened yet.
Edit Complete example (rather than my earlier fragmented code snippets), assumes it's okay if your xforms ready handler is within your jQuery ready handler:
jQuery.ready(function() {
var xformsReadyTimer;
xformsReadyTimer = setTimeout(function() {
// Too long, show the warning
xformsReadyTimer = undefined;
alert("XForms is taking too long!");
}, 6000);
new EventListener(document.documentElement,
"xforms-ready",
"default",
function() {
if (xformsReadyTimer) {
// Cancel the warning
clearTimeout(xformsReadyTimer);
xformsReadyTimer = undefined;
}
}
);
});
(You might consider making those named functions rather than anonymous ones, but I've used anonymous ones above for simplicity.)

Categories

Resources