Modernisez vos applications web

retour d'expérience sur la refonte site media

Benjamin RICHARD

Manager technique

Lead-dev

16 ans d'XP (aïe)

Meetup Meteor Lyon

@rebolon

On vous vend du rêve

Votre réalité technique

Dev

Full Stack

Back et Front

en PHP ou Java

avec

du jQuery

Alors n'hésitez pas à moderniser vos applications

Vos contraintes

  • Budget / Temps
  • Architecture existante
  • Compétences
  • Compatibilité navigateur
  • SEO / Référencement
  • Stratégie d'entreprise
  • ... 

Notre contexte :

Refonte du site Euronews.com, le site d'une chaine d'information audio-visuelle

V1

V2

Nos contraintes

  • Délais très courts (4 mois)
  • Stack technique en partie définie (PHP-Symfony2)
  • Multilingue (13 langues)
  • Responsive design (4 breakpoints)
  • Fort trafic : plusieurs milions de pages vues / mois hors app mobile
  • SEO
  • SEO
  • SEO

Les réalités : technicité

  • Un site media n'est pas forcément sexy techniquement

Les réalités : SEO

  • Le SEO est prépondérant pour générer du trafic :
    • Google News
    • Facebook
    • Twitter
    • Google
    • Bing
    • ...

L'expérience d'Africanews

  • Projet repris en main à l'automne 2015 :
    • Démarré par une autre équipe externe
    • Livraison pour décembre 2015
  • Stack SF2.6 / Gulp / Browserify / Vanilla JS

Difficulté à travailler avec la stack js

  • appels Ajax
  • templating

Volonté de travailler différemment

HomePage (sans js)

Text

stickyBars

newsBar

Caroussels

Sports Results

Ca fonctionne de manière traditionnelle

Client

Serveur Web PHP

Serveur Web NodeJs

Persistence

Cache

http

http

génère tout le DOM

^n

1 page = 1 appel http

Javascript

  • Ne dois pas être obligatoire :
    • Google (et les autres) doit pouvoir crawler l'intégralité du site
  • Dois apporter une plus-value pour l'utilisateur
  • Dois être léger !!! malgré les demandes du client (caroussel)

Javascript : bundles

  • Browserify : de mono-Bundle à multi-bundle :
    • en inline : un bundle pour les librairies utilisées (player video, lodash, caroussel, VueJs, ...)
    • en async : un bundle pour démarrer les composants communs
    • en async : un bundle pour démarrer les composants de la page courante

Javascript : ES6

  • ES6 avec polyfills core-js :
    • ne prendre que les polyfills dont on a besoin !!!
  • Framework CSS Foundation :
    • ne prendre que les briques JS utilisées

Javascript : the framework

  • Besoin d'un outils pour dynamiser le site :
    • ​Vanilla JS vs
    • Handlebars vs
    • VueJs :
      • empreinte légère de 76K non gzipé
      • simplicité
      • documentation claire et complète
      • structure les développements
      • orienté composant <my-component></my-component>
      • polyvalent : full app ou "simples" widgets
      • Vue Chrome Debug Tool

Réalisation d'un POC

  • Reprise d'un composant existant sous VueJS :
    • La timeline d'africanews.com recodée en 30 minutes

Comment utiliser VueJS ?

Déterminez vos composants

  • Ce qui pull de la donnée
  • Ce qui est interactif : formulaire, slideshow, ...
  • Ce qui nécessite de la pagination
  • Ce qui a besoin d'animation
  • ...

Vue Instance

Programmation réactive

  • propriétés et data sont observées
  • tout changement est répercuté sur leur dépendance (template, méthode notamment)

let cpt = new Vue({
  ...
  template: `{{name}}`,
  data: function() {
    return {
      name: "rebolon"
    }
  }
});

cpt.name = "benjamin";

Système d'évènement

  • Le composant parent altère les propriétés d'un enfant
  • Le composant parent écoute des évènements : $on
  • Les composants enfants émèttent des évènements : $emit
  • Possibilité de déclarer un bus de message commun

let cpt = new Vue({
  ...
  props: {
    name: {type: String, default: 'rebolon'}
  }
});

...

<div id="demo">
  <my-cpt v-bind:name="parentReactiveVar"></my-cpt>
</div>

Des directives à la "angular"

  • v-if
  • v-for
  • custom directives

