Mise a jour dynamique d'un textarea

Statut
N'est pas ouverte pour d'autres réponses.

SaYnGarD

Touriste
Bonjour a tous,

J'ai encore quelque petit problème avec des mise a jour d'ynamique pour une interface web ^^

Voila je probleme:

Dans ma page j'ai un <textarea> dont le contenu est mis a jour toutes les secondes, a chaque cycle une ligne est ajouter dans mon textearea. Pour avoir ce resultat je fais :
$('idConteneur').value += "Ma chaine";

Ca marche mais apres quelque temps de focntionnement, le browser devient de plus en plus lent et la charge sur le cpu du client devient execivement haute. Résultat même le refraichisement de la page ne se fait plus :/

je pense que le problème vienne du fait que j'utilise value += qui oblige de le browser de reevaluer tout le contenu de mon textarea.

Donc voila ma question, comment puis je faire pour avoir un affichage continu ligne par ligne sans surcharger le client ?

bien a vous.
 

Dolu

Touriste
Essaie peut-être avec des étapes intermédiaires du style :
var myString = $('idConteneur').value;
myString = myString + "TaChaine";
$('idConteneur').value = myString;
 

NoBrain

Touriste
Avec quel type de contenu le textarea est mis à jour ?
 

PiaFlalCoOl

NiuAge
T'utilises jquery pour faire $("#idconteneur") ? ou d'autres framework ont la meme syntaxe ?

Si t'utilises jquery, pour modifier la valeur fait plutot :
$("#idconteneur").val($("#idconteneur").val() + "Ma chaine");

Sinon ca commence à laguer à partir de combien de lignes à peu près ? Si tu le laisses 1h... y'a moyen que ca lag dans tous les cas.

Ou sinon tu peux garder une var en javascript auquelle tu concatènes à chaque fois "ma chaine", et tu fais simplement :

$("#idconteneur").val(varJavascript);
 

Calvin80

Respect is key
$('idConteneur') --> attention, tu vas parser ton doc a chaque fois pour trouver ton idConteneur.. mets le dans une variable une fois pour toute.
sinon, tu veux savoir si c'est le '+' qui prend de la charge ? simple: enelve le et regarde si tu as le problème avec un "=" plutot qu'un "+=".

Enfin, regarde si tu ne fais pas une fermerture (closure) dans ta fonction javascript. Elles sont très mal gérée par IE (surtout IE < IE 7) qui utilise son garbage collector comme ma grand mère utilise ma console.
 

PiaFlalCoOl

NiuAge
$('idConteneur') --> attention, tu vas parser ton doc a chaque fois pour trouver ton idConteneur.. mets le dans une variable une fois pour toute.
sinon, tu veux savoir si c'est le '+' qui prend de la charge ? simple: enelve le et regarde si tu as le problème avec un "=" plutot qu'un "+=".

Enfin, regarde si tu ne fais pas une fermerture (closure) dans ta fonction javascript. Elles sont très mal gérée par IE (surtout IE < IE 7) qui utilise son garbage collector comme ma grand mère utilise ma console.
Le cout de $('idConteneur') est négligeable je pense, et si on devait mettre dans des variables tous les sélecteurs qu'on utilise dans les évènements ajoutés au chargement de la fenêtre, ca serait pas viable.
Apres, ptêtre que pour son cas, ca peut etre utile.

tu veux savoir si c'est le '+' qui prend de la charge ? simple: enelve le et regarde si tu as le problème avec un "=" plutot qu'un "+=".
J'ai ptêtre pas compris, mais ce que tu dis n'a aucun sens... Genre tu dis : "si tu veux voir si une concaténation est couteuse en ressources, fais une simple affectation"...
Forcemment s'il ne fait que remplacer le contenu existant, y'aura pas de soucis. Et le fait qu'il n'y ai pas de prob avec = ne résoudrais pas son problème de toute facon.
 

Calvin80

Respect is key
salut Piaf.
Le $('idConteneur') a chaque boucle, c'est comme un (for i=0; i<montableau.length,i++); C'est une erreur de programmation. Si on fait de l'optimisation, autant le faire bien.
Bien entendu faut pas mettre tout en mémoire ca dépend du contexte. ICi on parle bien d'un appel toutes les secondes..

