SharePoint est un framework très riche et puissant, permettant de réaliser facilement et rapidement des applications web, mais encore faut-il savoir ce que l'on en fait. Car un framework peut être aussi puissant et complet que l'on veut, "sans maîtrise, la puissance n'est rien" (non, je n'ai pas d'action chez une célèbre marque de pneumatiques).
Il est facile alors, après des tests concluants sur son environnement de développement, de se dire que tout fonctionne et donc que tout fonctionnera pour le mieux. Malheureusement (ou pas !), ce n'est pas aussi simple.
L'exemple type classique est la mauvaise gestion des SPWeb/SPSite, provoquant ainsi pas mal de stress côté mémoire. Renaud a blogué récemment dessus, je vous invite à lire (et relire) ce billet et particulièrement les 2 liens de Best Practices :
Car on a beau se dire que les liens sont archi connus, la triste réalité revient à la charge quand on tombe sur certains projets.
Au delà donc de ces classiques ressources, il faut surtout s'interroger sur la pertinence du code que l'on écrit :
- quelles sont les données / informations dont j'ai besoin / que je cherche à récupérer ?
- Y a-t-il plusieurs moyens de les obtenir ?
- Si tel est le cas, lequel sera le plus efficace / optimisé ?
Des questions simples, que l'on doit se poser de manière générale dans ses développements (rien de spécifique ici à SharePoint) mais qui, lorsqu'on se lance dans le développement d'applications pour SharePoint et dans l'utilisation du modèle objet de celui-ci, ont tendance à être oubliées.
Vous savez tous très certainement que la quasi totalité des données se trouvent en base de données, avec en plus différents mécanismes de cache, avec un peu de fichiers XML et de configuration. Or, lorsqu'on parcourt un objet SharePoint, un simple appel à une propriété peut effectuer plusieurs requêtes en base, charger des éléments en mémoire, instancier des objets COM etc... Il convient donc de réfléchir un peu à ce que l'on code plutôt que de partir du postulat : "tout est là, déjà chargé en mémoire et directement disponible sans surcoût". Car ce n'est évidemment pas du tout le cas. Ne serait-ce que pour des raisons d'optimisation, le chargement et les exécutions de requête à la demande sont encore le meilleur moyen d'être sûr de ne pas effectuer des tâches inutiles.
Quelques exemples concrets :
- oui, n'ayez pas peur d'utiliser le fameux SPContext, il vous aura déjà chargé la majorité des objets nécessaires (lorsqu'on travaille dans le contexte d'un site web, of course). SPContext.Current.Site et SPContext.Current.Web sont les plus classiques pour obtenir la collection et le site courants (les objets sont déjà instanciés, pas besoin de le faire et surtout ne pas faire de Dispose dessus !, cf les best practices)
- après la récupération de vos éléments de liste issus d'une requête (SPQuery ou SPSiteDataQuery), évitez de parcourir inutilement des sous objets pour récupérer au final des informations déjà présentes initialement. Par exemple, vous récupérez un ensemble de documents à travers votre requête, et vous désirez afficher l'url et certaines métadonnées. Première option :
Deuxième option :
- Dans le deuxième cas, nous utilisons directement les données issues de la requête, et on évite de charger des objets supplémentaires inutiles : accès au File puis encore à sa propriété Item alors que l'élément est déjà récupéré au début.
- Ne pas réinstancier n fois des objets que vous allez utiliser dans un même bloc de code ou même exécution. Par exemple :
- Devra plutôt s'envisager ainsi :
- Evident présenté de la sorte, mais lorsque ces appels sont englobés dans plusieurs méthodes pouvant être appelées indépendamment, ça peut être moins visible. Outre le coût de recréer un SPSite / SPWeb, certaines propriétés sont remplies lors du premier appel et stockées pour la suite. On se retrouve ainsi à générer beaucoup de requêtes inutiles, et donc gréver les performances. Dans le cas où il était nécessaire d'accéder à nouveau à la collection d'utilisateurs, dans le premier cas nous aurions rechargé tous les utilisateurs une deuxième fois, ceci pour rien.
Je m'arrête ici, mais sachez donc analyser votre code et vous poser les bonnes questions au bon moment !
Gat, SPBestPractices