<ul class="collection">
    <li v-for="character in characters">
        <img 
            v-bind:src="character.thumbnail.path + '.' + character.thumbnail.extension" 
            v-bind:alt="character.name">
        <span class="title">{{character.name | uppercase }}</span>
    </li>
</ul>

Template

  • Externalisez-les :

<script type="x/template" id="timeline-bar-template">
  /* Your tpl here */ 
  <div v-if="user">Hello {{user.name}} </div>
</script>
  • et même JSX dans Vue 2
  • ou en inline :
<div id="my-cpt">
  {{ name }}
</div>
  • voir dans une string du composant via sa propriété template

Notre gestion du

SEO / Référencement

  1. Avoir le plus possible une page web complète sans JS
  2. Permettre aux composants JS de prendre la main en restaurant un état identique à la page courante : utilisez les propriétés (props)

Pour finir :

  1. Au besoin, changez les délimiteurs du templating de VueJS pour utiliser des template Vue avec vos templates back
  2. Côté backend passez la data à vos composants vue via les propriétés afin de lui permettre de s'initialiser
  3. Utilisez les plugins pour définir des méthodes communes : chez nous cela concerne les filtres ou même le swap du DOM par celui du composant

VueJS 2.x

  • Toujours aussi polyvalent
  • JSX possible pour les templates
  • Vuex, ou vue-redux : implémentation de redux
  • Typescript typings
  • Vue-router (existe en v1.x)
  • Vue cli
  • et toujours Vue-devtools

Exemple

<div id="app">
    <characters></characters>
</div>
<script type="x/template" id="characters-tpl">
    <ul>
        <li v-for="character in characters">
          <div class="chip">
            <img v-bind:src="character.thumbnail.path + '.' + character.thumbnail.extension">
            {{character.name}}
          </div>
        </li>
    </ul>
</script>
<script data-item="vuejs-component-characters">
    Vue.component('characters', {
        template: '#characters-tpl',
        data: function () {
            return {
                characters: []
            };
        },
        beforeCreate: function () {
            this.$http
                .get("https://gateway.marvel.com:443/v1/public/characters", 
                    {params: {apikey: Rebolon.Marvel.apiKey}})
                .then(response => {
                    try {
                        var characters = response.body.data.results;
                        characters.forEach(item => {
                            this.characters.push(item);
                        });
                    } catch (e) {
                        console.error('unexpected data', response);
                    }
                }, response => {
                    console.warn('http error', response);
                }
            );
        }
    });

    new Vue({el: 'app'});
</script>

Exemple

Notre bilan sur VueJs

  • Structure notre code : template côté client, composant, data
  • Courbe d'apprentissage très courte
  • Léger
  • Communauté grandissante (de plus en plus de plugins)
  • Des grands l'utilisent (alibaba)
  • Une flexibilité qui ouvre des portes pour vos apps historiques
  • Réelle alternative à Angular2 ou React

<script type="x/template" id="timeline-bar-template">
    <a href="{{ itemTimeline | timelineSlug }}" 
       data-component
       v-for="itemTimeline in items | orderBy 'publishedAt' -1" 
       track-by="id" 
       id="timeline-1">
        <div class="enw-justin__item">
        ...
    ...
...

Mais par rapport à notre stack :

  • Double nos templates au démarrage du projet : php et js (améliorable en changeant les délimiteurs, à condition de ne pas utiliser de plugin intégrant ses propres templates)

 

  • Problèmes quand on mix les technos JS : caroussel + Vue, typeahead + Vue ... Il peut être préférable d'utiliser les briques sans les imbriquer ensemble

Si vous utilisez Vue

Partagez

ou 

Participez via Patreon ou Github

Resources

  • http://vuejs.org
  • https://github.com/vuejs/awesome-vue

Merci

Merci à @Aldebaran Robotics pour son robot

Modernisez vos applications web avec VueJS, conférence du BlendWebMix 2016

By Retour d'expérience MeteorJS

Modernisez vos applications web avec VueJS, conférence du BlendWebMix 2016

Slides de ma conf du BlendWebMix 2016 sur un retour d'expérience concernant la refonte du site Euronews.com. Ce projet web, techniquement traditionnel, intègre des composants VueJS qui nous ont permis d'améliorer la qualité et la maintenabilité du site.

  • 3,804