dcsimg
www.webdeveloper.com
Results 1 to 10 of 10

Thread: filereader memory leak

  1. #1
    Join Date
    Jan 2015
    Posts
    6

    filereader memory leak

    I have this function:

    Code:
        if (files) {
            for (var i=0, f; f=files[i]; i++) {
    	         r =  new FileReader();
                r.onload = (function(f) {
                    return function(e) {
                        var contents = e.target.result;
                        LeggiFile(e.target.result,f.name);
                    };
                })(f);
    
    
                r.onloadend = (function(f) {
                    return function(e) {
                        //alert("Letto " + NumeroFileProcessati);
    						 if (NumeroFileProcessati>=files.length) {
    							//TabellaFinale=null;
    							//RigaTabella=null;
    							contents=null;
    							CurrentFile=null;
    							r=null;
    							files=null;
    							alert("Memo liberata?");
    						 }
                    };
                })(f);
                r.readAsText(f);
    	 console.log(NumeroFileProcessati);
            }
        }
    It parses an array of files and reads each file into memory; content of each file is then converted into a row for an HTML table by LeggiFile(e.target.result,f.name);.
    Function is working fine, but there's a memory leak somewhere, so the Chrome tab executing the script grows and grows and grows in memory size...
    As the FILES array contains more than 1000 files, at the end of the process over 1 GB RAM is allocated to the tab!!

    I tried freeing some memory assigning "null" to same variables, but it does not work.
    How do I prevent memory leak?

    I do not need at all a synchronous file reading, I can accept a serial reading, but I don't know how to accomplish this.
    What instead I'd need is possibility to interrupt the script before it reaches the 1000th element in the array...

  2. #2
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    1,159
    Well there's not really anything I can test given what parts of your code are not here. Just based on what you've provided I don't know if I see any real potential memory leaks. The variable r should probably have a var declaration on it, but that should be a huge issue. I probably would have set up this type of thing slightly different, but that's probably just a preference in coding styles/methods.


    There are some variables that I do not see a declaration for, which leaves gaps in my understanding of your code as a whole. I'm also a little curious as to the filesizes of the files being used (or at least the average). Not that I expect the total filesize to be 1GB (otherwise I couldn't see you posting here). But it would provide a frame of reference as to how much 'extra' memory is being used. Also, perhaps it's just a lack of knowledge on my part, but I find your for() loop a bit odd. It doesn't actually contain a condition. It may not really matter but as I mentioned earlier, I suppose I would have coded it slightly different in that regard.

  3. #3
    Join Date
    Jan 2015
    Posts
    6
    I'm not very skilled in JS, so I just copied a "filereader code snippet" from somewhere and added into it a call to my function; actually I don't understand why there's no condition in the FOR, but if it works... :-)

    Each file is at most 15 KB long.

    This is the full code I'm using:

    Code:
    <!DOCTYPE html>
    <html>
    <head>
    	<style>
    		.example {
    		  padding: 10px;
    		  border: 1px solid #ccc;
    		}
    		#drop_zone {
    		  border: 2px dashed #bbb;
    		  -moz-border-radius: 5px;
    		  -webkit-border-radius: 5px;
    		  border-radius: 5px;
    		  padding: 25px;
    		  text-align: center;
    		  font: 20pt bold 'Vollkorn';
    		  color: #bbb;
    		}
    	</style>
      <script src="js/jquery.js" type="text/javascript" language="JavaScript"></script>
      <script src="js/sorter/jquery.tablesorter.js" type="text/javascript" language="JavaScript"></script>
      	<script>
    
    var TabellaFinale ='<table border="1" id="table" class="tablesorter"><thead>\
    		<th>Genere canale</th><th>(codice canale)</th><th>Posizione canale</th><th>Nome canale</th><th>Giorno settimana</th><th>Data</th><th>Id Evento</th><th>(ID interno)</th><th>Orario</th><th>Durata (min.)</th><th>Titolo</th><th>Estratto della trama</th><th>Genere evento</th><th>Tipo di evento</th><th>File dettagli</th><th>Pagina web evento</th><th>Pagina web programmazione mensile</th>\
    		</thead>';
    var CurrentFile;
    
    
    function LeggiDragOver(evt) {
    }
    
    function LeggiDragEnter(evt) {
    alert("in");
    }
    
    var files;
    var NumeroFileProcessati=0;
    	var TemplateRiga = '<tr> \
    	<td>#genere#</td>\
    	<td>chanpos</td>\
    	<td>#telecomando#</td>\
    	<td>#nomecanale#</td>\
    	<td>#giornosettimana#</td>\
    	<td>#data#</td>\
    	<td>id</td>       \
    	<td>pid</td>   \
    	<td>starttime</td>  \
    	<td>dur</td>   \
    	<td>title</td> \
    	<td>desc</td> \
    	<td>genre</td>  \
    	<td>subgenre</td> \
    	<td>#filedet#</td>  \
    	<td>#web#</td>\
    	<td>#mese#</td>\
    	<td></td>\
    	</tr>';
    	var giorni = ["Domenica", "Lunedý", "Martedý", "Mercoledý", "Giovedý", "Venerdý", "Sabato"];
    	var MeseStr = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"];
    
    function LeggiFile(contenuto, nome) {
       NumeroFileProcessati++;
    
    		var RigaTabella="";
    		var FileContents = contenuto; // legge intero file
    		var myObject = JSON.parse(FileContents); // trasforma testo JSON in oggetto Javascript
    		var Palinsesto = myObject.plan; // L'oggetto contiene l'array PLAN che Ŕ il palinsesto del canale
    		var NumeroEventi = Palinsesto.length-1; // Legge numero elementi (ma il primo Ŕ vuoto)
    
    		var InizioNome = nome.indexOf("(")+1;
    		var FineNome = nome.indexOf(",",InizioNome)+1;
    		var LunghezzaNome = FineNome - InizioNome - 1;
    		var NomeCanale=nome.substr(InizioNome,LunghezzaNome);
    
    		var InizioTelecomando = FineNome;
    		var FineTelecomando = nome.indexOf(",",InizioTelecomando)+1;
    		var LunghezzaTelecomando = FineTelecomando - InizioTelecomando - 1;
    		var Telecomando = nome.substr(InizioTelecomando,LunghezzaTelecomando);
    
    		var InizioGenere = FineTelecomando;
    		var FineGenere = nome.indexOf(")",InizioGenere)+1;
    		var LunghezzaGenere = FineGenere - InizioGenere - 1;
    		var Genere = nome.substr(InizioGenere,LunghezzaGenere);
    
    		var InizioData =  nome.indexOf("-grid")+6;
    		var FineData = nome.indexOf(".",InizioData)+1;
    		var LunghezzaData = FineData - InizioData - 1;
    		var Data = nome.substr(InizioData,LunghezzaData);
    		var Giorno=Data.substr(6,2);
    		var Mese=Data.substr(3,2);
    		var Anno=Data.substr(0,2);
    
    console.log("File n." + NumeroFileProcessati + " su " + files.length + " (" + Math.round(100*(NumeroFileProcessati/files.length)) + "%) - Nome: " + NomeCanale + ", Telecomando: " + Telecomando + ", Genere: " + Genere + ", Data: \
    	 " + Giorno + "/" + Mese + "/" + Anno +  ", " +  NumeroEventi + " eventi.");
    
    		// *********Crea riga tabella sostituendo i marker con i dati reali dell'evento:
    		for (numev=1; numev<=NumeroEventi; numev++) {
    			var TitoloNormalizzato=myObject.plan[numev].normalizedtitle;
    			RigaTabella=TemplateRiga;
    			RigaTabella=RigaTabella.replace("#genere#",Genere);
    			RigaTabella=RigaTabella.replace("#telecomando#",Telecomando);
    			RigaTabella=RigaTabella.replace("#nomecanale#",NomeCanale);
    
    			var Data = "20" + Anno + "/" + Mese + "/" + Giorno;
    			var DataJS = new Date(Data);
    			RigaTabella=RigaTabella.replace("#giornosettimana#",giorni[DataJS.getDay()]);
    			RigaTabella=RigaTabella.replace("#data#","20" + Anno + "/" + Mese + "/" + Giorno + " (" + MeseStr[parseInt(Mese)-1] + ")");
    			RigaTabella=RigaTabella.replace("id",myObject.plan[numev].id);
    			RigaTabella=RigaTabella.replace("pid",myObject.plan[numev].pid);
    			RigaTabella=RigaTabella.replace("starttime",myObject.plan[numev].starttime);
    			RigaTabella=RigaTabella.replace("dur",myObject.plan[numev].dur);
    			RigaTabella=RigaTabella.replace("title",myObject.plan[numev].title);
    			RigaTabella=RigaTabella.replace("desc",myObject.plan[numev].desc);
    			RigaTabella=RigaTabella.replace("genre",myObject.plan[numev].genre);
    			RigaTabella=RigaTabella.replace("subgenre",myObject.plan[numev].subgenre);
    			RigaTabella=RigaTabella.replace("chanpos",nome.substr(3,nome.indexOf('-')-3));
    
    			var URLDettagli = "http://guidatv.sky.it/EpgBackend/event_description.do?eid=EEEEEEEE";
    			URLDettagli=URLDettagli.replace("EEEEEEEE",myObject.plan[numev].id)
    			RigaTabella=RigaTabella.replace("#filedet#","<a href='" + URLDettagli + "' target='dettagli'>Link</a>");
    
    			var URLEvento="http://guidatv.sky.it/guidatv/programma/" + myObject.plan[numev].genre + "/" + myObject.plan[numev].subgenre + "/" + TitoloNormalizzato + "_" + myObject.plan[numev].pid + ".shtml?eventid=" + myObject.plan[numev].id;
    			RigaTabella=RigaTabella.replace("#web#","<a href='" + URLEvento + "' target='evento'>Link</a>");
    
    			var URLMese = "http://guidatv.sky.it/EpgBackend/getprogrammazione.do?idprogramma=PPP";
    			URLMese=URLMese.replace("PPP",myObject.plan[numev].pid)
    			RigaTabella=RigaTabella.replace("#mese#","<a title='mese' href='" + URLMese + "' target='mese'>Link</a>");
             TabellaFinale = TabellaFinale +  RigaTabella;
    		}
    		document.getElementById('TabellaFinale').innerHTML = TabellaFinale;
          $("table").tablesorter({sortList: [[1,0]]});
    }
    
    function LeggiDrop() {
      event.stopPropagation();
      event.preventDefault();
      files = event.dataTransfer.files;
    
    console.log("Elaboro " + (files.length) + " files...");
        if (files) {
            for (var i=0, f; f=files[i]; i++) {
    	         r =  new FileReader();
                r.onload = (function(f) {
                    return function(e) {
                        var contents = e.target.result;
                        LeggiFile(e.target.result,f.name);
                    };
                })(f);
    
    
                r.onloadend = (function(f) {
                    return function(e) {
                        //alert("Letto " + NumeroFileProcessati);
    						 if (NumeroFileProcessati>=files.length) {
    							//TabellaFinale=null;
    							//RigaTabella=null;
    							contents=null;
    							CurrentFile=null;
    							r=null;
    							files=null;
    							alert("Memo liberata?");
    						 }
                    };
                })(f);
                r.readAsText(f);
    	 console.log(NumeroFileProcessati);
            }
        } else {
    	      alert("Failed to load files");
        }
    
    }
    
    	</script>
    </head>
    
    <body>
    <div  id="drop_zone" ondragover="LeggiDragOver();" ondrop="LeggiDrop()"; >Drop files here</div>
    <input type="text" id="test" ondragover="LeggiDragOver();" ondrop="LeggiDrop()";>
    
    
    <div id="TabellaFinale">
    	<table border="1">
    	</table>
    </div>
    
    
    </body>
    </html>
    You must drop in the drag&drop area files like this:
    http://guidatv.sky.it/app/guidatv/co...1_29/ch_899.js

    But I previously rename them, using another script, in this way:
    ch_899-(channelname,channelcode,channelgenre)-guidatv.sky.it-app-guidatv-contenuti-data-grid-15_01_29.js

    I'm working with Chrome 22.0:
    • If you press SHIFT+ESC while the script is running, you can see the memory growing and growing.
    • If you open the console window (CTRL+SHIFT+J) , you can also see the script execution slowing down and down...

  4. #4
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    1,159
    Alright, so after some fiddling around I narrowed down the problem. Surprisingly, your code efficiency issue comes from one single line of code:
    Code:
    TabellaFinale = TabellaFinale +  RigaTabella;
    You can play around with this by commenting out that one line in your _LeggiFile() function. If I took out the function entirely, the script seemed to complete in no more than a second. Commenting out that one single line also allowed the script to seemingly finish in the same amount of time. Or in other words, that line is where all the 'hard work' is happening and ther reason for the slowing of the script. It is likely causing your memory issues as well.

    The problem is with the string concatenation. There was actually a really awesome article by a guy named Joseph Myers that covered a lot of optimizations with javascript code. Your 'TabellaFinal' variable is a string that basically becomes ridiculously large. And since it's being concatenated within that loop, you not only have the browser store a large string, but then it must continually append more onto the string.

    Sparing all the 'mumbo jumbo', there are a number of ways this could be addressed. Unfortunately due to a lot of your code being in a language other than English, it takes me a bit more time than usual to decipher exactly what's going on and what needs to happen. I do have an improvement you could use, but this is more about a concept. My tests were using 280 files following the example file you gave. The script isn't as fast as I want it (and probably not as fast as you'd like either), but it's a drastic improvement, finishing my 280 file test in about 5 seconds.

    The concept is to not store your entire table (which is extremely large being that it contains over 1,000 rows in your example) in one single string. Instead, you would actually append these rows to your table as they are processed, freeing up memory and preventing bottlenecks in speed. Using document.createElement() you can create a new row element (<tr>). Ideally, you'd want to also use .createElement() to create the <td> elements as well, which I did not do for my example. But this isn't a huge issue. Because I didn't want to do a huge revamp of all of your code, I have the initial part of the table HTML already in your <div>. I also had to set the ID of your table, rather than using the ID on the <div> like you had initially. There were other small tweaks, like not repeating 'var' in your declarations (you can just use the word 'var' once and separate each new one with a comma). I also do have your tablesorter line commented out, but that was due to not being sure how to rework that bit of code. Technically that line is called once per file (or row added). But it almost seems like you'd actually only want it to be called once, when the entire table is ready. For that reason I left it out beacuse I felt it needed to be elsewhere, but wasn't sure where that would be (yet).

    Anyway, enough ramblings, here's my suggestion:
    HTML Code:
    <!DOCTYPE html>
    <html>
    <head>
    	<style>
    		.example {
    		  padding: 10px;
    		  border: 1px solid #ccc;
    		}
    		#drop_zone {
    		  border: 2px dashed #bbb;
    		  -moz-border-radius: 5px;
    		  -webkit-border-radius: 5px;
    		  border-radius: 5px;
    		  padding: 25px;
    		  text-align: center;
    		  font: 20pt bold 'Vollkorn';
    		  color: #bbb;
    		}
    	</style>
    </head>
    <body>
    
    	<div id="drop_zone" ondragover="LeggiDragOver();" ondrop="LeggiDrop()"; >Drop files here</div>
    	<input type="text" id="test" ondragover="LeggiDragOver();" ondrop="LeggiDrop()";>
    
    
    	<div>
    		<table id="TabellaFinale" border="1" id="table" class="tablesorter">
    			<thead>
    				<th>Genere canale</th>
    				<th>(codice canale)</th>
    				<th>Posizione canale</th>
    				<th>Nome canale</th>
    				<th>Giorno settimana</th>
    				<th>Data</th>
    				<th>Id Evento</th>
    				<th>(ID interno)</th>
    				<th>Orario</th>
    				<th>Durata (min.)</th>
    				<th>Titolo</th>
    				<th>Estratto della trama</th>
    				<th>Genere evento</th>
    				<th>Tipo di evento</th>
    				<th>File dettagli</th>
    				<th>Pagina web evento</th>
    				<th>Pagina web programmazione mensile</th>
    			</thead>
    		</table>
    	</div>
    
    	
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
      <script src="jquery.tablesorter.js"></script>
    	<script>
    		var CurrentFile,
    			files,
    			NumeroFileProcessati=0,
    			giorni = ["Domenica", "Lunedý", "Martedý", "Mercoledý", "Giovedý", "Venerdý", "Sabato"],
    			MeseStr = ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"];
    
    
    		function LeggiDragOver(evt) {
    		}
    
    		function LeggiDragEnter(evt) {
    			alert("in");
    		}
    
    		function LeggiFile(contenuto, nome) {
    			NumeroFileProcessati++;
    
    			var RigaTabella="";
    				FileContents = contenuto, // legge intero file
    				myObject = JSON.parse(FileContents), // trasforma testo JSON in oggetto Javascript
    				Palinsesto = myObject.plan, // L'oggetto contiene l'array PLAN che Ŕ il palinsesto del canale
    				NumeroEventi = Palinsesto.length-1, // Legge numero elementi (ma il primo Ŕ vuoto)
    
    				InizioNome = nome.indexOf("(")+1,
    				FineNome = nome.indexOf(",",InizioNome)+1,
    				LunghezzaNome = FineNome - InizioNome - 1,
    				NomeCanale=nome.substr(InizioNome,LunghezzaNome),
    
    				InizioTelecomando = FineNome,
    				FineTelecomando = nome.indexOf(",",InizioTelecomando)+1,
    				LunghezzaTelecomando = FineTelecomando - InizioTelecomando - 1,
    				Telecomando = nome.substr(InizioTelecomando,LunghezzaTelecomando),
    
    				InizioGenere = FineTelecomando,
    				FineGenere = nome.indexOf(")",InizioGenere)+1,
    				LunghezzaGenere = FineGenere - InizioGenere - 1,
    				Genere = nome.substr(InizioGenere,LunghezzaGenere),
    
    				InizioData =  nome.indexOf("-grid")+6,
    				FineData = nome.indexOf(".",InizioData)+1,
    				LunghezzaData = FineData - InizioData - 1,
    				Data = nome.substr(InizioData,LunghezzaData),
    				Giorno=Data.substr(6,2),
    				Mese=Data.substr(3,2),
    				Anno=Data.substr(0,2);
    
    			console.log("File n." + NumeroFileProcessati + " su " + files.length + " (" + Math.round(100*(NumeroFileProcessati/files.length)) + "%) - Nome: " + NomeCanale + ", Telecomando: " + Telecomando + ", Genere: " + Genere + ", Data: \
    			" + Giorno + "/" + Mese + "/" + Anno +  ", " +  NumeroEventi + " eventi.");
    
    			// *********Crea riga tabella sostituendo i marker con i dati reali dell'evento:
    			for(numev=1; numev<=NumeroEventi; numev++) {
    				var TitoloNormalizzato=myObject.plan[numev].normalizedtitle,
    					Data = "20" + Anno + "/" + Mese + "/" + Giorno,
    					DataJS = new Date(Data),
    					$newRow = document.createElement("tr");
    					
    				$newRow.innerHTML = '<td>'+Genere+'</td>\
    					<td>'+nome.substr(3,nome.indexOf('-')-3)+'</td>\
    					<td>'+Telecomando+'</td>\
    					<td>'+NomeCanale+'</td>\
    					<td>'+giorni[DataJS.getDay()]+'</td>\
    					<td>'+"20" + Anno + "/" + Mese + "/" + Giorno + " (" + MeseStr[parseInt(Mese)-1] + ")"+'</td>\
    					<td>'+myObject.plan[numev].id+'</td>\
    					<td>'+myObject.plan[numev].pid+'</td>\
    					<td>'+myObject.plan[numev].starttime+'</td>\
    					<td>'+myObject.plan[numev].dur+'</td>\
    					<td>'+myObject.plan[numev].title+'</td>\
    					<td>'+myObject.plan[numev].desc+'</td>\
    					<td>'+myObject.plan[numev].genre+'</td>\
    					<td>'+myObject.plan[numev].subgenre+'</td>\
    					<td><a href="http://guidatv.sky.it/EpgBackend/event_description.do?eid='+myObject.plan[numev].id+'" target="dettagli">Link</a></td>\
    					<td><a href=http://guidatv.sky.it/guidatv/programma/'+myObject.plan[numev].genre+'/'+myObject.plan[numev].subgenre+'/'+TitoloNormalizzato+'_'+myObject.plan[numev].pid+'.shtml?eventid='+myObject.plan[numev].id+'" target="evento">Link</a></td>\
    					<td><a title="mese" href="http://guidatv.sky.it/EpgBackend/getprogrammazione.do?idprogramma='+myObject.plan[numev].pid+'" target="mese">Link</a></td>\
    					<td></td>';
    				
    				document.getElementById("TabellaFinale").appendChild($newRow);
    			}
    			//$("table").tablesorter({sortList: [[1,0]]});
    		}
    
    		function LeggiDrop() {
    			event.stopPropagation();
    			event.preventDefault();
    			files = event.dataTransfer.files;
    
    			console.log("Elaboro " + (files.length) + " files...");
    			if(files) {
    				for (var i=0, f; f=files[i]; i++) {
    					r =  new FileReader();
    					r.onload = (function(f) {
    						return function(e) {
    							var contents = e.target.result;
    							LeggiFile(e.target.result,f.name);
    						};
    					})(f);
    
    
    					r.onloadend = (function(f) {
    						return function(e) {
    							if(NumeroFileProcessati>=files.length) {
    								alert("Memo liberata?");
    							}
    						};
    					})(f);
    					r.readAsText(f);
    					console.log(NumeroFileProcessati);
    				}
    			} else {
    				alert("Failed to load files");
    			}
    		}
    	</script>
    
    </body>
    </html>

  5. #5
    Join Date
    Jan 2015
    Posts
    6
    Thanks for your help.
    I also found out that that string concatenation was messing up memory, but I am not able to find an alternative method; I could just write the line to a file rather than into memory, but writing to files from within a browser is a pain.

    I'll try your code... but unfortunately Chrome suddenly auto-updated from 22.0 to 40.0 (I spent months trying updating it manually because autoupdates failed, and now it updated without me doing anything...), and now both my original source and yours do not work at all due to some changes in File API: now Chrome complains about readAsText() argument not being a blob...

    I'll do some tests.

  6. #6
    Join Date
    Jan 2015
    Posts
    6
    By the way, if you could also explain how in the world is possible that sometimes my estrai-palinsesti.html file completely disappears from my hard disk without me doing anything...
    It already happened two times: I press F5, Chrome complains for missing file, I check and it's actually disappeared! I was lucky because my text editor was still open and I had just to save the file again... but it's a crazy thing! Files do not just disappear!

  7. #7
    Join Date
    Jan 2015
    Posts
    6
    Ops, I can't edit my previous mex... estrai-palinsesti.html is the name of my source.

  8. #8
    Join Date
    Jan 2015
    Posts
    6
    I don't know what I am doing... Now Chrome does not complain any more about the blob, but it just does not detect the drag&drop.

    Fortunately, I just had to add this function, which in 22.0 was unnecessary so I had "deactivated" it:

    Code:
    function LeggiDragOver(evt) {
      event.stopPropagation();
      event.preventDefault();
    }
    Script is now actually very fast, but memory is still an issue: it does not reach 1 GB... "just" 745 MB! But if I save the page it results in a file 47 MB long. This method of handling memory is quite weird...

    I'll continue looking for a method to directly write to a file. Or maybe just into a textarea to manually copy and paste its contents into excel...

  9. #9
    Join Date
    Mar 2005
    Location
    Behind you...
    Posts
    1,159
    Honestly, it looks like the way browsers handle memory is just going to be somewhat of a limiting factor for you here. While there are still a few minor optimizations that could be made, you aren't going to see drastic results.

    Little things like this line:
    Code:
    var RigaTabella="";
    Where that semi colon should be a comma (typo on my part for the code I submitted here). And the line:
    Code:
    r =  new FileReader();
    You could put a 'var' declaration in front of it so that 'r' doesn't become a global var. But again, even these little things just free up minor bits of memory.

    One notable thing I noticed is that in an example where I used 1,680 files (each 15 KB), there were actually 85,680 rows added to the table. This seems to be due to the fact that each file can write multiple rows to the table. Once I noticed this then everything seemed more normal.

    Right now my chrome tab is using 981,764 KB of memory after loading the 1,680 files. Each file is exactly 14.1 KB. But if I divide the total memory being used by the 85,680 rows I get 11.46 (rounded)(and this ignores the initial memory being taken up by the browser tab). Which would make it seem like each row in the table takes up about 11.46 KB of memory. All of this makes it seem like there really isn't anything unusual going on here.

    Again, some minor optimizations could be made, but you aren't going to see drastic results. Unfortunately it just looks like this script is really writing that much data on the page.

  10. #10
    Join Date
    Jan 2011
    Posts
    234
    you are using new FileReader() in a loop;
    Do you have any idea how many FileReader API's are you loading on the document not taking into account the amount of data loaded because most of it will probably get cached but the API's need to stay in memory.
    Why not use the same FileReader to read all the files sequentially ?

    p.s.: who wrote this piece of junk anyway?

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles