You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
864 lines
46 KiB
864 lines
46 KiB
\documentclass[12pt, a4paper]{article}
|
|
|
|
\setlength{\parskip}{1em}
|
|
|
|
\usepackage[T1]{fontenc}
|
|
\usepackage[a4paper, margin=0.7in]{geometry}
|
|
\usepackage[french]{babel}
|
|
\usepackage{amsmath}
|
|
\usepackage{amsfonts}
|
|
\usepackage{mathtools}
|
|
\usepackage{mathabx}
|
|
\usepackage{listings}
|
|
\usepackage{xcolor}
|
|
\usepackage{float}
|
|
\usepackage{cite}
|
|
\usepackage{subcaption}
|
|
\usepackage{wrapfig}
|
|
\usepackage{svg}
|
|
\usepackage{ragged2e}
|
|
\usepackage[nottoc,numbib]{tocbibind}
|
|
|
|
\usepackage{hyperref}
|
|
\hypersetup{
|
|
colorlinks=true,
|
|
linkcolor=blue,
|
|
urlcolor=blue,
|
|
citecolor=red,
|
|
pdftitle={Adrien Burgun - Rapport de stage ST40 - A2022}
|
|
}
|
|
|
|
% From https://github.com/pinam45/utbm-latex-internship-report-covers
|
|
% Requires xelatex to run (or maybe also lualatex)
|
|
\usepackage{utbmcovers}
|
|
|
|
% From https://tex.stackexchange.com/questions/89574/language-option-supported-in-listings
|
|
\lstdefinelanguage{JavaScript}{
|
|
keywords={
|
|
typeof, new,
|
|
abstract, class, interface, type, function, return,
|
|
try, catch, finally,
|
|
switch, case, break,
|
|
var, let, const,
|
|
if, else,
|
|
for, while, in, of, do,
|
|
true, false, null, undefined
|
|
},
|
|
keywordstyle=\color{blue}\bfseries,
|
|
ndkeywords={
|
|
export, implements, import, this,
|
|
private, public, readonly, constructor,
|
|
@Inject, @Injectable, @Controller, @Module
|
|
},
|
|
ndkeywordstyle=\color{darkgray}\bfseries,
|
|
identifierstyle=\color{black},
|
|
sensitive=false,
|
|
comment=[l]{//},
|
|
morecomment=[s]{/*}{*/},
|
|
commentstyle=\color{purple}\ttfamily,
|
|
stringstyle=\color{red}\ttfamily,
|
|
morestring=[b]',
|
|
morestring=[b]"
|
|
}
|
|
|
|
\lstdefinelanguage{hbs}{
|
|
morecomment=[s]{\{\{!}{!\}\}},
|
|
commentstyle=\color{purple}\ttfamily,
|
|
stringstyle=\color{red}\ttfamily,
|
|
morestring=[s]{\{\{}{\}\}},
|
|
}
|
|
|
|
\definecolor{bgColor}{rgb}{0.95,0.94,0.92}
|
|
\lstdefinestyle{JavaScript}{
|
|
backgroundcolor=\color{bgColor},
|
|
commentstyle=\color{gray},
|
|
keywordstyle=\color{magenta},
|
|
numberstyle=\tiny\color{gray},
|
|
stringstyle=\color{purple},
|
|
basicstyle=\footnotesize,
|
|
breakatwhitespace=false,
|
|
breaklines=true,
|
|
captionpos=b,
|
|
keepspaces=true,
|
|
numbers=left,
|
|
numbersep=5pt,
|
|
showspaces=false,
|
|
showstringspaces=false,
|
|
showtabs=false,
|
|
tabsize=2,
|
|
language=JavaScript
|
|
}
|
|
|
|
\graphicspath{{build/figures/}{images/}}
|
|
|
|
\newfontfamily{\Tahoma}{Tahoma}
|
|
\newfontfamily{\SourceSans}{Source Sans Pro}
|
|
% Looks like the font from google fonts has a different case,
|
|
% so I'm stuck with scanning for existing fonts
|
|
\IfFontExistsTF{Source Sans Pro SemiBold}{
|
|
\newfontfamily{\SourceSansSB}[UprightFont={* SemiBold}]{Source Sans Pro}
|
|
}{
|
|
\IfFontExistsTF{Source Sans Pro Semi-Bold}{
|
|
\newfontfamily{\SourceSansSB}[UprightFont={* Semi-Bold}]{Source Sans Pro}
|
|
}{
|
|
\newfontfamily{\SourceSansSB}[UprightFont={* Semibold}]{Source Sans Pro}
|
|
}
|
|
}
|
|
\setmainfont{Source Sans Pro}
|
|
% \newfontfamily{\ossb}[UprightFont={* Semibold}]{Open Sans}
|
|
\newcommand{\entity}[1]{{\SourceSansSB #1}}
|
|
\newcommand{\entityb}[1]{#1}
|
|
\newcommand{\person}[2]{#1 #2}
|
|
\newcommand{\term}[1]{\textit{#1}}
|
|
\newcommand{\figref}[1]{[Figure~\ref{#1}]}
|
|
\newcommand{\inputfig}[1]{\input{figures/#1}}
|
|
|
|
\title{Rapport de stage ST40 - A2022}
|
|
\author{Adrien Burgun}
|
|
\date{Automne 2022}
|
|
|
|
|
|
\setutbmfrontillustration{assets/priscilla-du-preez-BjhUu6BpUZA-unsplash}
|
|
\setutbmtitle{Stage développeur full stack}
|
|
\setutbmsubtitle{Rapport de stage ST40 - A2022}
|
|
\setutbmstudent{BURGUN Adrien}
|
|
\setutbmstudentdepartment{Département Informatique}
|
|
\setutbmstudentpathway{}
|
|
\setutbmcompany{Moment - T\&M}
|
|
\setutbmcompanyaddress{3 boulevard Richard Lenoir\\75011 Paris}
|
|
\setutbmcompanywebsite{\href{https://moment.tech/}{moment.tech}}
|
|
\setutbmcompanytutor{PERRIN Pierre}
|
|
\setutbmschooltutor{HOLWECK Frederic}
|
|
% From https://moodle.utbm.fr/pluginfile.php/117803/mod_book/chapter/595/CARNET-A22-20220711.pdf
|
|
\setutbmkeywords{Télécommunications - Informatique - Développement logiciel - Logiciel de gestion - Logiciel de réseaux}
|
|
\setutbmabstract{
|
|
J'ai effectué mon stage ST40 au sein du département de développement full-stack de l'entreprise \entity{Moment},
|
|
une start-up française basée à Paris et fondée en 2013.
|
|
\newline
|
|
|
|
% TODO: check wording (maritime)
|
|
Moment propose à ses clients des offres de divertissement pour l'aviation, le secteur maritime, les chemins de fer et
|
|
plus récemment le domaine de la santé. Leur offre principale, \og Flymingo \fg, permet d'accéder aux divertissements
|
|
directement depuis les appareils mobiles des passagers.
|
|
\newline
|
|
|
|
J'ai pu contribuer au développement de fonctionnalités pour la nouvelle offre déployée dans les cliniques de santé,
|
|
à l'optimisation de l'application tournant sur des télévisions connectées et au maintien du code front-end.
|
|
}
|
|
|
|
\begin{document}
|
|
% \maketitle
|
|
\makeutbmfrontcover{}
|
|
{
|
|
\Tahoma
|
|
\tableofcontents
|
|
}
|
|
\newpage
|
|
|
|
\section{Présentation}
|
|
|
|
\subsection{Présentation de l'entreprise}
|
|
|
|
\entity{Moment} est une entreprise fondée en 2013, avec pour but de rendre l'expérience des voyageurs plus simple,
|
|
plus plaisante et plus connectée \cite{momenttech}.
|
|
Pour y parvenir, \entity{Moment} propose une plateforme digitale déployée dans les avions, les trains, les bateaux
|
|
de croisière et plus récemment les cliniques de santé.
|
|
Cette plateforme permet aux voyageurs de se connecter à un réseau wifi avec leurs propres appareils, et de profiter
|
|
de divertissements directement sur ceux-cis.
|
|
|
|
% TODO: récupérer le vrai nombre d'employés et de projets
|
|
À ce jour, \entityb{Moment} s'apprête à compter 10 ans de travail dans ce domaine, et possède une trentaine d'employés.
|
|
\entityb{Moment} a lancé une cinquantaine de projets, dans 15 pays, et ses produits sont utilisés par plus de 10 millions
|
|
de passagers par jour.
|
|
|
|
% TODO: valider Air France?
|
|
\entityb{Moment} fournit ses services aujourd'hui à \entity{Air France}, l'\entity{Aéroport de Paris},
|
|
\entity{TGV InOui}, \entity{Air Belgium}, \entity{Brittany Ferries} et \entity{Air Senegal}.
|
|
|
|
L'entreprise \entityb{Moment} a lancé en 2021 une filiale nommée \entity{Moment Care}, qui se spécialise dans
|
|
le divertissement dans le domaine de la santé:
|
|
\entity{Moment Care} souhaite révolutionner le contenu des offres de divertissement dans les établissements
|
|
de santé, et la manière d'y accéder \cite{momentcare}.
|
|
|
|
\subsection{Présentation du lieu de stage}
|
|
|
|
Lors de mon stage, les locaux de \entityb{Moment} se trouvaient à Paris, près de la place de la Bastille.
|
|
Ces bureaux sont partagés par la grande majorité des employés de \entityb{Moment}, qui sont organisés en
|
|
différents pôles:
|
|
|
|
\begin{description}
|
|
\item[Développement full-stack:] C'est au sein de cette équipe que mon stage s'est déroulé,
|
|
sous la supervision de son chef d'équipe, Pierre Perrin.
|
|
|
|
\item[Marketing \& Design:] Ce pôle s'occupe de l'image de l'entreprise et des produits, à la fois sur
|
|
les réseaux sociaux et auprès des clients présents et futurs.
|
|
Cette équipe décide notamment du design des différentes applications, qui est envoyé à l'équipe
|
|
\entity{Fullstack R\&D} pour implémentation.
|
|
|
|
\item[PMO (Project Management Office):] Ce pôle est constitué de chefs de projets, qui gèrent les demandes
|
|
des clients, les dates limites, les statistiques à relayer aux clients et les difficultés techniques.
|
|
|
|
\item[Contenu:] L'équipe contenu s'occupe de maintenir la base de contenus disponibles sur les
|
|
différentes plateformes déployées. Elle négocie auprès des distributeurs de films, de séries
|
|
et de magazines, et elle maintient à jour le \term{Content Management System} (CMS).
|
|
|
|
\item[Business Developers:] Cette équipe est en contact avec nos clients actuels et de potentiels clients
|
|
futurs. Elle met en place le business plan, amène à l'entreprise de nouvelles opportunités
|
|
de partenariat et négocie les prix lors de la vente des produits de l'entreprise.
|
|
|
|
% TODO: reste
|
|
|
|
\end{description}
|
|
|
|
\newpage
|
|
|
|
\subsection{Produits de Moment}
|
|
|
|
\subsubsection{Flymingo}
|
|
|
|
\entity{Flymingo} est le produit principal de \entityb{Moment}:
|
|
% Pitch de Moment, dire sur quoi c'est déployé
|
|
|
|
Ce produit est composé d'un serveur, nommé \entity{Flymingo Box}, sur lequel tournent plusieures applications:
|
|
|
|
\begin{itemize}
|
|
\item Une application web, \entity{Flymingo Digital}, sur laquelle les passagers peuvent se connecter.
|
|
\item La \entity{Content API}, qui est une API pour accéder aux informations sur les différents divertissements
|
|
disponibles sur le serveur. Cette API permet aux clients d'avoir un certain degré de customabilité.
|
|
Cette API sert également les différents contenus (vidéo, musique, magazines).
|
|
% Zirock?
|
|
\end{itemize}
|
|
|
|
\subsubsection{Mint}
|
|
|
|
% TODO: add logo floating to the right
|
|
\entity{Mint} est le produit que \entityb{Moment} développe et déploie en ce moment dans les cliniques de santé:
|
|
|
|
\begin{description}
|
|
\item[Mint Admin] est une application web permettant aux clinique de fixer les prix
|
|
pour les offres que celles-cis souhaite mettre à disposition, ainsi que de gérer l'assignement des différents
|
|
appareils (comme les télévisions et les tablettes) aux chambres, des différents patients à ces chambres,
|
|
et des offres aux patients.
|
|
\item[Mint Digital] est une application web que les patients des cliniques utilisent
|
|
pour se connecter, acheter des offres en ligne, regarder des films, documentaires, magazines et écouter de la musique.
|
|
\item[Mint Service] est le back-end avec lequel \entity{Mint Admin} et \entity{Mint Digital} communiquent.
|
|
\entity{Mint Service} expose une API permettant à \entity{Mint Admin} de faire des modifications aux offres et aux patients,
|
|
et à \entity{Mint Digital} de permettre aux utilisateurs de se connecter et d'acheter des offres en ligne.
|
|
\item[Mint Tab] est une application pour tablettes \term{iPad}, qui permet aux patients des cliniques
|
|
d'accéder au même contenu que sur \entity{Mint Digital}.
|
|
\item[Mint TV] est une application tournant sur les télévisions connectées, qui permet aux patients des
|
|
cliniques d'accéder au même contenu que sur \entity{Mint Digital}.
|
|
\end{description}
|
|
|
|
Durant ce stage, j'ai surtout travaillé sur les applications suivantes:
|
|
|
|
\begin{itemize}
|
|
\item Mint Service
|
|
\item Mint Admin
|
|
\item Mint Digital
|
|
\item Mint TV et Mood TV
|
|
\end{itemize}
|
|
|
|
\section{Organisation du stage}
|
|
|
|
% Durant ce stage, j'ai rejoint l'équipe \entity{Développement Full-Stack - Recherche \& Développement},
|
|
% afin de contribuer au développement des applications front-end et back-end de l'entreprise,
|
|
% à l'assurance de qualité de ces applications et aux choix techniques faits pour ces applications.
|
|
|
|
\subsection{Thèmes définis avant le stage}
|
|
|
|
% Note: commencé avec 9 personnes, puis est passé à 7 personnes
|
|
% TODO: vérifier sur le portail des stages notre mission
|
|
Durant mes échanges avec mon tuteur de stage et le directeur des ressources humaines de \entity{Moment},
|
|
nous nous étions convenus que j'allais intégrer l'équipe \entity{Développement Full-Stack - Recherche \& Développement} en tant que développeur.
|
|
|
|
Mes tâches au sein de cette équipe seraient de:
|
|
|
|
% https://utbm.jobteaser.com/en/job-offers/8878261-moment-developpeur-se-web-fullstack-stage-ou-alternance
|
|
% TODO: clarifier qu'est ce qui constitue un projet R&D
|
|
\begin{itemize}
|
|
\item Développer de nouvelles fonctionnalités (notamment de nouvelles \term{API} (interfaces de programmation) et de leur intégration côté client)
|
|
\item Documenter le code (sous forme de commentaires et sous forme de documentation technique)
|
|
\item Participer aux choix fonctionnels (quelles technologies utiliser, comment organiser des librairies, etc.),
|
|
et participation à leur implémentation
|
|
\item Participer à la définition de la roadmap technique, et au suivi de cette roadmap
|
|
\item Aider à améliorer les solutions déjà existantes (amélioration de performances, de maintenabilité, etc.)
|
|
\item Participation aux projets Recherche \& Développement
|
|
\end{itemize}
|
|
|
|
Au moment de mes entretiens pour ma candidature de stage,
|
|
les thèmes principaux sur lesquels l'équipe travaillaient étaient le développement de \entity{Flymingo Digital}
|
|
et de \entity{Mood TV}, ainsi qu'un peu de développement pour \entity{Mint}.
|
|
|
|
J'ai aussi pu apprendre que l'équipe utilise la librairie \entity{React} et le framework \entity{Next.JS} pour ses applications front-end,
|
|
et le moteur javascript \entity{Node.JS} avec le framework \entity{Nest.JS} pour ses applications back-end.
|
|
|
|
J'espérais avant le stage pouvoir surtout travailler sur la partie back-end,
|
|
car j'avais jusqu'à ce moment-là peu d'expérience avec \entity{React},
|
|
et le peu d'expérience que j'avais ne m'inspirait pas confiance en cette technologie.
|
|
|
|
J'ai néanmoins décidé d'apprendre en amont du stage la librairie \entity{Solid.JS} \cite{solidjs},
|
|
car je n'avais jusqu'à maintenant que fait du développement front-end \og vanilla \fg (sans librairie ou framework).
|
|
\entity{Solid.JS} se veut être une librairie de développement front-end plus simple, plus réactive et plus efficace que \entity{React},
|
|
et l'apprendre m'a permis d'avoir une première expérience avec la programmation réactive.
|
|
|
|
\subsection{Premiers jours de stage}
|
|
|
|
À mon arrivée au stage, j'ai récupéré l'ordinateur portable qui m'a été préparé avec une installation d'Ubuntu,
|
|
puis j'ai installé un environnement de développement d'applications dessus (différents outils en ligne de commande,
|
|
un éditeur de texte et un gestionnaire de fenêtre avec lequel je suis plus à l'aise).
|
|
|
|
J'ai aussi reçu la documentation d'\og onboarding \fg,
|
|
qui contient une liste de documentations avec lesquelles je devais me familiariser afin de pouvoir travailler efficacement.
|
|
J'ai parcouru ces documentations et ai testé certaines des fonctionnalités décrites dans celles-cis dans un mini-projet de test.
|
|
|
|
L'équipe se réunit chaque matin pour discuter des nouveautés et du travail de la veille,
|
|
et pour annoncer sur quoi chaqu'un prévoit de travailler ce jour-ci.
|
|
J'ai participé à ces réunions dès mon premier jour,
|
|
ce qui m'a permis de rapidement construire une compréhension des problématiques récurrente et de la dynamique des différentes applications.
|
|
|
|
Nous sommes encouragés dans l'équipe à travailler en \og pair programming \fg,
|
|
et en général à collaborer ensemble.
|
|
Ma première contribution au code a été faite en pair programming,
|
|
après avoir remarqué que la logique pour la complexité des mots de passe dans \entity{Mint Admin} était fausse.
|
|
Faire cette contribution en pair programming m'a permis d'être guidé dans le processus d'envoi et de vérification de contributions,
|
|
ainsi que d'être guidé dans l'organisation de la repository.
|
|
|
|
\subsection{Outils utilisés}
|
|
|
|
\newcommand{\logowidth}{0.15\textwidth}
|
|
|
|
\entity{Git} \cite{git} est utilisé pour gérer le versionage du code: cet outil permet de stocker les modifications
|
|
apportées au code sous forme de \og commits \fg, et de facilement rassembler et gérer les modifications faites par plusieures personnes.
|
|
|
|
% wrapfigure does not work with my \entity :(
|
|
\begin{wrapfigure}{r}{\logowidth}
|
|
\centering
|
|
\includesvg[width=\logowidth]{gitlab_logo.svg}
|
|
\caption*{GitLab \cite{gitlabsvgs}}
|
|
\end{wrapfigure}
|
|
|
|
\textbf{GitLab} \cite{gitlab} est utilisé pour stocker les repositories de l'entreprise en ligne,
|
|
pour stocker en ligne les packages npm \cite{npm} et pour lancer automatiquement les tâches de \term{Continuous Integration}.
|
|
|
|
\textbf{VSCode} \cite{vscode} est un éditeur de texte utilisé par presque toute l'équipe pour modifier ou naviguer le code.
|
|
|
|
\textbf{Slack} \cite{slack} est une plateforme de messagerie instantanée,
|
|
que l'entreprise préfère aux emails pour la communication indirecte.
|
|
|
|
\textbf{Jira} \cite{jira} est un logiciel de gestion et de suivi de tickets,
|
|
que notre équipe utilise pour suivre les tâches à faire durant la semaine,
|
|
quelles tâches sont en cours de développement, prêtes à être revues ou finies,
|
|
ainsi que pour garder un \term{backlog} des tâches à faible priorité.
|
|
|
|
\textbf{Confluence} \cite{confluence} est un logiciel qui permet à l'équipe de regrouper des documentations qui n'ont pas de place claire au sein du code.
|
|
|
|
\textbf{NX} \cite{nx} est un outil simplifiant la gestion de \og monorepositories \fg (des repositories contenant plusieures applications et librairies).
|
|
\textbf{NX} est utilisé pour la repository de l'équipe qui contient Mint Service, Mint Admin et Mood TV.
|
|
L'objectif au long terme et de migrer l'ensemble des projets de l'équipe sur cette repository,
|
|
car elle permet de facilement réutiliser du code entre les projets et de synchroniser des modifications entre projets.
|
|
|
|
\begin{wrapfigure}{r}{\logowidth}
|
|
\centering
|
|
\includesvg[width=\logowidth]{ts-logo-128.svg}
|
|
\caption*{TypeScript \cite{typescriptlogo}}
|
|
\end{wrapfigure}
|
|
|
|
\textbf{Typescript} \cite{typescript} est une extension au langage JavaScript, qui ajoute un système de vérification de types.
|
|
Typescript permet d'éviter une classe de bugs causés par des valeurs passées à des fonctions attendant un certain type en entrée.
|
|
\\
|
|
Typescript existe aujourd'hui en tant que langage qui doit être transpilé en javascript avant de pouvoir être utilisé dans Node.JS ou dans un navigateur,
|
|
mais certains interpréteurs (comme \textbf{Bun} \cite{bun}) supportent le typescript,
|
|
et il existe une initiative pour standardiser un système permettant d'ajouter des types en javascript sans devoir le traduire.
|
|
|
|
\textbf{React} \cite{react} est une librairie JavaScript qui permet de facilement construire des interfaces graphiques fortement intéractives.
|
|
React permet d'encapsuler l'affichage et la gestion d'évenéments dans des \og composants \fg, qui peuvent être réutilisés de manière modulaire.
|
|
React propose aussi une extension de JavaScript, qui permet d'écrire du code HTML directement dans le code JavaScript,
|
|
ainsi que d'insérer des composants avec la même syntaxe.
|
|
|
|
\textbf{Next.JS} \cite{nextjs} est un framework simplifiant l'utilisation de React pour des plus grandes applications:
|
|
NextJS permet de séparer l'application en différentes pages,
|
|
et de naviguer de manière inintérompue entre ces pages.
|
|
NextJS a également pour but d'optimiser la vitesse de chargement de ces pages, en faisant un maximum du rendu de ces pages côté serveur.
|
|
|
|
\textbf{Nest.JS} \cite{nestjs} est un framework simplifiant la création d'applications back-end.
|
|
NestJS utilise l'injection de dépendance pour permettre de plus facilement faire grandir une application back-end,
|
|
et propose de nombreux outils pour gérer les requêtes, les bases de données et la documentation.
|
|
|
|
\subsection{Organisation de l'équipe}
|
|
|
|
% Agile, poker planning
|
|
% Backlog, recettes, versioning
|
|
|
|
\subsection{Planning}
|
|
|
|
|
|
% Afin de pouvoir développer \entity{Mint TV} sans duplication de code,
|
|
% nous avons décidé de prendre l'ensemble des composants de \entity{Mood TV},
|
|
% de les nettoyer et des les mettre dans une librairie au sein de la monorepository.
|
|
|
|
|
|
\section{Travail réalisé sur Mint Service}
|
|
|
|
Mint Service est une application construite avec \entity{NestJS}.
|
|
NestJS est un framework permettant de construire des applications côté serveur en JavaScript,
|
|
et de s'assurer que ces applications soient à la fois sûres, efficaces et flexibles \cite{nestjs}.
|
|
|
|
\subsection{NestJS et organisation du code}
|
|
|
|
% TODO: hiérarchiser l'argumentaire
|
|
|
|
NestJS emploie à son coeur les principes de \term{modularité} et d'\term{inversion de contrôle} (\term{IoC}):
|
|
\\
|
|
L'application est séparée en différents modules, qui eux-mêmes contiennent des \term{services} et des \term{controleurs}. \figref{nestjs3}
|
|
|
|
\begin{description}
|
|
\item[Les services] (aussi appelés \term{providers}) contiennent l'implémentation de la logique nécessaire
|
|
pour répondre aux besoins de l'application: contacter une base de donnée, traiter l'information, faire des
|
|
requêtes réseau, etc.
|
|
|
|
\item[Les controleurs] sont responsables d'accepter les requêtes des \entity{clients}, de les transformer, de vérifier
|
|
leur légitimité et d'appeler les méthodes des \entity{services} avant de transformer la réponse à envoyer au \entity{client}.
|
|
\\
|
|
NestJS fournit un ensemble d'outils simplifiant l'implémentation des controleurs.
|
|
|
|
\item[Les modules] s'occupent de gérer la configuration des \entity{services} et des \entity{controleurs}:
|
|
chaque \entity{module} indique à NestJS quels \entity{services} et \entity{controleurs} il contient,
|
|
ainsi que comment NestJS doit construire ces services dans les cas plus complexes.
|
|
\\
|
|
Les modules peuvent exporter un sous-ensemble de leurs services, ce qui permet de rapidement
|
|
réutiliser des services en important le module leur étant associé. \figref{nestjs2}
|
|
\end{description}
|
|
|
|
\begin{figure}[H]
|
|
\centering
|
|
\includegraphics{nestjs3}
|
|
\caption{Organisation d'un module NestJS typique}
|
|
\label{nestjs3}
|
|
\end{figure}
|
|
|
|
|
|
La séparation entre controleurs et services permet d'avoir une claire \term{séparation des préoccupations}:
|
|
|
|
\begin{itemize}
|
|
\item Les controleurs s'occupent de gérer, valider et répondre aux requêtes faites par un client;
|
|
\item Les services s'occupent de l'implémentation de la logique permettant de satisfaire la requête;
|
|
\item Les modules s'occupent de configurer les services et les controleurs, et permettent la modularisation du code.
|
|
\end{itemize}
|
|
|
|
Pour limiter le couplage entre les services, et pour simplifier la réutilisation des services,
|
|
NestJS permet de faire de l'\term{injection de dépendances} par \term{constructeur sans défaut} \cite{yang2008empirical} dans les services et dans les controleurs,
|
|
d'une manière similaire au framework \entity{Spring} en \entity{Java}. \figref{nestjs1}
|
|
|
|
% TODO: trouver une source
|
|
% Separation of concerns
|
|
% https://citeseerx.ist.psu.edu/document?repid=rep1&type=pdf&doi=0fd24fa8ac2a77c4709103eb8a179fec38311fe8
|
|
% "On the importance of the separation-of-concerns principle in secure software engineering"
|
|
Il devient ainsi plus simple avec ce système de modifier différentes parties du code sans accidentellement casser une autre partie du code.
|
|
Il est aussi plus simple de tester du code organisé de la manière suivante, car les services et les controleurs peuvent
|
|
être placés dans un environnement isolé et testés individuellement ou collectivement.
|
|
|
|
|
|
\subsection{Système d'envoi de mail}
|
|
|
|
\subsubsection{Analyse et prototype}
|
|
|
|
On m'a donné en début de stage la tâche d'implémenter un système d'envoi de mail pour \entity{Mint Service}.
|
|
Ce système prend la forme de plusieurs librairies, qui doit remplir les conditions suivantes:
|
|
|
|
\begin{itemize}
|
|
\item Il doit être facilement réutilisable dans d'autres projets.
|
|
\item Il doit permettre de changer de fournisseur de service pour l'envoi d'emails sans devoir faire de grands changements du côté des utilisateurs de la librairie.
|
|
\item Il doit pouvoir envoyer des emails qui s'affichent de la manière voulue sur la majorités des boîtes mail.
|
|
\item Il doit pouvoir envoyer des emails contenant des informations sur l'utilisateur; cette étape devra être faite avec le service de \term{templates} d'email sur \entity{Amazon SES} \cite{amazonses} \cite{amazonsestemplate}
|
|
\item Il doit permettre de décrire le contenu des emails d'une manière facilement maintenable et réutilisable.
|
|
\end{itemize}
|
|
|
|
Mon travail a commencé par l'analyse de différentes solutions permettant d'adresser les deux dernières conditions.
|
|
|
|
Par le passé, l'entreprise avait déjà utilisé le moteur \entity{Handlebars} \cite{handlebars},
|
|
une librairie de recherche et de remplacement de texte, qui permet d'avoir des formes simples de logique,
|
|
comme des conditions ou des boucles.
|
|
|
|
Bien que \entity{Handlebars} fonctionne bien pour insérer les informations de l'utilisateur dans les mails,
|
|
il ne permet pas de facilement réutiliser du code, qui est souvent complexe afin d'assurer un bon affiche sur les
|
|
différents programmes de boîte mail.
|
|
|
|
J'ai donc cherché à avoir un système de \og composants \fg dans la solution choisie, afin de pouvoir construire des couches
|
|
d'abstraction et de réutiliser facilement le code. Ces composants doivent, plus spécifiquement:
|
|
|
|
\begin{itemize}
|
|
\item Pouvoir être appelés avec différentes valeurs en arguments
|
|
\item Pouvoir appeler d'autres composants
|
|
\end{itemize}
|
|
|
|
% TODO: source sur search and replace
|
|
J'ai selectionné deux moteurs de recherche et de remplacement de texte (\term{Search and Replace}): \entity{Handlebars} \cite{handlebars} et \entity{Mustache} \cite{mustache}.
|
|
Ces deux moteurs opèrent de manière similaire: ils lisent le code source,
|
|
et lorsqu'une variable indiquée par les balises \texttt{\{\{} et \texttt{\}\}} est rencontrée,
|
|
celle-ci est subtituée par la valeur assignée au nom de cette variable.
|
|
|
|
\entity{Handlebars} et \entity{Mustache} peuvent tous les deux être utilisés pour implémenter le système de composants voulu,
|
|
car ils permettent de définir des variables spéciales, que les deux moteurs appelent \term{partials},
|
|
qui peuvent appeler du code javascript arbitraire.
|
|
|
|
J'ai enfin fait un prototype en \entity{Typescript},
|
|
qui transforme un email décrit à partir de composants \entity{Handlebars} ou \entity{Mustache} en du HTML.
|
|
|
|
Après avoir montré ce prototype à mon chef de projet, nous étions tous les deux d'accord que le moteur \entity{Handlebars}
|
|
remplissait mieux nos attentes, en grande partie parce que \entity{Handlebars} permet de passer du code en tant qu'\og enfants \fg,
|
|
tandis que \entity{Mustache} requiet de passer par deux composants (un avant et un après le code \og enfant \fg). \figref{hbs1}
|
|
|
|
\inputfig{hbs1}
|
|
|
|
Pour le premier projet sur lequel \entity{Mint Service} allait être déployé,
|
|
\entity{Amazon SES} \cite{amazonses} allait être utilisé pour faire l'envoi de mails.
|
|
\entity{Amazon SES} permet d'envoyer les emails sous format texte et HTML en même temps,
|
|
permettant d'avoir des emails facilement lisibles par un lecteur d'écran
|
|
ou sur une messagerie configurée pour afficher les mails sans leur mise en forme.
|
|
|
|
La partie \entity{Handlebars} a donc été étendue pour permettre d'annoter quels parties du code doivent être
|
|
placés dans la version texte du mail. [Figures~\ref{hbs2a} et \ref{hbs2b}]
|
|
|
|
\inputfig{hbs2}
|
|
|
|
\subsubsection{Implémentation initiale dans Mint-Service}
|
|
|
|
Une fois que le prototype me donnait des résultats satisfaisants,
|
|
j'ai pu passer à l'implémentation au propre du système d'envoi de mails dans \entity{Mint Service}.
|
|
Cette première implémentation devait faire l'envoi de mail en deux étapes:
|
|
|
|
\begin{enumerate}
|
|
\item Les mails sont chargés et sont rendus, puis sont mises en lignes sur \entity{Amazon SES} en tant que \og templates \fg \cite{amazonsestemplate}
|
|
\item Les mails sont ensuite envoyés en instructant à \entity{Amazon SES} de faire le rendu et l'envoi d'une des \term{templates} à l'adresse mail voulue, avec les données voulues
|
|
\end{enumerate}
|
|
|
|
J'ai d'abords créé et implémenté une librairie permettant de compiler du code \entity{Handlebars}
|
|
ainsi que des composants en format HTML et en format texte, nommée \texttt{handlebars-generator}. Cette librairie ne s'occupe pas du
|
|
chargement des fichiers, ni de l'envoi des mails, et est implémentée sans framework,
|
|
ce qui permet de la réutiliser dans le futur pour d'autres projets.
|
|
|
|
Puis, j'ai créé et implémenté une librairie Nest.JS nommée \texttt{mailing-nest} qui s'occupe de:
|
|
|
|
\begin{itemize}
|
|
\item Charger les composants et les emails depuis un dossier donné
|
|
\item Transformer ceux-cis avec \texttt{handlebars-generator} en HTML et en texte
|
|
\item Mettre en ligne des \term{templates} pour utiliser le service d'envoi d'emails personalisés d'\entity{Amazon}
|
|
\item Envoyer les \term{templates} avec les informations de l'utilisateur dedans avec \entity{Amazon SES}
|
|
\end{itemize}
|
|
|
|
Afin de pouvoir tester le fonctionnement de la librairie \texttt{mailing-nest},
|
|
j'ai également créé une petite application Nest.JS qui affiche dans le navigateur les emails en format HTML et en format texte.
|
|
Cette application permet aussi de développer rapidement les emails sans devoir passer par Amazon pour tester
|
|
les modifications.
|
|
|
|
% TODO: screenshots
|
|
|
|
Enfin, j'ai implémenté un module Nest.JS dans l'application \entity{Mint Service},
|
|
qui charge le module de \texttt{mailing-nest} avec en paramètre le chemin des emails pour \entity{Mint}.
|
|
Ce module est importé à plusieurs endroits dans le code, et expose des méthodes dans son service permettant
|
|
de convertir les entités de \entity{Mint Service} au format attendu par les emails.
|
|
|
|
\begin{figure}[H]
|
|
\includegraphics[width=\textwidth]{mailingnest}
|
|
\caption{Organisation initiale du système d'envoi de mail dans Mint-Service}
|
|
\end{figure}
|
|
|
|
Avec le système de mail en place, j'ai pu implémenter la première template d'email, qui était celle pour l'envoi d'identifiants au patients.
|
|
Très rapidement, j'ai pu voir sur \url{caniemail.com} que la quasi-totalités des fonctionnalités HTML5 modernes n'étaient pas supportés par \entity{Microsoft Outlook},
|
|
ce qui nous forcerait à utiliser des \texttt{<table>} dans l'entièreté des emails pour pouvoir supporter \entity{Microsoft Outlook},
|
|
qui est à ce jour le 3ème client email le plus utilisé du monde \cite{oberloemailclients}.
|
|
|
|
Une solution à ce problème est d'utiliser une librairie assurant la compatibilité avec \entity{Outlook}.
|
|
J'ai choisi la librairie \entity{MJML} \cite{mjml}, qui utilise un langage ressemblant au html, qui est ensuite compilé en HTML compatible avec \entity{Outlook}:
|
|
|
|
\inputfig{email}
|
|
|
|
\subsection{Rétrospective sur le système d'envoi de mails}
|
|
|
|
% - [x] parler des désavantages de cette méthode
|
|
% - [x] parler de ce qu'on prévoyait de faire
|
|
% - [~] parler de comment on l'a fait (pour showcase l'avantage du monorepo), et des étapes prises
|
|
% - [x] parler des améliorations futures qui pourront être faites
|
|
% (ajouter plus de providers, simplifier la logique pour choisir les providers, react.email, svelte, etc.)
|
|
% - [ ] Comparer la maintenabilité
|
|
|
|
Après avoir fini l'implémentation du système de mail, j'ai pu l'observer alors qu'il est passé par la vérification de qualité,
|
|
des déploiements et recettes sur un serveur local, et enfin des déploiements chez les clients.
|
|
|
|
Les deux librairies ont vu peu de changements, et ont fonctionné comme voulu.
|
|
L'organisation du code au sein de \entity{Mint Service} a pris deux essais pour arriver à un format satisfaisant:
|
|
le premier essai plaçait l'envoi des mails dans un service dédié à la gestion des utilisateurs (\texttt{GuestModule}),
|
|
mais il s'averrait qu'il fallait assez de code pour préparer les informations des mails qu'il était préférable de déplacer la logique d'envoi des mails dans un module à part, \texttt{MintMailingModule}.
|
|
|
|
Malgré \entity{MJML} et le système de composants, écrire des templates d'emails reste plus compliqué à écrire que du code React:
|
|
|
|
\begin{itemize}
|
|
\item La différence de format entre les templates Handlebars/MJML et les composants React fait qu'il est difficile d'appliquer les intuitions valables pour le React lorsqu'on écrit ou réécrit des templates d'emails.
|
|
\\
|
|
Ceci est en grande partie dû au fonctionnement de MJML,
|
|
qui requiet une structure stricte dans le code (\texttt{mj-body} $\rightarrow$ \texttt{mj-section} $\rightarrow$ \texttt{mj-column} $\rightarrow$ texte).
|
|
\\
|
|
HTML lui a une structure plus flexible,
|
|
permettant d'imbriquer la pluspart des éléments disponibles dans un ordre arbitraire. \cite{mdncontentcategories}
|
|
|
|
\item Le choix de faire le rendu final des templates via les templates d'\entity{Amazon SES} rend l'écriture des emails plus compliquée
|
|
(il faut mixer ensemble deux différents formats handlebars, l'un étant interprété de notre côté, et l'autre étant interprété du côté d'\entityb{Amazon SES} \figref{emailsrchbs}).
|
|
\\
|
|
Ce choix rend aussi le débogage de toute erreur lors du deuxième rendu très compliqué,
|
|
car le seul moyen pour accéder aux erreurs d'envoi de mails sur \entityb{Amason SES} est de mettre en place un système
|
|
de transfert de messages, puis de l'activer en envoyant les mails avec un paramètre précis.
|
|
\end{itemize}
|
|
|
|
Pour palier à la deuxième difficulté, j'ai décidé vers la fin de mon stage de modifier l'implémentation du système d'envoi de mails,
|
|
afin de faire l'entièreté du rendu de notre côté, et d'uniquement utiliser \entity{Amazon SES} pour l'envoi pur des mails.
|
|
|
|
J'avais également comme but secondaire de rendre ce système plus robuste,
|
|
en permettant notamment l'insertion de code pour vérifier la validité des données insérées dans les emails lorsqu'on est dans un environnement de développement.
|
|
|
|
Les modifications ont été faites dans l'ordre suivant, qui permettait de progressivement appliquer les changements nécessaires:
|
|
|
|
\begin{enumerate}
|
|
\item Suppression de la transformation des balises secondaires (\texttt{[[} et \texttt{]]}) et des options associées
|
|
\item Marquage de différents types comme dépréciés, et ajout de types pour l'envoi pur d'emails
|
|
\item Dépréciation des méthodes d'envoi d'email via les templates SES (\texttt{sendTemplatedEmail}), et ajout des méthodes pour l'envoi pur d'emails (\texttt{sendEmail})
|
|
\item Modification des templates pour ne plus utiliser les balises secondaires
|
|
\item Modification de l'application de prévisionage des emails pour utiliser le nouveau format des informations substituées dans les mails
|
|
\item Modification de \entity{Mint Service} pour utiliser \texttt{sendEmail} au lieu de \texttt{sendTemplatedEmail}
|
|
\item Suppression de \texttt{UploadModule} et de \texttt{sendTemplatedEmail}
|
|
\item Suppression des types inutilisés
|
|
\end{enumerate}
|
|
|
|
À la suite de ces modifications, les emails s'affichent de la même manière qu'avant,
|
|
et le système d'envoi de mails est désormais plus simple à utiliser
|
|
et plus simple à étendre avec différents services d'envoi de mail.
|
|
|
|
Je n'ai pas pu implémenter le système de validation des données, par soucis de difficulté d'implémentation:
|
|
il aurait fallu étendre le système de chargement de composants pour également charger du code Javascript,
|
|
et transformer le format des données utilisé par Handlebars en un format facilement vérifiable.
|
|
\\
|
|
Il est par contre maintenant possible d'écrire dans \entityb{Mint Service} des tests pour s'assurer que la logique de transformation des données reste compatible avec les emails.
|
|
|
|
À la suite de cette modification,
|
|
je pense qu'il est encore possible d'améliorer de différentes manières ce système d'envoi de mails:
|
|
|
|
\begin{itemize}
|
|
\item En ajoutant plus de tests automatisés dans le système, notamment des tests d'intégration
|
|
\item En rendant les différents modules plus simples d'utilisation
|
|
\item En permettant d'utiliser une syntaxe plus proche de celle de React pour appeler des composants (\texttt{<Composant>} au lieu de \texttt{\{\{>Composant\}\}})
|
|
\item En utilisant un système comme \href{https://react.email/}{React Email} ou \href{https://astro.build/}{Astro} pour écrire les templates en Javascript, ce qui permetterait aussi de faire de la vérification des données et des types.
|
|
\end{itemize}
|
|
|
|
\begin{figure}[H]
|
|
\includegraphics[width=\textwidth]{mailingnest-2}
|
|
\caption{Organisation finale du système d'envoi de mail dans Mint-Service}
|
|
\end{figure}
|
|
|
|
\section{Travail sur Mood TV}
|
|
|
|
\subsection{Introduction?}
|
|
|
|
\entity{Mood TV} est une application tournant sur les télévisions \og intelligentes \fg produites par \entity{LG}.
|
|
Ces télévisions font tourner le système d'exploitation \entity{WebOS}, et la version pour laquelle nous visons l'application utilise \entity{Chrome 53}.
|
|
|
|
Comme ces télévisions utilisent chrome, notre application peut être programmée entièrement en React,
|
|
à condition de s'assurer que le code javascript soit compatible avec cette version de chrome.
|
|
|
|
Mon travail sur \entity{Mood TV} a été d'optimiser le temps de chargement de la page:
|
|
avant, celle-ci prenait environ 10 secondes à charger,
|
|
et j'ai été laissé en autonomie pour trouver pourquoi le temps de chargement est si haut et comment le baisser.
|
|
|
|
% Présentation de la plateforme, des télés (chrome 53 hehe), mentionner procentric
|
|
% Parler de l'hydration, du rendu, etc.
|
|
|
|
\subsection{Analyse des performances}
|
|
|
|
La première étape avant de pouvoir optimiser les performances de l'application est de mesurer ses performances.
|
|
Il faut pour celà mesurer de manière précise le temps moyen de chargement,
|
|
et il faut pouvoir avoir un aperçu de quelles opérations prennent le plus de temps.
|
|
|
|
J'ai tout d'abords activé le mode de débogage sur la télévision,
|
|
qui peut être fait via l'API propriétaire de contrôle de la télévision.
|
|
Avec ce mode de débogage, on peut se connecter depuis une interface web aux outils de développeur du navigateur tournant sur la télévision.
|
|
|
|
J'ai ensuite pu prendre plusieurs profils de performance pour observer quelles opérations prenait le plus de temps:
|
|
|
|
\begin{figure}[H]
|
|
\includegraphics[width=\textwidth]{mood-tv-before.png}
|
|
\caption{Profil du chargement de la page, avant toute optimisation; annoté}
|
|
\label{moodtvbefore}
|
|
\end{figure}
|
|
|
|
On peut séparer le temps de chargement en différentes étapes:
|
|
|
|
\begin{enumerate}
|
|
\item Le chargement initial (en bleu), qui est le moment durant lequel le navigateur télécharge le code javascript,
|
|
et durant lequel \entity{webpack} prépare ce code pour reproduire un environnement modulaire moderne.
|
|
\item L'hydration \cite{hydration}, qui est une étape du rendu avec React: cette étape du chargement permet à React d'attacher
|
|
son arborescence d'état au HTML existant, permettant d'intéragir dans le code React avec les éléments du DOM.
|
|
\item La réception des \og catégories \fg, qui consiste au traitement de deux requêtes faites à l'API sur laquelle se trouve le \term{Content Management System}
|
|
\item L'envoi de requêtes pour récupérer les informations des films présents dans ces catégories
|
|
\\
|
|
On peut déjà observer sur cette capture d'écran que cet envoi est en triple, alors qu'il ne devrait n'y avoir qu'une vague.
|
|
\item La réception des informations de films, et le traitement du résultat de ces requêtes.
|
|
\end{enumerate}
|
|
|
|
Ensuite, il me fallait un moyen de mesurer de manière précise les performances avant de pouvoir faire des changements.
|
|
La solution que j'ai trouvé a été de créer et d'implémenter un protocole d'envoi et de réception de performances: \figref{moodtvperf}
|
|
|
|
\begin{itemize}
|
|
\item La télévision mesure les performances avec l'API javascript \texttt{Performance} \cite{performanceapi},
|
|
puis envoie ces valeurs via une requête sur un petit serveur sur mon ordinateur.
|
|
|
|
\item Ce serveur stoque ensuite toutes les valeurs reçues dans un fichier,
|
|
et peut relire de ce fichier si jamais il faut reprendre la mesure de performance.
|
|
|
|
\item Un programme lit les valeurs du fichier, puis calcule la moyenne, l'écart standard de ces valeurs.
|
|
Ce programme peut aussi lire deux fichiers, et comparer les performances entre ceux-cis.
|
|
\end{itemize}
|
|
|
|
\begin{figure}[H]
|
|
\includegraphics[width=\textwidth]{moodtvperf}
|
|
\caption{Protocole d'envoi et de réception de performances}
|
|
\label{moodtvperf}
|
|
\end{figure}
|
|
|
|
Les valeurs obtenues sont sous la forme de listes de nombres, une liste par métrique mesurée.
|
|
Soit $(\omega_1, \omega_2, ..., \omega_n)$ une telle liste.
|
|
Si on suppose que ces valeurs correspondent à différents résultats d'une même expérience $X$,
|
|
alors on peut calculer la moyenne empirique ($\mu^{\star}_n$) et la variance ($(\sigma^{\star}_n)^2$) empirique de ces valeurs de la manière suivante:
|
|
|
|
\begin{align*}
|
|
\mu^{\star}_n &= \frac{\sum_{i=1}^{n} \omega_i}{n} \\
|
|
(\sigma^{\star}_n)^2 = S_{n-1} &= \frac{\sum_{i=1}^{n} (\omega_i - \mu^{\star}_n)^2}{n-1} \\
|
|
&= \frac{(\mu^{\star}_n)^2}{n-1} - \frac{\sum_{i=1}^{n} \omega_i^2}{n(n-1)} \\ \\
|
|
\mu^{\star}_n \xrightarrow{n\rightarrow\infty} \mu & \quad \quad \quad \sigma^{\star}_n \xrightarrow{n\rightarrow\infty} \sigma
|
|
% TODO: preuve?
|
|
\end{align*}
|
|
|
|
Afin de pouvoir comparer différents ensembles de valeurs,
|
|
je fais l'hypothèse que les valeurs suivent une loi normale ($X \hookrightarrow \mathcal{N}(\mu, \sigma^2)$).
|
|
% TODO: refine
|
|
Dans ce cas, on peut utiliser une approximation de la distribution de student pour calculer un intervale de confiance pour $\mu$.
|
|
J'utilise comme taux de confiance $\alpha = 0.95$:
|
|
|
|
\begin{align*}
|
|
\mu &\in [\mu^{\star}_n - z_{1-\alpha/2} \frac{\sigma^{\star}_n}{\sqrt{n}}, \mu^{\star}_n + z_{1-\alpha/2} \frac{\sigma^{\star}_n}{\sqrt{n}}] \\
|
|
z_a \;&\text{est tel que} \int_{-\infty}^{z_a}{\frac{e^{-\frac{(x-\mu)^2}{2\sigma^2}}}{\sigma\sqrt{2\pi}}}=a
|
|
\end{align*}
|
|
|
|
Enfin, on peut utiliser le t-test pour estimer si deux valeurs différentes $X$ et $Y$ diffèrent bien de moyenne. \cite{ttest}
|
|
|
|
Pour \entity{Mood TV}, les valeurs mesurées sont les suivantes, en millisecondes:
|
|
|
|
\begin{itemize}
|
|
\item Le temps jusqu'au début de l'hydration: \textbf{hydration}
|
|
\item Le temps jusqu'à la première éxecution des \texttt{useEffect}: \textbf{mount}
|
|
\item Le temps jusqu'à ce que l'entièreté des requêtes pour charger les informations des films soient finies: \textbf{ready}
|
|
\end{itemize}
|
|
|
|
\inputfig{perf1}
|
|
|
|
% Screenshot du panel des performances sur mood tv (avant et après)
|
|
% Parler de la loi du milieu, du Z-test, du test de normalité, de comment récupérer ces données
|
|
|
|
\subsection{Optimisation du temps de chargement}
|
|
|
|
% - [x] Optimisation du nombre de requêtes faites (avec un dessin? ~ plus tard)
|
|
% - [x] Optimisation de la taille du bundle
|
|
% - [x] Optimisation du parsing des requêtes
|
|
% - [x] Avoir de jolis nombres
|
|
% - [ ] tableau final avec toutes les mesures
|
|
|
|
\subsubsection{Optimisation du nombre de requêtes}
|
|
|
|
La première optimisation a été d'éviter que les requêtes pour récupérer les informations sur les films ne soient envoyées plusieures fois.
|
|
La fonction pour faire la requête pour une catégorie (\texttt{getItems}) utilisait un \texttt{useCallback} et un cache gêré par React,
|
|
ce qui faisait que dès que les informations d'un film était récupéré et stocké dans le cache, React assignait une nouvelle référence à \texttt{getItems},
|
|
causant le \texttt{useEffect} responsable pour charger l'ensemble des informations des films à s'éxecuter à nouveau,
|
|
et de nouvelles requêtes sont envoyées en conséquence. \figref{fromeffectloop}
|
|
|
|
Pour résoudre ce problème, j'ai créé une nouvelle fonction qui récupère l'entièreté des informations des films,
|
|
et qui seulement une fois que toutes les requêtes soient finies stoque ces informations dans le cache.
|
|
|
|
\inputfig{perf2}
|
|
|
|
\subsubsection{Optimisation de la taille du bundle}
|
|
|
|
Ensuite, j'ai optimisé la taille du bundle javascript, pour passer de $350$ kilooctets à $243$ kilooctets,
|
|
en enlèvant les librairies qu'on n'utilisait peu et qui prenaient beaucoup de place, comme \texttt{browserify-crypto}.
|
|
|
|
Réduire la taille du bundle permet de réduire le temps passé à télécharger le code javascript de la page,
|
|
et le temps passé à compiler ce code et à charger les différents modules avec \entity{webpack}.
|
|
|
|
\inputfig{perf3}
|
|
|
|
\subsubsection{Optimisation du traitement des réponses}
|
|
|
|
Enfin, j'ai optimisé la logique de traitement des réponses des requêtes pour récupérer les informations sur les films.
|
|
Ce traitement, jusqu'à ce moment, se faisait grâce à la librairie \texttt{class-transformer} \cite{classtransformer},
|
|
qui permet de facilement transformer des objets ordinaires en instances de classe.
|
|
|
|
Cette librairie est utilisée pour transformer les résultats des requêtes, qui sont sous forme d'objets ordinaires,
|
|
en instances de classes proposant des fonctions pour facilement traiter les informations contenues dedans.
|
|
Malheureusement, \texttt{class-transformer} ajoute beaucoup de temps de calcul, qui sur le hardware de la télévision connectée,
|
|
se traduit en secondes de chargement en plus. \cite{classtransformerbenchmark}
|
|
|
|
J'ai donc remplacé \texttt{class-transformer} par une transformation manuelle pour les listes de films,
|
|
qui copie manuellement les données des films et des catégories en instances de classe.
|
|
|
|
Avant de faire ce changement, j'ai d'abords écrit des tests unitaires pour vérifier le comportement du système déjà en place.
|
|
Puis, j'ai progressivement modifié les fonctions de traitement de requête affectées pour utiliser ma transformation manuelle à la place.
|
|
|
|
% Les seuls tests présents auparavant étaient des tests d'intégration, qui avaient cassé au fil des mois et qui ne fonctionnent plus ajourd'hui.
|
|
% J'ai donc dû nettoyer les tests d'intégration existants pour les faire tourner séparemment des tests unitaires.
|
|
|
|
\inputfig{perf4}
|
|
|
|
\subsection{Résultats et rétrospective}
|
|
|
|
Avec ces optimisations, la page prend désormais entre 4 et 6 secondes pour charger, contre 10 à 15 secondes auparavant.
|
|
Le temps d'éxecution sur le processeur de la télévision n'est aussi plus un engorgement,
|
|
et on peut voir sur le profil des performances qu'une bonne partie du temps est passé à attendre que les différentes requêtes se finissent. \figref{moodtvafter}
|
|
|
|
\begin{figure}
|
|
\includegraphics[width=\textwidth]{mood-tv-after.png}
|
|
\caption{Profil du chargement de la page, après les optimisations; annoté}
|
|
\label{moodtvafter}
|
|
\end{figure}
|
|
|
|
Faire ce travail m'a permis d'avoir une compréhension plus profonde sur différents sujets:
|
|
|
|
\begin{itemize}
|
|
\item Les techniques d'optimisation logicielle (profilage, benchmarking)
|
|
\item Le modèle de propagation de mises à jour de React (\texttt{useEffect}, les boucles d'évenements infinies \figref{fromeffectloop})
|
|
\item L'optimisation de la taille des bundle javascript
|
|
\item L'extraction de données de performances depuis le navigateur (web vitals \cite{webvitals}, \texttt{reportWebVitals} sur Next.JS \cite{nextjsvitals})
|
|
\item L'analyse de données de performances (z-test, t-test, intervale de confiance)
|
|
\end{itemize}
|
|
|
|
|
|
\makeutbmbackcover{}
|
|
\newpage
|
|
|
|
\begingroup
|
|
\raggedright
|
|
\bibliographystyle{plain}
|
|
\bibliography{references}{}
|
|
\endgroup
|
|
|
|
\newpage
|
|
\section{Annexes}
|
|
|
|
\subsection{Listings de code}
|
|
|
|
\inputfig{nestjs1}
|
|
\inputfig{nestjs2}
|
|
\inputfig{email-src-hbs}
|
|
\inputfig{email-src-mjml}
|
|
% \inputfig{ttest}
|
|
\inputfig{fromeffectloop}
|
|
|
|
|
|
\end{document}
|