HellFest “Open Air Edition”, part II – IoC/ PixIoC Workflow Guidelines and Performance Optimization (Object Pooling)
Hellfest, un site Full Flash réalisé en IoC ActionScript, Part II
This article is available in French (available in Spanish in a few hours)
WORKFLOW (ECLIPSE/ FDT)
AUTOMATISATION DES PROCESS
Le corollaire d’un développement IoC est un workflow permettant d’atomiser les processus de développement et d’exécuter quand cela est nécessaire des sous-ensembles d’opérations concernant des plugins ayant vocation à interagir ensemble.
EXCLUSIONS ET LIBRAIRIES PARTAGÉES
Les tâches Ant nous permettent de synchroniser l’exclusion des classes communes aux plugins lors de leur compilation (notamment celles déjà présentes dans l’assembler).
En excluant les classes redondantes nous réduisons de façon drastique le poids de chaque plugin et la durée globale de chargement des dlls (et par là, la consommation de bande passante).
1. Le shell (Assembler.swf) comme réservoir des librairies partagées
(Les classes propres à certains plugins sont le cas échéant incluses dans le shell)
2. Externalisation des librairies partagées dans un dll autonome.
Le poids total de l’application augmente (l’assembler et SharedLib ont des classes en commun)
3. Chaque plugin embarque son lot de classes (pas d’exclusion).
Le poids total de l’application explose et le différentiel s’accroit de plus en plus à mesure de l’ajout de nouveaux plugins
PUISSANCE DES BUILDS
A chaque plugin correspond une build particulière permettant non seulement d’atomiser les développements mais aussi d’accélérer les phases de tests. Certaines builds ont des vocations thématiques facilitant le test de groupes de plugins.
GESTION DES PLUGINS ET PERFORMANCE
Le Player à tendance à abuser des ressources processeur et mémoire dès lors que vous tendez à la réalisation d’ une application riche en interactivité et visuellement fourni. Préserver un équilibre entre la qualité de lecture et l’ exécution du code peut relever d’un vrai travail de laboratoire. Cette partie ne traite pas de tips concernant l’écriture d’un code optimisé ou la manipulation de certaines APIs. Pour cela vous pouvez notamment vous reportez aux 2 excellent articles suivants publiés par la team de BigSpaceShip :
http://labs.bigspaceship.com/2006/12/08/flash-performance-tips-part-i/ http://labs.bigspaceship.com/2007/02/28/flash-performance-tips-part-ii/
Ma prétention se limite ici à l’exposé d’un moyen par lequel améliorer les performances du Player tout en donnant, dans la foulée, davantage de flexibilité à vos application IoC.
PLUGINS À LA DEMANDE
Attention à ne pas confondre le sujet ici exposé avec le thème du chargement et instanciation différée des UI (AbstractMovieClipHelper) ainsi que celui des macroplugins (inclusion de contexts additionnels au runtime).
Classiquement, vos plugins sont définis (c’est à dire instanciés) dans le fichier de configuration de base (applicationContext.xml). Cela induit certaines contraintes concernant la souplesse et la performance de l’application.
Prenons pour exemple, le plugin Scrollbar. Selon les besoins il sera potentiellement sujet à instanciation en différentes parties du site et/ où à différents moments, que ce soit à raison d’une ou plusieurs occurrences simultanées. Voici les limitations de l’implémentation:
- Tous les cas recensés d’utilisation du plugin conduisent à un nombre équivalent d’ instanciation (autrement dit, si, durant le cycle de vie de l’application je recense n occurrences de Scrollbar, je dois préparer n instanciations du plugin dans l’applicationContext).
- Un XML long à parser et un nombre élevé d’initialisations constructeurs congèlent l’éxécution générale de l’application d’autant de temps nécessaire à leur digestion par le Player (il n’est pas multithreadé).
Idéalement vous ne devriez donc instancier vos plugins seulement lorsque cela s ‘avère nécessaire.
De là, jaillit une nouvelle difficulté, la gestion du cycle de vie de plugins dynamiques. En effet, comment gérer sans conflits et de façon optimisée un parc de plugins instanciés au runtime ?
Instanciation dynamique et gestion des occurences
La mise en cache des objets permet de gérer les instanciations à la demande en stockant et libérant après usage pour réutilisation ultérieure les occurrences créées dynamiquement. Le nombre d’instanciations maximums prévues s’en trouve donc potentiellement réduit.
EspaceProPlugin avec « object pooling »
EspacePro réclame au manager de plugin (ObjectPoolingPlugin) le nombre d’occurrences de DynProxyForm dont il a besoin (en théorie une occurrence pour chaque movieclip). Ici, une seule occurrence est créée car les formulaires sont gérés à tour de rôle et non simultanément.
EspaceProPlugin sans « object pooling »
Contraignant et verbeux, il nous faut recenser le nombre d’occurrences nécessaires et les déclarer dans l’applicationContext. Le total des objets à instancier est égal au maximum recensé (4 occurences) et l’implémentation d’EspacePro est plus complexe car il faut vérifier si les dépendances (DynProxyFormPlugin) sollicitées sont bien initialisés.
En conclusion nous profitons des avantages suivants:
- On s’affranchit de certaines déclarations d’ objets dans la configuration.
- Economie réalisée sur le nombre total des instanciations.
- Mise en cache et recyclage des occurences.
Le verdict est sans appel, l’ utilisation de l’ Object Pooling autorise une architecture plus souple en même temps qu’il permet à l’application de gagner en performance!
Liens connexes
Definition historique
Implémentations Object Pooling
- AS3 is FAST! (via Jobe Makar, AS3 Speed And Object Pooling)
- Boost Flex performance with Object Pooling Manager API
- Flex Performance, Memory Management, & Object Caching
- Trying to design some object pooling
- Tweening and object pools at blog.je2050.de - Blog of Joa Ebert














