Optimisation de la longueur des URL avec la sérialisation JavaScript
20/05/2024 - 3 min read
Cet article a été écrit suite au développement de puppetfactory.app.
Au moment d’ajouter ma feature de partage de son avatar, j’ai remarqué que si j’utilisais les query params de mon url pour chaque propriété de mon avatar, j’allais me retrouver avec un lien beaucoup trop long car je possède 9 paramètres. J’ai donc serialisé puis deserialisé mes données pour créer un url plus joli et plus court.
Définitions
La sérialisation et la désérialisation sont des processus fondamentaux en programmation utilisés pour convertir des données d’un format à un autre.
Sérialisation: Processus de conversion des données en une forme qui peut être facilement stockée ou transmise, généralement sous forme de chaîne de caractères ou de flux de données.
Désérialisation: Processus inverse à la sérialisation. Cela permet de restaurer les données sérialiseés dans leur format d’origine.
Cas simplifié
Pour montrer comment j’utilise la sérialisation et la déserialisation dans le cadre de mon projet, je vais utiliser un cas simplifié.
Je vais commencer par récupérer toutes mes données. Mes valeurs sont des images numérotées. Dans ma codebase j’ai fait en sorte de récupérer seulement le chiffre associé à cette image. Pour l’exemple simplifié, je vais utiliser les chiffres en brut.
const data = {
eyes: 4,
hair: 1,
mouth: 3,
};
Sérialisation
Passons maintenant à la function pour sérialiser mes données.
const dataValues = Object.values(data); // [4, 1, 3]
function serialization() {
const encodedBytesFromData = new Uint8Array(dataValues);
const dataSerialized = btoa(
[...encodedBytesFromData].map((b) => String.fromCharCode(b)).join("")
);
return dataSerialized; // "BAED"
}
Dans cette fonction, j’utilise Uint8Array pour créer un tableau d’octets à partir des valeurs de data. J’ai fait le choix d’utiliser le constructeur new Uint8Array
pour que chaque élément utilise une place de 8 bits
au lieu de recourir à un tableau simple, ce qui aurait entraîné une utilisation plus importante de la mémoire.
J’encode ensuite chaque octet en caractère puis en base64 grâce à la méthode btoa().
C’est donc le résultat de cette fonction que je vais stocker dans un query params nommé avatar
.
Cette fonction de sérialisation me permet d’avoir une URL qui ressemble à puppetfactory.app?avatar=BAED
au lieu de pupperfactory.app?eyes=4&hair=1&mouth=1
.
Désérialisation
L’url est cool mais maintenant je veux pouvoir récupérer mes data initiales via le query params avatar
.
C’est ici que rentre en jeu la deserialization et voici ma fonction:
const dataKeys = Object.keys(data); // ["eyes", "hair", "mouth"]
function deserialize(serializedData) {
const decodedData = new Uint8Array(
atob(serializedData)
.split("")
.map((char) => char.charCodeAt(0))
);
const originalData = {};
dataKeys.forEach((key, index) => {
originalData[key] = decodedData[index];
});
return originalData; // { eyes: 4, hair: 1, mouth: 3 }
}
Je fais donc le processus inverse avec la fonction atob qui va me permettre de décoder ma chaîne de caractères en série d’octets puis je les convertis en tableau d’entier grâce à new Uint8Array
.
En parcourant ce tableau, j’associe chaque valeur décodée à sa clé correspondante, rétablissant ainsi mes données initiales.
Conclusion
J’ai appris l’importance de comprendre les techniques de sérialisation et de désérialisation, ainsi que l’utilisation appropriée des structures de données telles que Uint8Array
pour optimiser l’efficacité de la mémoire.
En stockant mes query params sous forme d’une seule chaîne dans l’URL, j’ai pu réduire considérablement sa longueur tout en préservant toutes les informations nécessaires pour reconstruire l’avatar. Cela rend mon URL plus esthétique mais aussi plus pratique à partager.
C’est mon premier article, si jamais vous avez des retours ce sera avec plaisir.