11499 sujets

JavaScript, DOM et API Web HTML5

Bonsoir à tous.


J'ai un énorme besoin de vous !
J'ai un code qui s'exécute sans bug apparent...

Par contre, je trouve que ma page se met à jour
de façon trop lente, quand on bouge les slider-controls
(dans le 1er pavé blanc).

Je n'en trouve pas la raison !

Avez-vous un peu de temps à me consacrer ?
Pouvez-vous m'aider ?
D'avance, un IMMENSE merci !
Voici la page en question
Modifié par jytest (24 May 2013 - 19:51)
Salut,

Tout d'abord, tu as un délais assez important (3-4 secondes) avant d'envoyer ta requête au serveur. C'est énorme!

Ensuite, ton serveur est incroyablement lent (1.5s de transfert et 500ms de traitement ici). Essaie de limiter les vas et viens vers la database, réduit au maximum les requêtes. Pour le temps de transfert... Dur à dire, tu as peut-être seulement un mauvais serveur (si tu es en mutualisé c'est "normal").
Merci pour ta réponse.

a écrit :
Tout d'abord, tu as un délais assez important (3-4 secondes) avant d'envoyer ta requête au serveur. C'est énorme!

Que faire pour réduire ces temps ?
Apparemment, cela proviendrait de ma fonction "newrecherche()"...
Un indice peut-être, j'utilise json... avec le jquery dataTables

Je joins le code de cette fonction, ci-dessous :

	function newrecherche() {
		url();
		oTable = $('#example').dataTable( {
			"bDestroy": true,
			"sScrollY": example,
//			"bPaginate": false,
			"bFilter": false,
			"bInfo": false,
//			"bScrollInfinite": true,
			"bScrollCollapse": true,
			"BJQueryUI" : false,
			"aoColumns": [
				{ "sTitle": "comparer",		"bSortable": false,
				"sClass": "alignCenter", 	"bVisible": true,							},
				{ "sTitle": "forme",		"bSortable": true,
				"sClass": "alignLeft",    	"bVisible": true							},
				{ "sTitle": "carat",		"bSortable": true,
				"sClass": "alignRight",  	"bVisible": true							},
				{ "sTitle": "taille",		"bSortable": true,
				"sClass": "alignCenter",  	"bVisible": true							},
				{ "sTitle": "couleur",		"bSortable": true,
				"sClass": "alignCenter",  	"bVisible": true							},
				{ "sTitle": "pureté",		"bSortable": true,
				"sClass": "alignCenter",  	"bVisible": true							},
				{ "sTitle": "poli",			"bSortable": true,
				"sClass": "alignCenter",	"bVisible":	(swColonne[11]==1)?true:false	},
				{ "sTitle": "symétrie",		"bSortable": true,
				"sClass": "alignCenter", 	"bVisible":	(swColonne[12]==1)?true:false	},
				{ "sTitle": "prof.",		"bSortable": true,
				"sClass": "alignRight",  	"bVisible":	(swColonne[13]==1)?true:false	},
				{ "sTitle": "table",		"bSortable": true,
				"sClass": "alignRight",  	"bVisible":	(swColonne[14]==1)?true:false	},
				{ "sTitle": "fluorescence",	"bSortable": true,
				"sClass": "alignCenter", 	"bVisible":	(swColonne[15]==1)?true:false	},
				{ "sTitle": "prix/ct",		"bSortable": true,
				"sClass": "alignRight",  	"bVisible":	(swColonne[16]==1)?true:false	},
				{ "sTitle": "colette",		"bSortable": true,
				"sClass": "alignCenter", 	"bVisible":	(swColonne[17]==1)?true:false	},
				{ "sTitle": "Lg/lg",		"bSortable": true,
				"sClass": "alignRight",  	"bVisible":	(swColonne[18]==1)?true:false	},
				{ "sTitle": "délai",		"bSortable": true,
				"sClass": "alignRight",  	"bVisible": true							},
				{ "sTitle": "certificat",	"bSortable": true,
				"sClass": "alignCenter",  	"bVisible": true							},
				{ "sTitle": "prix",			"bSortable": true,
				"sClass": "alignRight",  	"bVisible": true							},
				{ "sTitle": "détail",		"bSortable": false,
				"sClass": "alignLeft",  	"bVisible": true							}
			],
			"sAjaxSource": "js/dt/chargementdata00.php" + argurl,
			"bDeferRender": true,
			"bServerSide": true,
			"sDom": "frtiS",
			"oScroller": {
				"loadingIndicator": true
			},
			"oLanguage": {
				"sLoadingRecords": "<img src='images/general/roulette.gif' width='16' height='16'>&nbsp;&nbsp;Chargement en cours...",
				"sZeroRecords":  "Aucun diamant n'a pu être trouvé !"
			},
			"sScrollX": "100%",
			"sScrollXInner": coef,
			"fnServerData": function ( sSource, aoData, fnCallback ) {
				aoData.push( { "name": "more_data", "value": "my_value" } );
				$.getJSON( sSource, aoData, function (json) {
					maxref = json.iTotalRecords;
					triref = json.iTotalDisplayRecords;
					nbreference();
					fnCallback(json);
				} );
        	},
			"fnInitComplete": function() {

			},
       		"aaSorting": [[ 16, "asc" ]]
		} );
		$(".dataTables_scrollBody").height(example);
		$(".dataTables_scrollHead").height("25px");
	}
PS "url()" ne pose pas de souci, ni en vitesse non plus !

Je vous joins aussi "chargementdata00.php", ci-dessous :

 <?php
	session_start();

	$nbcomparer = 0;
	if (isset($_SESSION['recherche'])) {
		if ($_SESSION['recherche']['stringcomparer'] != "") {
			unset($refcomparer);
			$refcomparer = explode(":", $_SESSION['recherche']['stringcomparer']);
			$nbcomparer = count($refcomparer);
		}
	}
	
	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	 * libellés types
	 * 0 = forme
	 * 3 = taille
	 * 4 = couleur
	 * 5 = pureté
	 * 6 = poli
	 * 7 = symetrie
	 * 10 = fluo
	 */
	$libelle = array();
	$libelle[1] = array ("", "Rond", "Princesse", "Emeraude", "Radiant", "Ovale", "Poire", "Marquise", "Coeur", "Asscher CS");
	$libelle[4] = array ("D", "E", "F", "G", "H", "I", "J", "K");
	$libelle[3] = array ("Faible", "Bon", "Très bon", "Excellent", "Idéal");
	$libelle[5] = array ("IF", "VVS1", "VVS2", "VS1", "VS2", "SI1", "SI2", "SI3", "I1");
	$libelle[6] = array ("Faible", "Bon", "Très bon", "Excellent", "Idéal");
	$libelle[7] = array ("Faible", "Bon", "Très bon", "Excellent", "Idéal");
	$libelle[10] = array ("Sans", "Très légère", "Légère", "Faible", "Moyenne", "Forte", "Très forte");
	$libelle[12]  = array ("Pointue", "Très petite", "Petite", "Moyenne", "Large");
	$libelle[15]  = array ("", "GIA", "HRD", "IGI", "EGL", "AGS");

	/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
	 * Easy set variables
	 */
 
	/* Array of database columns which should be read and sent back to DataTables. Use a space where
	 * you want to insert a non-database field (for example a counter or static image)
	 */
	$aColumns = array();
	$aColumns [] = 'item_id';				/* 00					*/
	$aColumns [] = 'cut';					/* 01					*/
	$aColumns [] = 'carat';					/* 02					*/
	$aColumns [] = 'cut_grade';				/* 03					*/
	$aColumns [] = 'color';					/* 04					*/
	$aColumns [] = 'clarity';				/* 05					*/
	$aColumns [] = 'polish';				/* 06	option11		*/
	$aColumns [] = 'symmetry';				/* 07	option12		*/
	$aColumns [] = 'depth';					/* 08	option13		*/
	$aColumns [] = 'table'; 				/* 09	option14		*/
	$aColumns [] = 'fluo_intensity';		/* 10	option15		*/
	$aColumns [] = 'price_per_carat_ht';	/* 11	option16		*/
	$aColumns [] = 'culet_size';			/* 12	option17		*/
	$aColumns [] = 'length_width';			/* 13	option18		*/
	$aColumns [] = 'delay';					/* 14					*/
	$aColumns [] = 'certificat';			/* 15					*/
	$aColumns [] = 'total_price_ht';		/* 16					*/
	$aColumns [] = 'item_id';				/* 17					*/
 
	/* Indexed column (used for fast and accurate table cardinality) */
	$sIndexColumn = "item_id";
 
	/* DB table to use */
	$sTable = "diamant_data";
 
	/* Database connection information */
	$gaSql['user']       = "***";
	$gaSql['password']   = "***";
	$gaSql['db']         = "***";
	$gaSql['server']     = "***";
 
 
	/* 
	 * MySQL connection
	 */
	$gaSql['link'] =  mysql_pconnect( $gaSql['server'], $gaSql['user'], $gaSql['password']  ) or
		die( 'Could not open connection to server' );
 
	mysql_select_db( $gaSql['db'], $gaSql['link'] ) or 
		die( 'Could not select database '. $gaSql['db'] );
 
	mysql_set_charset( 'utf8' ); 	


	/* 
	 * Paging
	 */
	$sLimit = "";
	if ( isset( $_GET['iDisplayStart'] ) && $_GET['iDisplayLength'] != '-1' )
	{
		$sLimit = "LIMIT ".intval( $_GET['iDisplayStart'] ).", ".
			intval( $_GET['iDisplayLength'] );
	}
 
 
	/*
	 * Ordering
	 */
	$sOrder = "";
	if ( isset( $_GET['iSortCol_0'] ) )
	{
		$sOrder = "ORDER BY  ";
		for ( $i=0 ; $i<intval( $_GET['iSortingCols'] ) ; $i++ )
		{
			if ( $_GET[ 'bSortable_'.intval($_GET['iSortCol_'.$i]) ] == "true" )
			{
				$sOrder .= "`".$aColumns[ intval( $_GET['iSortCol_'.$i] ) ]."` ".
					($_GET['sSortDir_'.$i]==='asc' ? 'asc' : 'desc') .", ";
			}
		}
 
		$sOrder = substr_replace( $sOrder, "", -2 );
		if ( $sOrder == "ORDER BY" )
		{
			$sOrder = "";
		}
	}


	/* 
	 * Filtering
	 * NOTE this does not match the built-in DataTables filtering which does it
	 * word by word on any field. It's possible to do here, but concerned about efficiency
	 * on very large tables, and MySQL's regex functionality is very limited
	 */
	$sWhere = "";
	if ( $_GET['sSearch'] != "" )
	{
		$sWhere = "(";
		$aWords = preg_split('/\s+/', $_GET['sSearch']);
		for ( $j=0 ; $j<count($aWords) ; $j++ )
		{
			if ( $aWords[$j] != "" )
			{
				$sWhere .= "(";
				for ( $i=0 ; $i<count($aColumns) ; $i++ )
				{
					$sWhere .= "`".$aColumns[$i]."` LIKE '%".mysql_real_escape_string( $aWords[$j] )."%' OR ";
				}
				$sWhere = substr_replace( $sWhere, "", -3 );
				$sWhere .= ") AND ";
			}
		}
		
		$sWhere = substr_replace( $sWhere, "", -5 );
		$sWhere .= ")";
	}
	
	/* Individual column filtering */
	$sColumnWhere = "";
	for ( $i=0 ; $i<count($aColumns) ; $i++ )
	{	
		if ( $_GET['sSearch_'.$i] != "" )
		{
			$aWords = preg_split('/\s+/', $_GET['sSearch_'.$i]);
			$sColumnWhere .= "(";
			for ( $j=0 ; $j<count($aWords) ; $j++ )
			{
				if ( $aWords[$j] != "" )
				{
					$sColumnWhere .= "`".$aColumns[$i]."` = '".mysql_real_escape_string( $libelle[ $i ][ $aWords[$j] ] )."' OR ";
				}
			}
			$sColumnWhere = substr_replace( $sColumnWhere, "", -3 );
			$sColumnWhere .= ") AND ";
		}
		if ( $_GET['sStart_'.$i] != "" AND $_GET['sEnd_'.$i] != "" )
		{
			$sColumnWhere .= "(";
			$sColumnWhere .= "`".$aColumns[$i]."` >= '".mysql_real_escape_string( $_GET['sStart_'.$i] )."' AND `".$aColumns[$i]."` <= '".mysql_real_escape_string( $_GET['sEnd_'.$i] )."' ";
			$sColumnWhere .= ") AND ";
		}
	}
	
	if ( $sColumnWhere != "" ) {
		$sColumnWhere = substr_replace( $sColumnWhere, "", -5 );
		if ( $sWhere == "" ) {
			$sWhere = $sColumnWhere;
		} else {
			$sWhere .= " AND ".$sColumnWhere;
		}
	}
	
	if ( $sWhere != "" )
	{
		$sWhere = "WHERE ".$sWhere;
	}
 
 
	/*
	 * SQL queries
	 * Get data to display
	 */
	$sQuery = "
	 SELECT SQL_CALC_FOUND_ROWS `".str_replace(" , ", " ", implode("`, `", $aColumns))."` 
		FROM   $sTable
		$sWhere
		$sOrder
		$sLimit
		";
	$rResult = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
 
	/* Data set length after filtering */
	$sQuery = "
		SELECT FOUND_ROWS()
	";
	$rResultFilterTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
	$aResultFilterTotal = mysql_fetch_array($rResultFilterTotal);
	$iFilteredTotal = $aResultFilterTotal[0];
 
	/* Total data set length */
	$sQuery = "
		SELECT COUNT(`".$sIndexColumn."`)
		FROM   $sTable
	";
	$rResultTotal = mysql_query( $sQuery, $gaSql['link'] ) or die(mysql_error());
	$aResultTotal = mysql_fetch_array($rResultTotal);
	$iTotal = $aResultTotal[0];
 
 
	/*
	 * Output
	 */
	$output = array(
		"sEcho" => intval($_GET['sEcho']),
		"iTotalRecords" => $iTotal,
		"iTotalDisplayRecords" => $iFilteredTotal,
		"aaData" => array()
	);
 
	while ( $aRow = mysql_fetch_array( $rResult ) )
	{
				$on=0;
				$comparer = trim($aRow[ 'item_id' ]);
                                if ($nbcomparer > 0) {
				for ($krow=0; $krow<$nbcomparer; $krow++) {
					if ($refcomparer[$krow] == $comparer) {
						array_splice($refcomparer,$krow,1);
						$nbcomparer--;
						$on=1;
						break;
					}
				}
                                }
				$row = array();
				$row[] = "<div id='tag".$comparer."'><input id='comparer[".$comparer."]' type='checkbox' class='curseur' onclick='acomparer(".$comparer.");'"
				.($on==1?' CHECKED':'')."></div> ";
				$row[] = trim($aRow[ 'cut' ]);
				$inter = trim($aRow[ 'carat' ]);
				$row[] = number_format($inter, 2, ',', ' ');
				$row[] = trim($aRow[ 'cut_grade' ]);
				$row[] = trim($aRow[ 'color' ]);
				$row[] = trim($aRow[ 'clarity' ]);
				$row[] = trim($aRow[ 'polish' ]);
				$row[] = trim($aRow[ 'symmetry' ]);
				$inter = trim($aRow[ 'depth' ]);
				if (floatval($inter)>0) {
					$row[] = number_format($inter, 2, ',', ' ');
				} else {
					$row[] = "";
				}
				$inter = trim($aRow[ 'table' ]);
				if (floatval($inter)>0) {
					$row[] = number_format($inter, 2, ',', ' ');
				} else {
					$row[] = "";
				}
				$row[] = trim($aRow[ 'fluo_intensity' ]);
				$inter = trim($aRow[ 'price_per_carat_ht' ]);
				$row[] = number_format($inter, 0, ',', ' ');
				$row[] = trim($aRow[ 'culet_size' ]);
				$inter = trim($aRow[ 'length_width' ]);
				if (floatval($inter)>0) {
					$row[] = number_format($inter, 2, ',', ' ');
				} else {
					$row[] = "";
				}
				$inter = trim($aRow[ 'delay' ]);
				if (floatval($inter) == 0) {
					$row[] = "nc";
				}
				if (floatval($inter) == 1) {
					$row[] = $inter." jour";
				}
				if (floatval($inter) > 1) {
					$row[] = $inter." jours";
				}
				$row[] = trim($aRow[ 'certificat' ]);
				$inter = trim($aRow[ 'total_price_ht' ]);
				$row[] = number_format($inter, 0, ',', ' ');
				$row[] = "<a href='javascript:envoiDetails(".trim($aRow[ 'item_id' ]).");'><span class='voir'>Détails</span></a>";
				$output['aaData'][] = $row;
	}

	echo json_encode( $output );
?>


Pouvez-vous m'aider ?
Modifié par jytest (23 May 2013 - 22:54)
Indépendamment du script, tu n'emploies pas les bonnes pratiques de base pour optimiser les perfs. Il faut plusieurs secondes pour charger tes ressources. Ton serveur étant lent, vois si tu peux en changer ou basculer les fichier statiques sur un cdn. En suivant quelques règles de bases, tu devrais déjà gagner un peu de perf.
Ici, je ne comprends plus rien !
Que dois-je faire alors ?
A l'aide, svp !
Modifié par jytest (23 May 2013 - 12:36)
En premier lieu, tu fais appel à trop de ressources (js, css etc)
Essaie de réduire leur nombre, notamment en concaténant les fichiers.
Je vois également des scripts non minimifiés (ça se dit ça ?) avec jquery à +130kb...
Remplace-les par leurs versions + légères.
Ton contenu statique ne semble pas bénéficier de compression. Il faut l'activer (1,3mb(!) de gain d'après webpagetest)
Tes en-tête de cache (expires-header) sont pour la plupart à h+60mn. C'est trop court.

