At our MVC project we have this specific View (HTML/JS) where the user can manipulate a large table: select a line and make some operations including move up/down. With move up/down we are facing memory leak: page starts with ~100 MB and goes up until browser crashes (~8 GB at localhost).
Table data is generated at backend, being sent via JSON to frontend. Each line is treated via JS as below:
function LoadTableClient(selectedLine) {
$('#table-client tbody').find('tr').remove(); //Added for clarification
var listClientInformationJson= $('#generalData').data('listclientinformation');
var html = '';
$.each(JSON.parse(listClientInformationJson), function (index, item) {
html += WriteTableClient(item, index, selectedLine);
});
$('#table-client').find('tbody').append(html);
}
When user move up/down it can affect several rows since each line can also be a group containing several rows inside (and other subgroups and so on). Also, we have subtotal and total columns, therefore we need to redraw the hole table.
For this move up/down operation we are triggering a JS function that requests backend via AJAX, and then it gather the response to redraw our table.
$.ajax({
url: '...../MoveTableClientItem',
type: "POST",
contentType: "application/json",
data: JSON.stringify({
...
}),
success: function (response) {
if (response.success) {
GetProjectInfo(); //gets JSON
LoadTableClient(var1); //read JSON and append to table
}
Update: GetProjectInfo function
function GetProjectInfo() {
$.ajax({
url: '..../GetProjectInfo',
type: "POST",
contentType: "application/json",
async: false,
data: JSON.stringify({
...
}),
success: function (response) {
$('#generalData').data('listclientinformation', '');
$('#generalData').data('listclientinformation', response.listClientInformationJson);
},
error: function (response) {
...
}
});
}
It works fine regarding the visual and functional output, the problem is the memory leak. With Chrome "Memory Inspector" we understood that each operation adds ~30 MB to memory due to rows kept in memory.
Update: see attached print showing JS memory increase.
We tried Location.reload() but it was not a good user experience since the hole page is reloaded and what the user was doing is lost (open modals, screen position, etc.)
We tried $("#table-client").empty(); at "response.success" but it just didn't work (nothing changed).
Any ideas on how to solve this?
The issue was related to saving the AJAX response at an element thus making GC (garbage collector) not effective. I managed it by creating a global variable that contains the AJAX response, see below. Now the RAM usage is decreased by GC.
let listClientInformationJson = ''; //Global variable
$(document).ready(function () {
...
//Gets new data with the function below
...
}
function GetProjectInfo() {
$.ajax({
url: '..../GetProjectInfo',
type: "POST",
contentType: "application/json",
data: JSON.stringify({
...
}),
success: function (response) {
listClientInformationJson = undefined; //forces erase
listClientInformationJson = JSON.parse(response.listClientInformationJson);
},
error: function (response) {
...
}
});
}
Related
I have spent 2 days to find a solution, but stackoverflow does not have correct answer for this.
I have 2 ajax function first loading values onload,
$.ajax({
url: 'http://localhost/movies/data/home_data.php',
type: 'POST',
dataType: 'json',
cache: false,
success: function(data) {
var home_contents_data='';
$.each(data, function(index, element) {
home_contents_data += 'More Details';
});
}
});
it is working and giving data perfectly. it have a onclick function call as "readSingleMovie2()" I want to send this value to another ajax function. this is my second ajax function
//second function
function readSingleMovie2(movie_id2)
{
myApp.onPageInit('single-movie-2', function (page) {
var single_movie_details2 = '';
$.ajax({
url: 'http://localhost/movies/data/single_movie-2.php?rand='+(Math.random()),
type: 'POST',
data: 'movie_id2='+movie_id2,
dataType: 'json',
cache: false,
success: function(data) {
var single_movie_data='';
$.each(data, function(index, element) {
single_movie_data += '<div>'+data[index].film_name+'</div>';
});
}
});
})
}
That is also working perfectly and that function data comes inside to the function.
but my problem is. when I click second time some of value from 1st function. second function's URL loading multiple times.
I have attached firebug screenshot image to get an idea.
I tried with unbind, preventDefault, preventStop and cache false... everything I know and get the internet. But I am still finding the better solution for this.
Please help me to resolve this problem.
Really appreciate your valuable time and answers
Thanks!
Instead of unbind, preventDefault and preventStop, try off() .
See this: http://api.jquery.com/off/
I am using redips plugin(http://www.redips.net/javascript/drag-and-drop-table-content/) for drag and drop. It is working on static data, but when data comes dynamic through java, the drag and drop stops. I am using the following functions to pick up data on drag and drop:
droppedBefore: function() {}
, finish: function() {}
The plugin is written on pure javascript, so jquery is not working otherwise we could use $(document).live for picking dynamic data
Please suggest something so that drag and drop can work on dynamic data also
Whenever table layout inside drag container is changed, then is needed to call init() or initTables() method. Please see example0 where new table is dynamically appended with jQuery.
http://www.redips.net/my/preview/REDIPS_drag/example00/index2.html
... and here is JavaScript code used in script.js file:
// new table using AJAX/jQuery to the drag container
redips.load_table = function (button) {
// parameter (example for ajax request)
var id = 1;
// disable button (it can be clicked only once)
button.style.backgroundColor = '#c0c0c0';
button.disabled = true;
// AJAX request
$.ajax({
type: 'get',
url: 'ajax.php',
data: 'id=' + id,
cache: false,
success: function (result) {
// load new table
$('#load_content').html(result);
// rescan tables
REDIPS.drag.initTables();
}
});
};
after post request change in table then call
REDIPS.drag.init();
$.ajax({
type: "post",
url: "/recipe/sliderData",
dataType: "json",
data: dataForSlider,
success: function (data) {
//table change
REDIPS.drag.init();//
},
error: function (data) {
alert("Error")
}
});
I have a div call load-ajax-hotels in which I am trying to load php files after the click event has been fired.
Say that I am trying to load alpha.php, beta.php, gamma.php ... delta.php
$("span.dessert-make").click(function(){
/* Load Initial Data */
$(".ajax-load-hotels").load("./php/alpha.php");
$.get("./php/beta.php", function(data){
$(".ajax-load-hotels").append(data);
});
$.get("./php/gamma.php", function(data){
$('.ajax-load-hotels').append(data);
});
$.get("./php/delta.php", function(data){
$('.ajax-load-hotels').append(data);
});
});
But this call is not working properly. I mean that at each instance of the click event I get different results. Some times just alpha.php and beta.php gets displayed some times every php files duplicate comes along. Its random every time. Can some one tell me what the problem is?
And also how do I make php files load as the user scrolls down to bottom of the page. How to implement the scrollTo() method for this. x and y pos becomes different once window resizes.
Sorry. That I might have overlooked. I corrected it.
Assuming you are trying to load these sequentially (syncronously), I would probably go with something like this:
function load_pages(index, pages) {
$.get("./php/" + pages[index] + ".php", function(data) {
$(".ajax-load-hotels").append(data);
if (index + 1 < pages.length) {
load_pages(index + 1, pages);
}
})
}
$("span.dessert-make").click(function(){
load_pages(0, ["alpha", "gamma", "delta"]);
});
You missed a }) at
$.get("./php/2.php", function(data){
$(".ajax-load-hotels").append(data); // here is missed });
$.get("./php/3.php", function(data){
$('.ajax-load-hotels').append(data);
});
Correct:
$.get("./php/2.php", function(data){
$(".ajax-load-hotels").append(data);
});
$.get("./php/3.php", function(data){
$('.ajax-load-hotels').append(data);
});
EDIT 1:
And, $.get is asynchronous.
To make it synchronous (I provided just an example):
$.ajax({
url: urltophp,
async: false,
success: function(data) { $(".ajax-load-hotels").append(data) },
dataType: 'html'
});
I have a list of thumbnails of recipe names and i want to track which recipes people are clicking on. I problem is that i can strictly do this using jQuery and nothing else. I dont have access to any other pages of the website.
What i did so far is i checked on the names of recipe and images and added a common class using .addClass() in jquery and just after that i declared an onclick function on that name.
Then i a taking the tile of the tag(Which is the recipe name) and sending this information of my other website where it stores this info in database.
The problem is my clicks are not getting all of the time. The behavior looks random to me till now and i don't know how some of the clicks are getting stored and how some are not!! I researched on net and only related thing i found was to keep cache to false. I also tried that but the behavior remained the same. Clicks got stored sometime only.
I am doing this on local host right now and i need to store this info on other website of mine.
jQuery(window).load(function(){
jQuery('.del-space .thumbnail a').addClass("recipeLinks");
$(".recipeLinks" ).on("click",function(event) {
var user=jQuery('loggedinuser').attr('title');
//alert(user);
if(typeof(user)==="undefined"){
user='Guest';
}
var recipeName=$(this).attr('title');
var data='recipeName='+recipeName+'&user='+user;
$.ajax({
url: "http://myotherwebsite.com/tracking/storeClick.php",
cache: false,
type: 'POST',
data: data,
beforeSend: function() {
},
success: function(data, textStatus, xhr) {
//alert('done');
//window.location = location.href;
},
error: function(xhr, textStatus, errorThrown) {
//alert("error");
}
});
});
Apart from this i am also wondering, that when i will put this code on live, where there would be a hell lot of clicks at a time, will i be able to log all the clicks?
use event.preventDefault() to stop the click from changing the page right away so that your ajax request has time to complete, and use window.location to change the page once ajax is complete
jQuery(window).load(function(){
jQuery('.del-space .thumbnail a').addClass("recipeLinks");
$(".recipeLinks" ).on("click",function(event) {
event.preventDefault(); //stop the default action
//the action will take place after
//ajax is complete
var href = jQuery(this).attr("href"); //get the location to goto
var user=jQuery('loggedinuser').attr('title');
//alert(user);
if(typeof(user)==="undefined"){
user='Guest';
}
var recipeName=$(this).attr('title');
var data='recipeName='+recipeName+'&user='+user;
$.ajax({
url: "http://myotherwebsite.com/tracking/storeClick.php",
cache: false,
type: 'POST',
data: data,
beforeSend: function() {
},
success: function(data, textStatus, xhr) {
//alert('done');
window.location = href; //now goto the links href
},
error: function(xhr, textStatus, errorThrown) {
//alert("error");
}
});
});
I have a nifty little piece of Ajax code that loads in PHP.
http://www.moneyworrier.com/client-stories/
What happens is that when you click on a menu item on the left-hand navigation, it reloads a Div with content appropriate.
What it does however is loop through previous requests, which is bothersome (Click on any left hand item 3x and you will see what I mean). I think I need to find a function that does the equivalent of exit; and clears any post data.
My call in code is:
Video
And my JS looks like:
$(document).ready(function () {
$('a.media').click(function () {
var usr = $(this).attr('rel');
$("#displaystories").html('Retrieving..');
$.ajax({
type: "POST",
url: "/client-stories/media.php",
data: "showcode=" + usr,
success: function (msg) {
$("#displaystories").ajaxComplete(function (event, request, settings) {
$(this).html(msg);
});
}
});
});
});
You're binding a new listener to ajaxComplete on every click. Your success callback should just be:
success: function(msg) {
$("#displaystories").html(msg);
}