Catégorie : Développement informatique

  • Et si on agençait des photos sur une page ?

    J’ai cher­ché à agen­cer des vignettes de photo de façon harmo­nieuse sur une page web. Le problème à l’air simple mais j’ai des photos de tous formats, dont certains vrai­ment atypiques.

    La grille

    La méthode la plus simple c’est de choi­sir un format d’images, choi­sir un nombre de colonnes, et de s’y tenir. Si une image n’a pas le bon ratio, il suffira de couper ce qui dépasse. 500px utilise encore ce système pour la plupart de ses vues.

    grillePour aller plus loin on peut mettre quelques photos en grande taille en prenant la place de plusieurs autres. On casse la mono­to­nie tout en permet­tant de mettre en avant les images les plus impor­tantes.

    En prévoyant plusieurs agen­ce­ments diffé­rents prédé­ter­mi­nés on peut réus­sir à caser des images en format diffé­rent, et ne pas trop déna­tu­rer  les formats portraits ou les images très étirées. On reste toute­fois fixés à des formats prédé­ter­mi­nés.

    Le système de grille est rapide et effi­cace. La seule contrainte est de choi­sir entre la capa­cité de respec­ter scru­pu­leu­se­ment l’ordre des photos et celle de choi­sir manuel­le­ment lesquelles seront mises en avant.

    L’al­go­rithme de Packery va encore plus loin sur ce chemin. À partir d’une grille fixée, il propose de défi­nir un nombre de lignes et de colonnes pour chaque image et de la placer à l’es­pace le plus adapté. L’ordre n’est alors qu’in­di­ca­tif et on doit toujours rogner les images pour les faire tenir sur un nombre fixe de lignes et colonnes, mais on y place des formats et des tailles très diffé­rentes. Pas de secret toute­fois, cet agen­ce­ment lais­sera forcé­ment des blancs. À vous de voir si c’est accep­table, quitte à tenter de les combler par quelques mots.

    Quel que soit le système de grille, le réel enjeu est de savoir ce qu’on peut couper ou pas dans chaque image pour qu’elle colle aux formats prévus. Certains algo­rithmes y arrivent main­te­nant assez bien, surtout quand il y a des visages.

    Même si mon cas d’usage me permet­trait de choi­sir manuel­le­ment comment décou­per chaque image au cas par cas, intel­lec­tuel­le­ment ça me gêne de couper des pixels que j’avais volon­tai­re­ment choisi de garder lors de la créa­tion initiale de l’image. Je crains aussi que le visi­teur s’en fasse une idée faus­sée et au final n’ouvre pas l’image dans son format voulu. C’est parti­cu­liè­re­ment vrai pour les images très en hauteur ou très en largeur, qui ne pour­ront jamais donner le même ressenti si elles sont tronquées.

    On empile

    L’autre méthode est d’em­pi­ler les photos par lignes ou par colonnes en respec­tant leur ratio.

    Tumblr le fait par colonnes en mettant chaque image sur la première place dispo­nible. On obtient une sensa­tion de vrac où l’ordre des images n’est qu’à moitié respecté mais le résul­tat est parfait pour leur cas d’usage. Toutes les images ne terminent pas à la même hauteur mais c’est là encore tout à fait légi­time pour le système de flux sans fin que repré­sente un Tumblr.

    On peut imagi­ner de mettre en avant des images en les passant sur deux colonnes mais, sauf à espé­rer un cas excep­tion­nel où les deux images du dessus s’ar­rêtent pile à la même hauteur, il faudra soit lais­ser du blanc soit couper un peu la plus longue des deux.

    Avec un algo­rithme un peu intel­li­gent on peut tenter de repé­rer quand deux images arrivent presque à la même hauteur et donc ne couper que quelques pixels qui ne se verront pas, mais ça veut aussi dire que l’image mise en avant est quasi­ment lais­sée au hasard. La proba­bi­lité d’en avoir une dépend direc­te­ment de la quan­tité de pixels qu’on accepte de rogner sur les images.

    Pour quelque chose de plus struc­turé Flickr a choisi une dispo­si­tion par lignes. On choi­sit une hauteur cible et on empile toutes les images une à une jusqu’à la fin de la ligne. Ça ne tombe jamais juste mais Flickr se permet alors de faire varier légè­re­ment la hauteur de la ligne à la hausse ou à la baisse. Si on respecte les ratios des images concer­nées, on finira forcé­ment par tomber sur la largeur de ligne souhai­tée. On peut choi­sir de garder la dernière image ou pas (respec­ti­ve­ment en dimi­nuant ou augmen­tant la hauteur de ligne) en fonc­tion de la dispo­si­tion la plus proche de la hauteur idéale.

    Avec un peu de complexité on doit pouvoir éviter les lignes incom­plètes en fin de page. Il suffit de tenter plusieurs combi­nai­sons sur les x dernières lignes puis voir laquelle respecte le mieux la hauteur cible pour chaque ligne parmi celles qui n’ont aucune ligne incom­plète. Je ne suis cepen­dant pas tota­le­ment certain que ça vaille le coup, et ça peut faire varier signi­fi­ca­ti­ve­ment la hauteur des dernières lignes.

    Ce système permet des mises en avant simples en mettant une image en pleine largeur de temps en temps. On peut même, si on le souhaite, avoir des mises en avant à largeur arbi­traire. Il suffit alors de mettre les mises en avant sur un des bord et de reprendre l’al­go­rithme stan­dard sur la largeur restante. Une fois arrivé proche du bas de l’image mis en avant, on la réduit ou l’agran­dit légè­re­ment (avec pour effet d’agran­dir ou de réduire propor­tion­nel­le­ment l’es­pace hori­zon­tal sur le côté, et donc la hauteur corres­pon­dante) jusqu’à ce que les deux corres­pondent.

    On peut aussi imagi­ner ne pas se limi­ter à une seule mise en avant par hauteur et les empi­ler sur un ou deux côtés, y compris sur des hauteurs diffé­rentes. La contrainte va être de toujours avoir les plus hautes à l’ex­té­rieur.

    Il reste que la dispo­si­tion en colonnes de Tumblr flatte les images verti­cales et vigné­tise à l’ex­cès des images orien­tées format paysage. La dispo­si­tion en lignes de Flickr fait l’op­posé et rend diffi­cile la lecture des images au format portrait.

    Si un format est très forte­ment majo­ri­taire, on peut imagi­ner utili­ser le système des mises en avant pour compen­ser.

    Je n’ai pas vu d’adap­ta­tion de l’al­go­rithme Flickr en ce sens. Il faut dire que ça complexi­fie­rait nette­ment un système qui est sinon rela­ti­ve­ment simple. Si j’ai un peu de temps, je vais peut-être tenter l’ex­pé­rience.


    Quelques liens si le sujet vous inté­resse :

  • Compo­si­tion d’une équipe tech­nique produit

    – Dis, on met quoi dans une équipe tech­nique ?

    Ça dépend du temps, du produit, des besoins. Voici ma recette par défaut, à réagen­cer en fonc­tion de la réalité. Il reste qu’à chaque fois je finis par me dire que j’au­rais aimé la voir suivre ce schéma :

    1 et 2 : Donc au début on commence, il faut un ou deux déve­lop­peurs. Idéa­le­ment à ce niveau ils savent toucher un peu de front et un peu de back, et appré­cient de pouvoir inter­ve­nir partout. Pas d’ad­mi­nis­tra­tion système à cette taille, on exter­na­lise un maxi­mum.


    Petit inter­mé­diaire. Il faut une direc­tion tech­nique avant de passer au troi­sième membre de l’équipe. Ce peut être un direc­teur tech­nique à part entière ou un des deux déve­lop­peurs qui a suffi­sam­ment de bouteille mais il faut quelqu’un qui a une vision tech­nique, et pas un néophyte.


    3 : Le troi­sième c’est le grand oublié : le web desi­gner. Il fait de l’UX, de l’UI, et va défi­nir une vraie expé­rience client. Bien évidem­ment tout dépend du métier et du produit mais recru­ter trop tard est habi­tuel­le­ment une erreur. La mode est de consi­dé­rer que ce profil doit même faire partie des fonda­teurs.

    4 : On complète avec un troi­sième déve­lop­peur. On peut commen­cer à envi­sa­ger un spécia­liste qui apporte une exper­tise qui manque aux deux autres mais il faudra quand même qu’il accepte de toucher un peu à tout.

    5 : L’équipe commence à avan­cer, main­te­nant il lui faut quelqu’un pour donner une direc­tion et prendre du recul. On peut l’ap­pe­ler product owner, respon­sable produit, chef de projet fonc­tion­nel, analyste métier… Il aura pour charge de réflé­chir aux usages, imagi­ner le produit, assu­rer la vision. Ce doit être quelqu’un de dédié, sans posi­tion hiérar­chique sur le reste de l’équipe.

    6 (et 7 ?) : L’équipe avance, dans le bon sens, il reste à lui donner un peu de puis­sance avec un ou deux autres déve­lop­peurs. À partir de quatre déve­lop­peurs c’est la taille où l’ef­fort est démul­ti­plié et où on peut commen­cer à assu­rer les impré­vus, ou les congés de chacun. Au delà de 5 déve­lop­peurs on commence à faire des sous-équipes et ça n’a plus grand inté­rêt.
    Les équipes les plus dyna­miques avec lesquelles j’ai travaillé ont des déve­lop­peurs qui travaillent tous sur l’in­té­gra­lité du produit mais on peut aussi avoir quelques experts qui inter­viennent essen­tiel­le­ment sur leur domaine de compé­tence.

    8 : Second grand oublié : Le dev op – ou sys admin, peu importe le nom. Son rôle est d’as­su­rer la produc­tion mais sa réelle valeur est de flui­di­fier tout l’ou­tillage interne, comme la plate­forme d’in­té­gra­tion conti­nue ou les scripts de déploie­ment.
    Il n’a d’in­té­rêt qu’a­vec une équipe qui tourne, mais s’en passer c’est comme conti­nuer en gardant un boulet aux pieds. Avant ce sont les déve­lop­peurs qui sont obli­gés de perdre du temps et du focus avec tout ça.

    9 : Je vais à neuf avant de m’ar­rê­ter mais j’ajoute quand même un dernier profil avec un tech­ni­cien. C’est lui qui va assu­rer les tâches d’ex­ploi­ta­tion courantes, s’oc­cu­per du support tech­nique, du support utili­sa­teur, et soula­ger le product owner.
    On peut s’en passer mais c’est au prix d’un manque de focus non négli­geable, donc d’un peu de gâchis.


    Je n’ai pas parlé de mana­ger mais à neuf le besoin s’est peut-être déjà fait sentir depuis un petit moment. S’il existe, il peut faire le dixième. Le problème du mana­ger mérite plus d’un billet mais je retiens une règle : ni la direc­tion commer­ciale de la société, ni le product owner de l’équipe. Ce peut être le CTO qui gère la direc­tion tech­nique décrite plus haut.


    Je n’ai pas mis de QA non plus. Je conti­nue à penser que l’équipe doit être respon­sable de ce qu’elle livre. Une QA sépa­rée à tendance à déres­pon­sa­bi­li­ser mais aussi à ajou­ter de la distance avec la réalité et du délai lors des livrai­sons. Ça aura du sens quand il y aura plusieurs équipes, pas tout de suite. Le dev op pourra par contre outiller et auto­ma­ti­ser un maxi­mum de tests et de proces­sus entre temps.


    Et vous, vous conseillez quoi comme compo­si­tion ? Qu’ai-je oublié ?

  • Mention bot, cibler la revue de code

    À La Ruche qui Dit Oui, comme dans mon équipe précé­dente, on fait des revues de code avec la règle des deux pouces. Pour qu’une modi­fi­ca­tion appli­ca­tive passe en produc­tion il faut qu’elle soit vali­dée par deux pairs, qui vont mettre un ? (le feed­back par emoji, si vous n’avez pas essayé, vous manquez quelque chose).

    En discu­tant avec les équipes d’Al­go­lia, on m’a pointé mention-bot. L’idée est simple : avec un git blame on repère qui est le déve­lop­peur qui a le plus travaillé sur ces parties de code et on le mentionne expli­ci­te­ment auto­ma­tique­ment comme parti­ci­pant poten­tiel à la revue.

    Do you have a GitHub project that is too big for people to subscribe to all the noti­fi­ca­tions? The mention bot will auto­ma­ti­cally mention poten­tial revie­wers on pull requests. It helps getting faster turna­round on pull requests by invol­ving the right people early on.

    Je ne sais pas si ça va vrai­ment s’in­té­grer à notre struc­tu­ra­tion par équipes ici (le déve­lop­peur ciblé risque d’être sur un autre équipe, donc pas la meilleure personne pour faire la revue sur le projet en cours) mais je partage quand même.

  • [Lecture] Ideal HTTP Perfor­mance

    A common ques­tion about Server Push is “what if the client already has a copy in cache?” Because Push is inhe­rently specu­la­tive, there’s always the chance that you’re sending some­thing that the brow­ser doesn’t need.

    HTTP/2 allows the client to cancel the push in this situa­tion, with a RESET_STREAM. Howe­ver, even then, there’s roughly a round trip’s worth of wasted data in flight that could have been used for better things. Remem­ber, the ideal is to send only the data that the client needs to show the page.

    A propo­sed solu­tion for this is for the client to use a compact Cache Digest to tell the server what it already has in cache, so that the server knows what’s needed.

    Bon article de Mark Nottin­gham sur HTTP 2, qui dépasse les notions de base qu’on voit partout. On y parle même un peu des évolu­tions de TCP.

  • Arrê­tez avec les git squash

    Je ne suis pas enthou­siasmé par l’an­nonce de Github. Ok, on peut faire désor­mais un squash sur une branche avant de lancer le merge.

    Je n’aime pas géné­ra­le­ment les squash et les rebase, c’est un fait, mais le cas de Github est proba­ble­ment le cas où le squash me semble toujours une mauvaise idée.

    Cas d’usage : Vous avez fait une branche, envoyé plusieurs commit dessus, publié la branche pour que d’autres fassent une revue, peut-être corrigé un ou deux trucs et repu­blié la branche. Il est temps de fusion­ner votre code avec la branche prin­ci­pale.

    Pourquoi diable cher­cher à faire un squash de la branche ? La seule raison qu’on m’a donné est « avoir un joli histo­rique ». Plus basique­ment ne pas avoir plein de commit en vrac quand on fait un git log sur master.

    Si votre outil de visua­li­sa­tion d’his­to­rique est mauvais, chan­gez votre outil de visua­li­sa­tion, ne bidouillez pas l’his­to­rique à la source ! squash, rebase et fast-forward sont simple­ment de mauvaises pratiques de contour­ne­ment, malheu­reu­se­ment trop répan­dues.

    Il est tout à fait possible de voir les choses sous la forme de branches et de ne pas être pollué par les commit unitaires des autres branches. Il y a plein de bons outils. En fait même git log est tout à fait viable, il suffit de ne pas lais­ser les options par défaut. Vouloir réécrire l’his­toire et effa­cer l’his­to­rique me semble une pratique plus que contes­table pour juste contour­ner le problème.

    Vous voulez ma pratique idéale ? Des branches pour tous les déve­lop­pe­ments, même les fix unitaires. Jamais(*) de fast-forward, de squash ou de rebase une fois le code publié (chez vous vous faites bien ce que vous voulez). La branche prin­ci­pale ne contient que des merge, toujours en –no-ff.

    Pour l’his­to­rique, le plus souvent, on ne devrait même pas regar­der les commit réali­sés sur d’autres branches que celle en cours – le commit de merge qui résume ce qui a été fait devrait suffire.

    Le résul­tat c’est une visua­li­sa­tion linéaire, sans détail inutile, simple à lire, et qui ne néces­site jamais de tricher en suppri­mant ou modi­fiant l’his­to­rique réel.

    Si vous avez besoin, l’his­to­rique complet existe toujours et peut être exploré. Il y a des outils ou para­mètres qui permettent d’avoir une très bonne vision de l’ar­bo­res­cence quand vous en avez besoin.

    C’est quand même dommage d’uti­li­ser un outil de version­ne­ment qui est excellent avec les branches et le travail en paral­lèle pour ensuite en faire une bouillie de commit linéaire et virtuels.

  • La langue des signes et Paris Web racon­tés par une licorne

    Une des choses dont je suis le plus fier vis à vis de Paris-Web, c’est l’ar­ri­vée de la langue des signes et de la vélo­ty­pie.

    Les inter­prètes LSF font un boulot magni­fique au milieu d’un trou­peau de geeks qui parlent en fran­glais plein de jargon et d’acro­nymes, à toute vitesse. En octobre dernier l’équipe a proposé à une de ces inter­prètes de racon­ter comment ça se passe de l’in­té­rieur. C’est une des trois confé­rences à ne pas manquer de cette édition, et elle est pour vous en vidéo :

    Confé­rence LSF from Paris-Web on Vimeo.

    Il s’agit d’un gros budget, pour quelques uns. Ce n’est pas facile tous les ans et à chaque fois que c’est un peu tendu je suis certain que la ques­tion revient sur la table. Pour autant à chaque fois ça tient, même quand il y a un défi­cit.

    Pour moi c’est dans les valeurs de l’évé­ne­ment mais c’est aussi une façon de montrer par l’exemple qu’on peut tenter d’in­clure tout le monde.

  • [Lecture] How we run design critique sessions

    Lu sur le web :

    Recently, we totally chan­ged our design critique sessions. After care­fully analy­zing what was wrong with our previous format, we esta­bli­shed the follo­wing pillars for our design critique sessions:

    1. It’s called Things That Rock
    2. It happens every week
    3. Everyone shows some­thing
    4. No prepa­ra­tion needed
    5. 10 minutes per person
    6. Critique comes in the form of ques­tions
    7. The session ends by a vote

    Let’s go over each point in more details.

    chez Blabla­car

    Inté­res­sant. On rejoint un peu le système des revues de pair mais avec une autre approche, moins systé­ma­tique et plus bran­chée sur comment parta­ger l’ex­pé­rience pour s’en­ri­chir. J’aime beau­coup l’idée qu’en montrant ce qui fonc­tionne on finit par monter le niveau d’exi­gence.

    Qui fait quelque chose de simi­laire côté déve­lop­pe­ment ? Tout ce que j’ai vu finit par tour­ner dans des présen­ta­tions de tech­nos et moins dans le « voilà ce que j’ai fait ».

  • [Lecture] On a testé fonc­tion­nel­le­ment notre app JS

    Lu sur le web :

    L’uti­lité des tests fonc­tion­nels pour les appli­ca­tions web n’est plus à démon­trer (comment ça, vous ne testez pas encore vos apps ?). Malheu­reu­se­ment, tout ne peut pas être tota­le­ment testé fonc­tion­nel­le­ment, ou de façon aisée : je pense par exemple au player chez nous, un compo­sant stra­té­gique mais pauvre­ment testé fonc­tion­nel­le­ment de par sa nature un peu hybride (mélange de flash et de JS). Dans tous les cas, pour ce qui peut l’être, nous sommes parti­sans dans l’équipe Cytron d’user sans mesure (ou presque !) de cet outil de manière à être le plus zen possible au moment d’ap­puyer sur le bouton “deploy”.

    chez M6 Web

    Inté­res­sant, mais à deux moments j’ai l’im­pres­sion de tâton­ne­ments, de tests qui peuvent échouer sans raisons et qu’on relance pour s’as­su­rer que ça passe. Je trouve ça assez risqué comme approche. Ai-je mal compris ?

    il nous arri­vait que le compor­te­ment “hover” ne soit pas déclen­ché, mettant en échec la suite du test. Nous avons donc changé notre manière d’ef­fec­tuer le rollo­ver : on répète l’ac­tion grâce au waitUntil tant que l’éle­ment devant appa­raître au hover n’est pas visible

    Pourquoi l’évé­ne­ment n’est-il pas déclen­ché ? Et l’uti­li­sa­teur risque-t-il d’avoir le même bug ?

    Elle permet de stocker dans un fichier texte la liste des scéna­rios en échec pour les relan­cer ensuite afin de véri­fier qu’ils le sont réel­le­ment.

    Des faux posi­tifs ? Et si parfois le test échoue alors qu’il ne devrait pas, il y a-t-il un risque qu’il réus­sisse alors qu’il ne devrait pas ? Combien de fois le relan­cer pour être certain du résul­tat ?

    Le retour d’ex­pé­rience est extrê­me­ment inté­res­sant, mais ça laisse un goût de bidouille qu’il serait préfé­rable de corri­ger avant de consi­dé­rer la solu­tion comme stable.

  • [Lecture] Refac­to­ring a Docker­file for image size

    Lu sur le web :

    There’s been a welcome focus in the Docker commu­nity recently around image size. Smal­ler image sizes are being cham­pio­ned by Docker and by the commu­nity. When many images clock in at multi-100 MB and ship with a large ubuntu base, it’s greatly needed.

    sur Repli­ca­ted

    J’aime bien l’ap­proche de l’ar­ticle, qui tient plus à reti­rer le super­flu qu’à partir sur des confi­gu­ra­tions peu stan­dard. Main­te­nant, qu’y gagne-t-on ?

    L’es­pace disque est-il vrai­ment un enjeu majeur aujourd’­hui par rapport au temps qu’on y passe et à la perte éven­tuelle de souplesse ?

    Le système de système de fichier par couche devait mutua­li­ser les télé­char­ge­ments et les espaces de stockage. Ai-je mal compris ?

  • Compo­ser paral­lel install plugin

    Bench­mark Example
    288s -> 26s

    hirak/pres­tis­simo, compo­ser paral­lel install plugin

    Non testé, mais je me dis qu’il y a peu de chances que ça fasse du mal