Tu te feras une meilleure idée du problème en regardant ce rapport sur webpagetest

Si tu veux en savoir plus, lis ces quelques chapitres et regarde ce qui passe sur ce groupe.
Modifié par paolo (24 May 2013 - 00:01)
Merci pour les éclaircissements !

a écrit :
Tu te feras une meilleure idée du problème en regardant ce rapport sur webpagetest

Ton lien ne fonctionne pas...

Je précise que mon problème n'est pas, à mes yeux, au chargement de la page.
Mais plutôt au (re)chargement de la dataTables.
Pour comprendre ma douleur, déplace un curseur de l'un des 14 slider control !
C'est ici que je voudrais arriver à faire bien mieux que 4 secondes d'attente.

Je viens de contacter "Allan" sur le forum de dataTables.net
(concepteur), il me dit que cela peut provenir du "chargementdata00.php",
qui n'est pourtant qu'une copie de leur code natif (server-processing).
http://datatables.net/forums/discussion/15658/too-slow-loading-5-seconds#Item_1

Alors que faire ?
Comment faire pour "supprimer" cette latence de 3-4 secondes ?

... Car, c'est atroce !!!!!!!
A l'aide, svp
Modifié par jytest (23 May 2013 - 14:41)
Paolo: Cependant, le problème ici n'est pas en terme de temps de chargement (bien que ce puisse être énormément optimisé). Il y a carrément une latence causé par le code.