Concernant le second point, tu as tout à fait raison quand tu dis :""si tu veux voir si une concaténation est couteuse en ressources, fais une simple affectation". Mais là tu pars du principe que c'est son affectation qui bouffe des ressources (c'est certainement le cas).
Ma solution vient en amont de la tienne, à savoir : "Si tu veux savoir si c'est bien la concaténation qui pose problème, fait une affectation". C'est ce que je dis clairement dans la phrase que tu cite. J'espère que tu vois la nuance.
Comme expliqué, le problème peut venir de plusieurs autres endroits, surtout quand on ne voit pas le code (comment appelle-t-il sa fonction de mise à jour, comment fait il les "toutes les secondes", fait- il des fermetures, etc..) : mon idée est donc de cibler le problème avant de le résoudre et ma solution le permet en quelques clics.
Après ce test, je te rejoins: il faudra passer à l'étape suivante si la concaténation est bien le problème: comment optimiser la concaténation.
 

PiaFlalCoOl

NiuAge
Je voyais pas ca comme une boucle en fait.
Genre

function lalal () {

$('idConteneur') += blabla

setTimeout("lalal", 1000);

}

et donc il faudrait une var globale pour stocker le conteneur. Mais c'est pas forcemment un problème. Je suis un peu une merde en js, j'ai appris recemment et par moi même.
 

Calvin80

Respect is key
je pense qu'il utilise un setInterval plutot qu'un setTimeout.
Mais il a peut être utilisé ta solution (ou alors un autre truc qui bouffe les ressources).
SaYnGarD, tu nous donnes un feedback ?
 
1er
OP
S

SaYnGarD

Touriste
Voila desole de repondre un peu tard, mon probleme n'est toujours pas regler bien que j 'ai reussit a ameliore un peu les performance mais ca ne correspond pas encore aux exigences du projet.

Pour un peu plus d'indications, j'utilise le framework prototype.js et pour la mise a jour periodique j'utilise un periodicalUpdater qui met a jour un div. Un des problème que j'avais était le fait de faire appel a la focntion "eval" a chaque mise a jour, je l'ai enleve mais firefox continue a prendre de plus en plus de processeur en focntion du nombre de ligne affichées :/

Je continue a cherche, je vais tester les propositions que vous avez faite juste pour me donner bonne conscience :p

merci pour les reponses!
 
1er
OP
S

SaYnGarD

Touriste
Voila apres quelque tests les solutions que vous m'avez proposer m'ont permis de reduire un peu la charge sur le cpu mais pas de manière notable :/

Existe t il une manière de positionner le curseur de manière a afficher le resultat a la fin du textarea sans recopier tout le contenu de celui ci ?
 

Tifox

ou pas
Je viens de tester le bazar avec du javascript simple mais avec un refresh toute les 100ms (donc a priori 10 fois plus que toi), et ça tourne depuis 15 minutes sous IE6 et firefox 3 avec les utilisation cpu suivante, sur un vieux P4 pas Hyper Threading :
28% firefox
8% IE
Ceci dit, ça augmente lentement des 2 cotés.

Vais encore laisser tourner un peu pour voir, mais une question :
Combien de temps le script doit-il tourner ? Car si c'est plusieurs heures, ça ramera de toute manière avec cette méthode, car la page devient de plus en plus grosse. Il faudrait donc peut-être revoir le besoin.


PHP:
<html>
	<head>
		<script type="text/javascript" >
			var i = 0;
			function add() {
				var txtArea = document.getElementById('content');
				var txt = txtArea.value;
				txtArea.value = txt + " ajoutNbr" + i;
				i++;
				setTimeout('add()', 100);
			}
			
		</script>
	</head>
	<body>
		<textarea id="content" style="width: 100%; height: 900px;">
			Coucou
		</textarea>
		
		<script type="text/javascript" >
			add();
		</script>
	</body>
	
</html>
 

PiaFlalCoOl

NiuAge
Et si tu mettais var txtArea = document.getElementById('content'); à l'extérieur de la fonction add, ca pourrait pas etre mieux ? Et utiliser un setinterval au lieu du settimeout comme le suggérait Calvin.
 
