<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>Kévin Subileau &#187; PHP, HTML et CSS</title> <atom:link href="https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/feed" rel="self" type="application/rss+xml" /><link>https://www.kevinsubileau.fr</link> <description>Espace personnel</description> <lastBuildDate>Sun, 02 Feb 2020 15:18:58 +0000</lastBuildDate> <language>fr-FR</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>Debounce et throttle : limiter les appels successifs à une fonction Javascript</title><link>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/javascript-debounce-throttle-reduire-appels-fonction.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rss</link> <comments>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/javascript-debounce-throttle-reduire-appels-fonction.html#comments</comments> <pubDate>Mon, 08 Dec 2014 20:10:41 +0000</pubDate> <dc:creator>Kévin Subileau</dc:creator> <category><![CDATA[PHP, HTML et CSS]]></category> <category><![CDATA[optimisation]]></category><guid isPermaLink="false">http://www.kevinsubileau.fr/?p=1306</guid> <description><![CDATA[Les fonctions debounce et throttle sont deux techniques très efficaces pour optimiser une application Web, en évitant les appels trop fréquents à une fonction Javascript en réaction à certains événements par exemple. <a href="https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/javascript-debounce-throttle-reduire-appels-fonction.html">Lire la Suite <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Lorsque l'on développe une application Web réagissant à certains <strong>évènements en Javascript</strong>, comme le redimensionnement de la fenêtre, le mouvement de la souris ou la frappe au clavier, les fonctions rattachées à ces événements risquent d'être appelées très fréquemment. Si le code contenu dans ces fonctions est coûteux en ressources, cela peut ralentir considérablement l'application Web.</p><p>Pour <strong>améliorer les performances</strong>, ou plutôt ne pas les plomber, il existe deux techniques simples, appelées <strong><em>debounce</em></strong> et <strong><em>throttle</em></strong>. Toutes deux permettent de <strong>réduire le nombre d'appels</strong> à une fonction <strong>dans un intervalle de temps donné</strong>. En effet, il est souvent inutile d'exécuter ces fonctions à chaque fois que l’événement est déclenché.</p><p>Imaginons par exemple que l'on souhaite synchroniser sur le serveur, via des appels AJAX, le contenu d'un champ de saisie au fur et à mesure que l'utilisateur tape le texte (comme le fait Google Docs par exemple). Dans ce cas, plutôt que de solliciter le serveur à chaque caractère saisi ou inutilement lorsque le texte reste inchangé, il peut être plus judicieux de sauvegarder le texte toutes les 5 secondes tant que l'utilisateur le modifie, et de ne plus faire de requêtes lorsque que le texte reste inchangé. Et c'est exactement ce que la fonction <em>throttle</em> permet de faire.</p><p>Cependant, bien que ces deux techniques soit assez similaires, il existe une <strong>différence fondamentale</strong> dans leurs fonctionnements qu'il est important de bien comprendre pour les utiliser correctement.</p><p>Je vais donc vous présenter ces deux méthodes l'une après l'autre, en vous expliquant leurs <strong>fonctionnements </strong>et en vous donnant le <strong>code Javascript</strong> nécessaire pour les mettre en place.<br /> <span id="more-1306"></span></p><h1><em>Debounce</em></h1><p>Commençons par la fonction <em>debounce</em>. Cette technique a pour but de <strong>n'appeler qu'une seule fois une méthode</strong> au début ou à la fin d'une succession de déclenchements d'un événement. Voici tout d'abord le <strong>code source</strong> de la fonction en question :</p><pre class="gutter: true; brush: javascript;">/**
 * Retourne une fonction qui, tant qu&#039;elle continue à être invoquée,
 * ne sera pas exécutée. La fonction ne sera exécutée que lorsque
 * l&#039;on cessera de l&#039;appeler pendant plus de N millisecondes.
 * Si le paramètre `immediate` vaut vrai, alors la fonction 
 * sera exécutée au premier appel au lieu du dernier.
 * Paramètres :
 *  - func : la fonction à `debouncer`
 *  - wait : le nombre de millisecondes (N) à attendre avant 
 *           d&#039;appeler func()
 *  - immediate (optionnel) : Appeler func() à la première invocation
 *                            au lieu de la dernière (Faux par défaut)
 *  - context (optionnel) : le contexte dans lequel appeler func()
 *                          (this par défaut)
 */