@jytest: j'aimerais te donner une réponse simple, mais ton UI ne semble pas bloquer; c'est seulement la requête qui prend un temps fou à envoyer. Cela veut probablement dire que tu as un timeout ou que tu attends trop longtemps après une interaction utilisateur pour lancer ta requête (venant peut-être de datatable, mais je connais pas le plugin) - c'est là que je regarderais avant tout.

Tu peux commencer par mettre des breakpoints dans ton code aux endroits clés et regarder le cheminement au travers de ton debugger.
Modifié par SBoudrias (23 May 2013 - 19:31)
Mes slider controls ne posent pas de soucis !
Je confirme bien que mon problème est au niveau du dataTables.

Pour arriver à mes fins, j'ai dû utiliser plusieurs plugins additionnels au dataTables (scrolling + server-processing).
Pour votre information, selon les concepteurs de dataTables,
la lenteur d'excécution proviendrait du server-processing
(appelé chez moi, "chargementdata00.php") !
Mais je ne vois pas ce qui change par rapport à leur code de base !


<script type="text/javascript" src="js/dt/jquery.dataTables.js"></script>
<script type="text/javascript" src="js/dt/jquery.dataTables.scroller.js"></script>


Hélàs, leur support n'est pas assez rempli d'exemples pour des "applications" étoffées.
De plus, les recherches sur internet ne sont pas fructueuses.