1er
OP
S

SaYnGarD

Touriste
oTu as bien compris mon problème chez moi firefox varie entre 8% et 45 voir 50% du processeur en fonction de la taille de la texte box.
toutes les seconde j'affiche environ 10 lignes ce qui correspond a ton scipt qui tourne a 100ms, sur 1 sec tu affiche 10 * "txt + " ajoutNbr" + i" ,sauf que moi le resultat est recupere a l aide d'ajax et que mes lignes sont lus longue. Maintenant je c pas si la difference au niveau de la charge cpu vient de la :/

Mon script doit afficher environ 2000 lignes donc tenir la route +- 4-5 min.
 
1er
OP
S

SaYnGarD

Touriste
Et si tu mettais var txtArea = document.getElementById('content'); à l'extérieur de la fonction add, ca pourrait pas etre mieux ? Et utiliser un setinterval au lieu du settimeout comme le suggérait Calvin.
déja essaier et très peu de gain de performance :/
 

PiaFlalCoOl

NiuAge
oTu as bien compris mon problème chez moi firefox varie entre 8% et 45 voir 50% du processeur en fonction de la taille de la texte box.
toutes les seconde j'affiche environ 10 lignes ce qui correspond a ton scipt qui tourne a 100ms, sur 1 sec tu affiche 10 * "txt + " ajoutNbr" + i" ,sauf que moi le resultat est recupere a l aide d'ajax et que mes lignes sont lus longue. Maintenant je c pas si la difference au niveau de la charge cpu vient de la :/

Mon script doit afficher environ 2000 lignes donc tenir la route +- 4-5 min.
T'as besoin des toutes les lignes constamment ?
Tu peux pas faire un truc du genre sauvegarder le contenu du textarea dans un fichier ou une bdd toutes les 1000 lignes par exemple puis l'effacer ? Et apres tu fais un ptit systeme qui te permet de réafficher telles ou telles lignes à la demande.
 

Tifox

ou pas
Après avoir un peu tout essayé avec un textarea (différentes manières de faire l'ajout, optimisations diverses, ...), j'ai rien de bien concluent non plus. Ma conclusion est que c'est soit la concaténation, soit le rendu du textarea qui bouffe les ressources.

J'ai fais un script qui supprime les données les plus vieilles au delà de 10000 caractères, et ça reste toujours à 2-6%cpu sous firefox (0-1 sous ie), donc il y a moyen de s'en sortir comme ça avec la proposition de PiaFlalCoOl juste au dessus.



Une solution trouvée est de se passer du textarea et de faire le rendu dans un div. Comme ça on ajoute directement un nouveau noeud au DOM, donc pas de concaténation et il faut juste faire le rendu de ce qu'on ajoute.

J'ai bricolé ça en vitesse, ça tourne à 0% de CPU depuis 10 minutes.

PHP:
<html>
	<head>
		<script type="text/javascript" >
			var i = 0;
			
			function add2() {
				var div = document.getElementById('dv');
				var tagp = document.createElement("p");
				var newText = document.createTextNode("ajoutNbr" + i);
 				tagp.appendChild(newText);
 				div.appendChild(tagp);
 				i++;
				setTimeout('add2()', 100);

			}
		</script>
	</head>
	<body>
		
		<div id="dv">
			<p>Coucou</p>
		</div>
			
		
		<script type="text/javascript" >
			add2();
		</script>
	</body>
	
</html>
Pour moi, la seule raison de vouloir un textarea est qu'il faudra faire un submit tôt ou tard du contenu vers le serveur. Mais même là, il y a moyen de se débrouillé avec ma méthode pour récupérer le contenu du div juste avant le submit, ou le faire en ajax.
 
1er
OP
S

SaYnGarD

Touriste
Ok j'y avais pense aussi mais pas essaier je vais essaier ca cette apres midi pause pour mangé oblige :D
 
1er
OP
S

SaYnGarD

Touriste
Voilà problème résolu merci beaucoup Tifox pour t'être penché sur mon problème maintenant ca marche nickel !!!
 

Tifox

ou pas
De rien ;)
 
Statut
N'est pas ouverte pour d'autres réponses.
Haut