function debounce(func, wait, immediate, context) {
    var result;
    var timeout = null;
    return function() {
        var ctx = context || this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) result = func.apply(ctx, args);
        };
        var callNow = immediate &amp;&amp; !timeout;
        // Tant que la fonction est appelée, on reset le timeout.
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) result = func.apply(ctx, args);
        return result;
    };
}</pre><p>Pour mieux comprendre son fonctionnement, regardons le schéma ci dessous :</p><div id="attachment_1396" class="wp-caption aligncenter" style="width: 751px"><img class="size-full wp-image-1396" alt="js-debounce" src="http://www.kevinsubileau.fr/wp-content/uploads/2014/11/js-debounce.png" width="741" height="210" /><p class="wp-caption-text">Chronogramme de la fonction <em>debounce</em></p></div><p>Sur la première ligne de cette figure, chaque rectangle bleu représente <strong>un déclenchement de l’événement</strong> écouté (<em>keydown</em> par exemple). Lorsque deux déclenchements sont espacés par une <strong>durée inférieure à une valeur prédéfinie</strong> (paramètre <em>wait</em>), on va dire qu'ils appartiennent à <strong>une même séquence</strong>. Si la durée est supérieure, alors cela marque le début d'une nouvelle séquence.</p><p>Sur la deuxième ligne, les rectangles verts représentent les exécutions de la fonction "débouncé" (paramètre <em>func</em>). On remarque alors que la fonction <em>debounce</em> permet d'<strong>attendre la fin d'une séquence d'évènement</strong> pour effectuer le traitement associé. Si maintenant on reprend l'exemple de la synchronisation d'un champ de texte, cela signifie que l'appel AJAX sera effectué uniquement lorsque l'utilisateur cessera de modifier le contenu pendant une durée supérieure à <em>wait</em>.</p><p>Par ailleurs, dans certains cas, il peut être plus intéressant d'exécuter le traitement <strong>au début de la séquence</strong> plutôt qu'à la fin (comme le représente les rectangles violets). Cela est possible simplement en définissant le <strong>paramètre optionnel <em>immediate</em></strong> à <em>true</em>.</p><p>L'utilisation concrète de cette fonction est assez simple. Voici un exemple :</p><pre class="gutter: true; brush: javascript; highlight: [8];">function traiterEvenement() {
	// Fonction de traitement de l&#039;évenement
        // (sauvegarde par appel AJAX par exemple)
}

// On limite l’exécution de la fonction traiterEvenement à une fois
// toutes les 5000 millisecondes (5s) au maximum.
var traiterEvenementDebounce = debounce(traiterEvenement, 5000);

