Col-Tracker, part V

La première partie de cette série est disponible ici.

Compression

Grace à la sérialisation de ma classe de base « Bindable » et à la nouvelle API LocalStorage d’HTML 5, il a été plutôt facile d’ajouter de la persistance, permettant à l’utilisateur de sauver dans son navigateur (et de manière persistante) ses instruments, patterns ou même mods complets.

Il reste cependant un petit problème : JSON est très verbeux, et la sérialisation d’un mod complet (même vide) prend… 3,9 millions de caractères ! D’autant plus que comme Javascript utilise UTF16 pour son encodage interne des caractères, ça prend 7,8 Mo !

Ca ne devrait même pas fonctionner puisque LocalStorage est limité par défaut à 5 Mo par site web (d’après ce que j’ai lu, ça ne fonctionnerait probablement pas sur Chrome… C’est une chance que je développe sur Firefox ;o) ).

En cherchant un peu, j’ai trouvé la librairie LZString qui a été écrite justement dans ce but (compresser les chaînes de caractères stockées dans le LocalStorage du navigateur). Ca a l’air de fonctionner mais compresser une chaîne de 3,9 millions de caractères prend un peu de temps.

Heureusement il devrait être possible d’améliorer un peu ces performances. La dé-sérialisation d’un objet s’effectue de la manière suivante :

  • D’abord je crée une nouvelle instance, initialisée avec la valeur par défaut de chaque propriété
  • Puis j’appelle la méthode fromBytes() en lui passant la chaîne de caractère correspondant à la sérialisation de l’objet sauvegardé
  • La méthode fromBytes() remplace la valeur des propriétés présentes dans sérialisation

Il devrait donc être possible de ne sérialiser que les propriétés qui ne sont pas égales à leur valeur par défaut. Faire ce tri n’est pas trivial, mais par contre il y a un moyen très simple de savoir si un objet est égal à sa valeur par défaut : En utilisant la valeur sérialisée d’un objet « neuf » (c’est ce que j’utilise pour permettre la fonction « reset » (utilisée par les boutons « Delete » et « Cut » de l’interface pour réinitialiser un objet)).

Une simple comparaison de chaîne permet donc de savoir si un objet (instrument, note, etc…) est un objet par défaut, et si c’est le cas il suffit de sauvegarder la chaîne « {} » (JSON pour un objet vide) au lieu de sa sérialisation complète.

Ca devrait fonctionner, être rapide, et économiser beaucoup de mémoire.

J’ai fait un test avec un mod presque vide (seulement deux patterns et deux instruments, et le résultat de la sérialisation est réduit à 4531 caractères (ou 9 Ko), soit 800 fois plus court que la version précédente :o)

On pourrait s’arrêter là, mais LZString ne devrait pas avoir de problème à manipuler des chaînes de cette taille, donc essayons de rajouter une étape de compression après la sérialisation : Le mod de test se sérialise maintenant en 383 caractères, soit moins de 1 Ko (10400 fois plus court que la version de départ)

Je pense que je vais m’arrêter là pour la partie sérialisation car maintenant nous avons des tailles de fichier plus qu’acceptables :o)

La sixième partie de cette série est disponible ici.

Un commentaire sur “Col-Tracker, part V

Laisser un commentaire