Mon rêve serait de "rencontrer" une personne qui maîtrise dataTables sur le bout des doigts.
J'ai déjà tenté de demander de l'aide sur plusieurs forums, quels qu'ils soient...

Mais peine perdue... Ce complexe jquery n'est pas la tasse de thé de bon nombre de développeurs...

a écrit :

@jytest: j'aimerais te donner une réponse simple, mais ton UI ne semble pas bloquer; c'est seulement la requête qui prend un temps fou à envoyer. Cela veut probablement dire que tu as un timeout ou que tu attends trop longtemps après une interaction utilisateur pour lancer ta requête (venant peut-être de datatable, mais je connais pas le plugin) - c'est là que je regarderais avant tout.

Moi aussi ! Mais je n'y arrive pas !
Une bonne âme pourrait-elle tenter de m'aider concrètement ?

a écrit :

Tu peux commencer par mettre des breakpoints dans ton code aux endroits clés et regarder le cheminement au travers de ton debugger.

Je tente cette approche depuis 2 jours !
Je n'y arrive pas ! A l'aide !

Je crois que je viens de trouver le code qui pose lenteur.
Il s'agit de "js/dt/jquery.dataTables.scroller.js".
Mes connaissances en js sont si maigres que je n'y arrive pas !

Ici, peut-être ?

A l'aide !
Modifié par jytest (24 May 2013 - 08:46)
Autre solution à, peut-être, envisager !

Mon client est chez "amen.fr" ?
Certains ont-ils déjà rencontré des soucis avec cet hébergeur ?