// On s&#039;enregistre sur l’événement de saisie clavier
document.querySelectorAll(&#039;#field&#039;)
        .addEventListener(&#039;keydown&#039;, traiterEvenementDebounce);</pre><p>Cependant, ce mode de fonctionnement <strong>peut parfois poser problème</strong>. Ici par exemple, si l'utilisateur tape son texte en continu pendant plusieurs minutes, il ne sera pas sauvegardé sur le serveur puisque la séquence ne se termine pas. Selon les cas, cela peut être souhaitable ou gênant, c'est à vous de voir. Pour éviter cela, il y a deux solutions :</p><ul><li>Soit <strong>réduire l'intervalle</strong> entre les séquences (de 5s à 500ms par exemple), en se disant que l'utilisateur ne pourra pas taper longtemps sur son clavier sans jamais s'arrêter moins de 500ms. C'est plutôt vrai, mais du coup on augmente potentiellement le nombre d’exécutions, donc ça risque d'être plus lent et ça perd un peu de son intérêt...</li><li>Soit <strong>utiliser la fonction <em>throttle</em></strong>, qui propose un fonctionnement un peu différent.</li></ul><h1><em>Throttle</em></h1><p>Parlons donc maintenant de la fonction <em>throttle</em>. Ici, comme le montre le chronogramme ci-dessous, on va exécuter la fonction de traitement de l'événement <strong>de manière périodique</strong> durant la séquence de déclenchements.</p><div id="attachment_1397" class="wp-caption aligncenter" style="width: 785px"><img class="size-full wp-image-1397" alt="js-throttle" src="http://www.kevinsubileau.fr/wp-content/uploads/2014/11/js-throttle.png" width="775" height="159" /><p class="wp-caption-text">Chronogramme de la fonction <em>throttle</em></p></div><p>Sur cette figure, les rectangles de couleur de la deuxième ligne représentes les exécutions de la fonction <em>func</em>. Attention, par défaut, seuls les rectangles violets sont effectivement exécutés. Pour inclure également les exécutions en début et/ou en fin de séquence (rectangles jaunes et verts), il faut définir respectivement les paramètres <em>leading</em> et/ou <em>trailing</em> à <em>true</em>.</p><p>Si on applique cette fonction à notre exemple, cela signifie que le texte du champ de saisie sera sauvegardé sur le serveur par un appel AJAX toutes les 5 secondes par exemple (paramètre <em>wait</em>), et ce tant que l'utilisateur change le contenu. Et si le texte n'est pas modifié, aucun appel n'est effectué. Ce comportement est donc idéal dans ce cas, puisqu'on limite le nombre d'appels au strict nécessaire pour ne pas risquer une perte de données.</p><p>Voici donc maintenant le code de la fonction <em>throttle</em> :</p><pre class="gutter: true; brush: javascript;">/**
 * Retourne une fonction qui, tant qu&#039;elle est appelée,
 * n&#039;est exécutée au plus qu&#039;une fois toutes les N millisecondes.
 * Paramètres :
 *  - func : la fonction à contrôler
 *  - wait : le nombre de millisecondes (période N) à attendre avant 
 *           de pouvoir exécuter à nouveau la function func()
 *  - leading (optionnel) : Appeler également func() à la première
 *                          invocation (Faux par défaut)
 *  - trailing (optionnel) : Appeler également func() à la dernière
 *                           invocation (Faux par défaut)
 *  - context (optionnel) : le contexte dans lequel appeler func()
 *                          (this par défaut)
 */
function throttle(func, wait, leading, trailing, context) {
    var ctx, args, result;
    var timeout = null;
    var previous = 0;
    var later = function() {
        previous = new Date;
        timeout = null;
        result = func.apply(ctx, args);
    };
    return function() {
        var now = new Date;
        if (!previous &amp;&amp; !leading) previous = now;
        var remaining = wait - (now - previous);
        ctx = context || this;
        args = arguments;
        // Si la période d&#039;attente est écoulée
        if (remaining &lt;= 0) {
            // Réinitialiser les compteurs
            clearTimeout(timeout);
            timeout = null;
            // Enregistrer le moment du dernier appel
            previous = now;
            // Appeler la fonction
            result = func.apply(ctx, args);
        } else if (!timeout &amp;&amp; trailing) {
            // Sinon on s’endort pendant le temps restant
            timeout = setTimeout(later, remaining);
        }
        return result;
    };
};</pre><p>L'utilisation de cette fonction est semblable à la fonction <em>debounce</em>, hormis les arguments optionnels qui sont différents. Voici un exemple :</p><pre class="gutter: true; brush: javascript;  highlight: [7];">function traiterEvenement() {
	// Fonction de traitement de l&#039;évenement
        // (sauvegarde par appel AJAX par exemple)
}

// Ici il est utile d&#039;activer le `trailing` pour traiter le dernier événement
var traiterEvenementThrottle = throttle(traiterEvenement, 5000, false, true);

// On s&#039;enregistre sur l’événement de saisie clavier
document.querySelectorAll(&#039;#field&#039;)
        .addEventListener(&#039;keydown&#039;, traiterEvenementThrottle);</pre><p>Les applications possibles de ces fonctions sont très nombreuses. Ici, j'ai pris l'exemple d'une fonctionnalité d'enregistrement automatique. Mais on peut aussi les utiliser pour repositionner des éléments lors du redimensionnement de la fenêtre, enregistrer des événements sur Piwik sans trop de répétitions, ...</p><p>Notez que <strong>certaines bibliothèques Javascript</strong>, comme <a href="http://lodash.com/">Lodash</a> ou <a href="http://underscorejs.org/#debounce">UnderscoreJS</a>, <strong>fournissent directement ces fonctions</strong>. Les implémentations que je vous propose ci-dessus en sont d'ailleurs inspirées. Inutile donc de les dupliquer si vous utilisez déjà une de ces bibliothèques pour votre application Web.</p><p>Enfin, bien que je parle ici de Web et de Javascript, je pense qu'il est tout à fait envisageable de reprendre le principe pour d'autres types de développement, y compris des applications bureaux en C++, C# ou Java par exemple. Étant donné la singularité de la syntaxe Javascript, il faudra en revanche revoir entièrement l'implémentation...</p><p>Voilà, j'espère que cet article vous aura aidé à comprendre l'utilité et le fonctionnement de ces fonctions. Si vous avez des questions, n'hésitez pas à me les poser en commentaire <img src='https://www.kevinsubileau.fr/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p><p><strong>Maj 12/08/2015</strong> :  En complément de cet article, je vous conseille de voir également ce <a href="http://www.grafikart.fr/tutoriels/javascript/debounce-throttle-642">tutoriel vidéo</a> que l'ami Grafikart a publié ce jour.</p> ]]></content:encoded> <wfw:commentRss>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/javascript-debounce-throttle-reduire-appels-fonction.html/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Color Thief PHP : extraire les couleurs dominantes d&#039;une image</title><link>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/color-thief-php-couleur-dominante-image.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rss</link> <comments>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/color-thief-php-couleur-dominante-image.html#comments</comments> <pubDate>Thu, 08 May 2014 16:49:34 +0000</pubDate> <dc:creator>Kévin Subileau</dc:creator> <category><![CDATA[PHP, HTML et CSS]]></category> <category><![CDATA[couleurs]]></category> <category><![CDATA[dominante]]></category> <category><![CDATA[palette]]></category><guid isPermaLink="false">http://www.kevinsubileau.fr/?p=1142</guid> <description><![CDATA[Color Thief PHP est une classe PHP qui vous permet d'extraire la couleur dominante ou une palette de couleurs à partir d'une image JPEG, GIF, ou PNG. Il s'agit d'un portage du script Javascript réalisé par Lokesh Dhakar, qui utilise un algorithme avancé de quantification des couleurs (MMCQ). <a href="https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/color-thief-php-couleur-dominante-image.html">Lire la Suite <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p><strong><a title="Color Thief PHP" href="http://www.kevinsubileau.fr/projets/color-thief-php">Color Thief PHP</a></strong> est une classe PHP qui vous permet d'<strong>extraire la couleur dominante ou une palette de couleurs à partir d'une image</strong> JPEG, GIF, ou PNG. Le projet est disponible sur <a title="Color Thief PHP" href="http://github.com/ksubileau/color-thief-php">GitHub</a>, et sur <a title="Color Thief PHP" href="http://packagist.org/packages/ksubileau/color-thief-php">Packagist</a>. Vous pouvez également voir le code en fonctionnement sur cette <a title="Color Thief PHP" href="http://www.kevinsubileau.fr/projets/color-thief-php">page de démonstration</a>.</p><p>La particularité de cette classe est qu'<strong>elle n'utilise pas une simple moyenne arithmétique</strong> pour déterminer la couleur dominante, contrairement à de nombreux scripts disponibles sur le web. En effet, cette méthode donne souvent des résultats plutôt aberrants, avec une couleur moche qui ne ressemble à rien de ce que l'on perçoit dans l'image. Ici, <strong>un algorithme avancé de quantification de couleurs est utilisé</strong>. Cet algorithme, nommé <a href="http://www.leptonica.com/papers/mediancut.pdf"><em>"Modified Mean Cut Quantizer"</em></a>, est comparable à celui utilisé par la compression JPEG. L'avantage est que les couleurs calculées sont le plus souvent <strong>visuellement très proches de celles présentes dans l'image</strong> d'origine, comme vous pouvez le voir sur l'exemple ci-dessous :</p><div id="attachment_1148" class="wp-caption aligncenter" style="width: 786px"><img class="size-full wp-image-1148" alt="color-thief-example" src="http://www.kevinsubileau.fr/wp-content/uploads/2014/05/color-thief-example.jpg" width="776" height="510" /><p class="wp-caption-text">Un exemple de palette de couleurs obtenue grâce à Color Thief PHP</p></div><p>L'<strong>utilisation de la classe est très simple</strong>, surtout si vous utilisez Composer, mais peut être assez gourmande en ressources en fonction de la taille de l'image et de la qualité demandée. Je vous conseille donc de conserver le résultat en base de données plutôt que d’exécuter le script à chaque chargement de page. Pour plus d'informations, je vous invite à vous reporter à la <a href="http://github.com/ksubileau/color-thief-php/blob/master/README.md">documentation sur GitHub</a>.</p><p>Les applications de cette classe ne sont limitées que par votre imagination : <strong>moteur de recherche par couleur</strong>, adaptation des couleurs de l'interface graphique en fonction de l'image affichée... Alex P. Gates a même développé <a href="http://alexpgates.com/blog/2013/11/scanning-colors-to-hue.html">un script PHP capable de modifier la couleur d'une lampe</a> en fonction des couleurs d'une image, en utilisant Color Thief PHP et une lampe Philips Hue.</p><p>Enfin, si vous avez besoin de cet outil coté client en Javascript, sachez qu'il s'agit en fait <strong>d'un portage d'un script javascript</strong>. Vous pouvez donc utiliser le script <a href="http://lokeshdhakar.com/projects/color-thief/">Color Thief original réalisé par Lokesh Dhakar</a>.</p> ]]></content:encoded> <wfw:commentRss>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/color-thief-php-couleur-dominante-image.html/feed</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Générer un faux texte en une ligne de PHP</title><link>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/generer-faux-texte-lorem-ipsum-en-php.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rss</link> <comments>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/generer-faux-texte-lorem-ipsum-en-php.html#comments</comments> <pubDate>Mon, 04 Nov 2013 19:53:21 +0000</pubDate> <dc:creator>Kévin Subileau</dc:creator> <category><![CDATA[PHP, HTML et CSS]]></category> <category><![CDATA[lorem ipsum]]></category> <category><![CDATA[PHP]]></category><guid isPermaLink="false">http://www.kevinsubileau.fr/?p=640</guid> <description><![CDATA[Le faux texte (lorem ipsum) est très souvent utilisé lors du développement d'un site Web. Voyez ici comment le générer simplement en une ligne de code PHP ! <a href="https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/generer-faux-texte-lorem-ipsum-en-php.html">Lire la Suite <span class="meta-nav">&#8594;</span></a>]]></description> <content:encoded><![CDATA[<p>Lorsque l'on développe un site ou une application Web, il est souvent très utile de pouvoir remplir la base de données ou la page Web de <strong>faux texte</strong>, de type <a href="http://fr.wikipedia.org/wiki/Faux-texte">Lorem ipsum</a>. En effet, cela permet de <strong>se concentrer sur le design et la mise en page</strong> sans pour autant avoir le contenu final de la page et sans que ce contenu ne détourne notre attention.</p><p>Mais plutôt que de copier/coller ces faux paragraphes sans cesse, saviez-vous qu'il est possible de<strong> le "générer" facilement avec une ligne de code PHP</strong> ? C'est plus classe, ça prend moins de place dans le code côté serveur, et surtout vous pouvez l'utiliser pour <strong>remplir la base de données</strong> et pas seulement pour l'afficher directement !</p><p>Le suspens a assez duré, <strong>voici le code en question</strong> :</p><pre class="gutter: true; brush: php;">$lipsum = simplexml_load_file(&#039;http://www.lipsum.com/feed/xml?amount=1&amp;what=paras&amp;start=0&#039;)-&gt;lipsum;</pre><p>Bon, ok, j'ai un peu triché. En réalité, on ne génère pas réellement le <em>lipsum</em> en PHP, mais on utilise plutôt l'API du site <a href="http://lipsum.com/">lipsum.com</a>. Mais peu importe, le but principal est atteint, on a <strong>un faux texte en une ligne de PHP</strong> !</p><p>Pour allez plus loin, vous pouvez transformer cette simple ligne en une fonction un peu plus évoluée qui vous permettra de contrôler un peu plus de paramètres sur le texte généré :</p><pre class="gutter: true; brush: php;">function generer_lipsum($quantite = 1, $type = &#039;paras&#039;, $lorem = false) {
    $url = &quot;http://www.lipsum.com/feed/xml?amount=$quantite&amp;what=$type&amp;start=&quot;.($lorem?&#039;yes&#039;:&#039;no&#039;);
    return simplexml_load_file($url)-&gt;lipsum;
}</pre><p>Où les paramètres sont :</p><ul><li><strong><em> $quantite</em></strong> : la quantité de texte à générer.</li><li><strong><em>$type</em></strong> : l'unité de comptage de la quantité de texte : <em>paras</em> pour paragraphes, <em>words</em> pour mots, <em>bytes</em> pour octets ou <em>lists</em> pour des listes HTML. Ainsi, si vous définissez <em>$quantite</em> à 5 et <em>$type</em> à <em>words</em>, vous allez générer une phrase aléatoire de 5 mots.</li><li><strong><em>$lorem</em></strong> : Si vrai, force le texte généré à débuter par <em>"Lorem ipsum dolor sit amet...".</em></li></ul><p>Voilà pour cette petite astuce qui me plait beaucoup et qui, je l'espère, vous plaira tout autant ! Et si vous en connaissez d'autres de ce style, n’hésitez pas à les partager en commentaire de cet article <img src='https://www.kevinsubileau.fr/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> .</p> ]]></content:encoded> <wfw:commentRss>https://www.kevinsubileau.fr/informatique/boite-a-code/php-html-css/generer-faux-texte-lorem-ipsum-en-php.html/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching using disk: basic

Served from: www.kevinsubileau.fr @ 2026-04-20 04:48:01 -->