Options de navigation pour SharePoint Online

Important :  Cet article a été traduit automatiquement, voir l’avertissement. Vous pouvez consulter la version en anglais de cet article ici.

Cet article décrit comment faire pour améliorer le temps de chargement de page pour SharePoint Online à l’aide de navigation structurelle et la navigation pilotés par la recherche.

Navigation globale et les requêtes requis pour générer la navigation structurelle peuvent rendre vos pages charger plus lentement dans SharePoint en ligne. C’est parce que chacune de ces requêtes envoie une autre requête à SQL server. Pour chaque site et sous-site dont vous disposez, plusieurs requêtes sont effectuées à SQL server. Ce problème concerne également les pages maîtres. Cela signifie que navigation globale est également concernée.

Certains sites SharePoint, vous devez structures volumineux et complexes. À l’aide de la navigation structurelle à l’emploi, qui utilise le contenu par requête, peut entraîner des temps de chargement de page chargée en raison de plusieurs couches de site. Chacune des couches de sous-sites crée également une autre requête.

Il existe deux options de navigation de prédéfinies principale dans SharePoint, ainsi qu’un troisième, approche personnalisée et pilotés par la recherche. Chaque option présente des avantages et inconvénients comme indiqué dans le tableau suivant.

Navigation structurelle

Navigation gérée

Navigation pilotés par la recherche

Professionnels de le :

  • Facile à configurer

  • Tronqué de sécurité

  • Met à jour automatiquement lors de l’ajout de sites

Professionnels de le :

  • Facile à gérer

Professionnels de le :

  • Tronqué de sécurité

  • Met à jour automatiquement lors de l’ajout de sites

  • Introduction chargement de la structure de navigation dans les temps et mis en cache localement

Inconvénients :

  • Permet d’effectuer mal structure de site complexe

Inconvénients :

  • Pas automatiquement mises à jour pour refléter la structure du site

Inconvénients :

  • Aucune possibilité de facilement des sites de commandes

  • Nécessite une personnalisation de la page maître (compétences techniques nécessaires)

Si vous disposez d’un site avec un grand nombre de sous-sites et que vous utilisez navigation structurelle, il peut être ralentir votre page se charge considérablement vers le bas. L’option la plus appropriée pour votre site dépendent de vos besoins de site et de votre capacité technique. Si vous êtes habitué à utiliser une page maître personnalisée et que certaines fonctionnalités de votre organisation de conserver les modifications pouvant se produire dans la page maître par défaut pour SharePoint Online, l’option de recherche par l’effort produira la meilleure expérience utilisateur. Si vous voulez milieu simple entre la navigation structurelle de prédéfinies et de recherche, la navigation gérée est une excellente option. L’option de navigation gérée peut être gérée par le biais configuration, n’entraîne pas les fichiers de personnalisation de code, et il est beaucoup plus rapide que la navigation structurelle à l’emploi.

Une autre consiste à restructurer le site existant et réduire le nombre d’éléments de navigation et des sous-sites obligatoires. C’est parce que la navigation structurelle effectue bien tant que la structure du site et navigation n’est pas trop compliquée.

Cet article compare les différentes approches dans une collection de sites exemple. La collection de sites exemple a 11 sous-sites et chaque sous-site a au moins quatre sous-sites supplémentaires.

Capture d’écran montrant des sites et des sous-sites

À l’aide de la navigation structurelle dans SharePoint Online

Ceci est la navigation à l’emploi utilisée par défaut et la solution la plus simple et appropriée dans la plupart des cas. Sauf s’il existe une structure complexe de différents sous-sites ou le nombre de niveaux de sous-sites, navigation structurelle fonctionne correctement. Les principaux avantages de cette approche sont qu’il est tronqué de sécurité, met automatiquement à jour lors de l’ajout de nouveaux sites et ne nécessite aucune personnalisation de la page maître. Un utilisateur vont peut également facilement ajouter des éléments, masquer les éléments et gérer la navigation dans la page Paramètres.

Activation de navigation structurelle dans SharePoint Online

Pour illustrer comment les performances dans une solution SharePoint Online standard avec navigation structurelle et le diaporama sous-sites option activé. Ci-dessous est une capture d’écran de paramètres figurant dans la page Paramètres du Site > Navigation.

Capture d’écran montrant des sous-sites

Analyse des performances de navigation structurelle dans SharePoint Online

Pour analyser les performances d’une page SharePoint utilisez l’onglet réseau des outils de développement F12 dans Internet Explorer.

Capture d’écran de l’onglet Réseau dans les outils de développement F12

Sous l’onglet réseau, cliquez sur la page .aspx qui est chargée, puis sous l’onglet Détails.

Capture d’écran montrant l’onglet Détails

Cliquez sur En-têtes de réponse.

Capture d’écran de l’onglet Détails

SharePoint renvoie des informations de diagnostics utiles dans son en-têtes de réponse. Un des plus utiles est SPRequestDuration    qui correspond à la valeur en millisecondes, de la durée pendant laquelle une demande de durée de traitement sur le serveur.

Dans l’écran suivant Afficher les sous-sites n’est pas cochée pour la navigation structurelle. Cela signifie qu’il est uniquement la liaison de collection de sites dans la navigation globale :

Capture d’écran montrant les délais de chargement sous la forme de durées de demande

La touche SPRequestDuration    comporte une valeur de 245 millisecondes. Il s’agit de la durée que nécessaire pour renvoyer la demande. Étant donné qu’un seul élément de navigation sur le site, il s’agit d’une moyenne de fonctionnement de SharePoint Online sans navigation dense. La capture d’écran suivante montre comment ajouter dans les sous-sites affecte cette touche.

Capture d’écran montrant une durée de demande de 2502 ms

Ajout de sous-sites a augmenté considérablement la durée que nécessaire pour renvoyer la demande de page.

Les avantages de l’utilisation de la navigation structurée normale est que vous pouvez facilement organiser l’ordre, masquer des sites, ajouter des pages, les résultats sont tronquées de sécurité et vous ne soyez pas entraînerait les pages maîtres pris en charge dans SharePoint Online. Si vous structurez votre site avec soin et réduisez la quantité de sous-sites dans votre collection de sites navigation structurelle fonctionne correctement.

À l’aide de la navigation gérée et métadonnées gérées dans SharePoint Online

Navigation gérée est une autre option de prédéfinies que vous pouvez utiliser pour recréer le même type de fonctionnalités que navigation structurelle.

L’avantage de l’utilisation de métadonnées gérées est qu’il est beaucoup plus rapide pour extraire les données de l’utilisation du contenu par requête pour générer la navigation du site. Bien qu’il soit que beaucoup plus rapidement il n’existe aucun moyen à la sécurité SUPPRESPACE les résultats donc si un utilisateur n’a pas accès à un site donné, le lien affichera toujours mais vous aboutissez à un message d’erreur.

Comment mettre en œuvre la navigation gérée et les résultats   

Il existe plusieurs articles sur TechNet sur les détails de la navigation gérée, par exemple, voir vue d’ensemble de la navigation gérée dans SharePoint Server 2013.

Afin de mettre en œuvre la navigation gérée, vous avez besoin de magasin de termes de stocker les autorisations d’administrateur. En configurant des termes avec des URL qui correspondent à la structure d’une collection de sites, navigation gérée peut être utilisée pour remplacer navigation structurelle. Par exemple :

Capture d’écran de l’exemple Sous-site 1

L’exemple suivant montre les performances de la navigation complexe à l’aide de la navigation gérée.

Capture d’écran de l’exemple SPRequestDuration

L’utilisation cohérente des navigation gérée améliore les performances par rapport au contenu par approche de navigation structurelle de requête.

À l’aide de la recherche par l’effort l’écriture de script côté client

Utiliser la recherche, vous pouvez exploiter les index sont créés à l’arrière-plan à l’aide de l’analyse continue. Cela signifie requêtes sans contenu dense. Les résultats de recherche sont extraits de l’index de recherche et les résultats sont tronqués de sécurité. Il s’agit plus rapide que l’utilisation des requêtes de contenu normales. Utiliser la recherche pour la navigation structurelle, surtout si vous avez une structure de site complexe, accélère beaucoup de temps de chargement de page. Le principal avantage du présent sur la navigation gérée est bénéficient ajustement de la sécurité.

Cette approche entraîne la création d’une page maître personnalisée et en remplaçant le code de navigation standard par code HTML. Suivez cette procédure pour remplacer le code de navigation dans le fichier seattle.html.

Dans cet exemple, vous ouvrez le fichier seattle.html et remplacer l’élément entier id = « DeltaTopNavigation » avec le code HTML personnalisé.

Exemple : Remplacez le code de navigation standard dans une page maître

  1. Accédez à la page Paramètres du Site.

  2. Ouvrir la galerie de pages maîtres, cliquez sur Pages maîtres.

  3. À partir de là, vous pouvez naviguer dans la bibliothèque et télécharger le fichier seattle.master.

  4. Modifier le code à l’aide d’un éditeur de texte et supprimez le bloc de code dans la capture d’écran suivante.

    Capture d’écran du code DeltaTopNavigation à supprimer
  5. Supprimer le code entre la < SharePoint:AjaxDelta id = « DeltaTopNavigation » > et < \SharePoint:AjaxDelta > balises et le remplacer par l’extrait de code suivante :

    <div id="loading">
      <!--Replace with path to loading image.-->
      <div style="background-image: url(''); height: 22px; width: 22px; ">
      </div>
    </div>
    <!-- Main Content-->
    <div id="navContainer" style="display:none">
        <div data-bind="foreach: hierarchy" class="noindex ms-core-listMenu-horizontalBox">
            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                <span class="menu-item-text" data-bind="text: item.Title">
                </span>
            </a>
            <ul id="menu" data-bind="foreach: $data.children" style="padding-left:20px">
                <li class="static dynamic-children">
                    <a class="static dynamic-children menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                        <span aria-haspopup="true" class="additional-background ms-navedit-flyoutArrow dynamic-children">
                            <span class="menu-item-text" data-bind="text: item.Title">
                            </span>
                        </span>
                    </a>
                    <ul id="menu" data-bind="foreach: children; visible: children.length>0" class="dynamic" >
                        <li class="dynamic">
                            <a class="dynamic menu-item ms-core-listMenu-item ms-displayInline ms-navedit-linkNode" data-bind="attr: { href: item.Url, title: item.Title }">
                                <span class="menu-item-text" data-bind="text: item.Title">
                                </span>
                            </a>
                        </li>
                    </ul>
                </li>
            </ul>
        </div>
    </div>
  6. Remplacer l’URL dans le chargement balise d’ancrage au début, avec un lien vers une image de chargement de votre collection d’images. Une fois les modifications apportées, renommez le fichier et puis téléchargez-le sur la galerie de pages maîtres. Cette action génère un nouveau fichier .master.

  7. Ce code HTML est le balisage de base qui sera rempli par les résultats de recherche à partir du code JavaScript. Vous devez modifier le code suivant pour modifier la valeur de la var root = “site collection URL comme illustré dans l’extrait de code suivante :

    var root = “https://spperformance.sharepoint.com/sites/NavigationBySearch”;

    L’intégralité du fichier JavaScript est la suivante :

    //Models and Namespaces
    var SPOCustom = SPOCustom || {};
    SPOCustom.Models = SPOCustom.Models || {}
    SPOCustom.Models.NavigationNode = function () {
    
        this.Url = ko.observable("");
        this.Title = ko.observable("");
        this.Parent = ko.observable("");
    
    };
    
    var root = "https://spperformance.sharepoint.com/sites/NavigationBySearch";
    var baseUrl = root + "/_api/search/query?querytext=";
    var query = baseUrl + "'contentClass=\"STS_Web\"+path:" + root + "'&trimduplicates=false&rowlimit=300";
    
    var baseRequest = {
        url: "",
        type: ""
    };
    
    
    //Parses a local object from JSON search result.
    function getNavigationFromDto(dto) {
        var item = new SPOCustom.Models.NavigationNode();
        if (dto != undefined) {
    
            var webTemplate = getSearchResultsValue(dto.Cells.results, 'WebTemplate');
    
            if (webTemplate != "APP") {
                item.Title(getSearchResultsValue(dto.Cells.results, 'Title')); //Key = Title
                item.Url(getSearchResultsValue(dto.Cells.results, 'Path')); //Key = Path
                item.Parent(getSearchResultsValue(dto.Cells.results, 'ParentLink')); //Key = ParentLink
            }
    
        }
        return item;
    }
    
    function getSearchResultsValue(results, key) {
    
        for (i = 0; i < results.length; i++) {
            if (results[i].Key == key) {
                return results[i].Value;
            }
        }
        return null;
    }
    
    //Parse a local object from the serialized cache.
    function getNavigationFromCache(dto) {
        var item = new SPOCustom.Models.NavigationNode();
    
        if (dto != undefined) {
    
            item.Title(dto.Title);
            item.Url(dto.Url);
            item.Parent(dto.Parent);
        }
    
        return item;
    }
    
    /* create a new OData request for JSON response */
    function getRequest(endpoint) {
        var request = baseRequest;
        request.type = "GET";
        request.url = endpoint;
        request.headers = { ACCEPT: "application/json;odata=verbose" };
        return request;
    };
    
    /* Navigation Module*/
    function NavigationViewModel() {
        "use strict";
        var self = this;
        self.nodes = ko.observableArray([]);
        self.hierarchy = ko.observableArray([]);;
        self.loadNavigatioNodes = function () {
            //Check local storage for cached navigation datasource.
            var fromStorage = localStorage["nodesCache"];
            if (false) {
                var cachedNodes = JSON.parse(localStorage["nodesCache"]);
    
                if (cachedNodes && timeStamp) {
                    //Check for cache expiration. Currently set to 3 hrs.
                    var now = new Date();
                    var diff = now.getTime() - timeStamp;
                    if (Math.round(diff / (1000 * 60 * 60)) < 3) {
    
                        //return from cache.
                        var cacheResults = [];
                        $.each(cachedNodes, function (i, item) {
                            var nodeitem = getNavigationFromCache(item, true);
                            cacheResults.push(nodeitem);
                        });
    
                        self.buildHierarchy(cacheResults);
                        self.toggleView();
                        addEventsToElements();
                        return;
                    }
                }
            }
            //No cache hit, REST call required.
            self.queryRemoteInterface();
        };
    
        //Executes a REST call and builds the navigation hierarchy.
        self.queryRemoteInterface = function () {
            var oDataRequest = getRequest(query);
            $.ajax(oDataRequest).done(function (data) {
                var results = [];
                $.each(data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results, function (i, item) {
    
                    if (i == 0) {
                        //Add root element.
                        var rootItem = new SPOCustom.Models.NavigationNode();
                        rootItem.Title("Root");
                        rootItem.Url(root);
                        rootItem.Parent(null);
                        results.push(rootItem);
                    }
                    var navItem = getNavigationFromDto(item);
                    results.push(navItem);
                });
                //Add to local cache
                localStorage["nodesCache"] = ko.toJSON(results);
    
                localStorage["nodesCachedAt"] = new Date().getTime();
                self.nodes(results);
                if (self.nodes().length > 0) {
                    var unsortedArray = self.nodes();
                    var sortedArray = unsortedArray.sort(self.sortObjectsInArray);
    
                    self.buildHierarchy(sortedArray);
                    self.toggleView();
                    addEventsToElements();
                }
            }).fail(function () {
                //Handle error here!!
                $("#loading").hide();
                $("#error").show();
            });
        };
        self.toggleView = function () {
            var navContainer = document.getElementById("navContainer");
            ko.applyBindings(self, navContainer);
            $("#loading").hide();
            $("#navContainer").show();
    
        };
        //Uses linq.js to build the navigation tree.
        self.buildHierarchy = function (enumerable) {
            self.hierarchy(Enumerable.From(enumerable).ByHierarchy(function (d) {
                return d.Parent() == null;
            }, function (parent, child) {
                if (parent.Url() == null || child.Parent() == null)
                    return false;
                return parent.Url().toUpperCase() == child.Parent().toUpperCase();
            }).ToArray());
    
            self.sortChildren(self.hierarchy()[0]);
        };
    
    
        self.sortChildren = function (parent) {
    
            // sjip processing if no children
            if (!parent || !parent.children || parent.children.length === 0) {
                return;
            }
    
            parent.children = parent.children.sort(self.sortObjectsInArray2);
    
            for (var i = 0; i < parent.children.length; i++) {
                var elem = parent.children[i];
    
                if (elem.children && elem.children.length > 0) {
                    self.sortChildren(elem);
                }
            }
        };
    
        // ByHierarchy method breaks the sorting in chrome and firefix 
        // we need to resort  as ascending
        self.sortObjectsInArray2 = function (a, b) {
            if (a.item.Title() > b.item.Title())
                return 1;
            if (a.item.Title() < b.item.Title())
                return -1;
            return 0;
        };
    
    
        self.sortObjectsInArray = function (a, b) {
            if (a.Title() > b.Title())
                return -1;
            if (a.Title() < b.Title())
                return 1;
            return 0;
        }
    }
    
    //Loads the navigation on load and binds the event handlers for mouse interaction.
    function InitCustomNav() {
        var viewModel = new NavigationViewModel();
        viewModel.loadNavigatioNodes();
    }
    
    function addEventsToElements() {
        //events.
        $("li.dynamic-children").mouseover(function () {
            var position = $(this).position();
            $(this).find("ul").css({ width: 125, left: position.left + 10, top: 50 });
    
        })
            .mouseout(function () {
                $(this).find("ul").css({ width: 0, left: -99999, top: 0 });
            });
    }
    
    _spBodyOnLoadFunctionNames.push("InitCustomNav");
    

    Pour synthétiser le code ci-dessus dans la fonction $(document).ready jQuery, il existe un objet viewModel créé et puis la loadNavigationNodes() fonctionne sur cet objet est appelé. Cette fonction charge soit la hiérarchie de navigation générée précédemment enregistrée dans le stockage local HTML5 du navigateur client ou elle appelle la fonction queryRemoteInterface().

    QueryRemoteInterface() crée une requête en utilisant la fonction getRequest() avec le paramètre de requête défini précédemment dans le script, puis renvoie des données à partir du serveur. Ces données sont essentiellement un tableau de tous les sites dans la collection de sites représentés sous forme d’objets de transfert de données avec différentes propriétés. Ces données sont analysées puis les objets défini précédemment SPO.Models.NavigationNode qui permet de créer des propriétés visible pour une utilisation Knockout.js en liant les valeurs dans le code HTML que nous avons définie précédemment données. Les objets sont placés ensuite dans un tableau des résultats. Ce tableau est analysé dans JSON à l’aide de masquage et stocké dans le stockage de navigateur local pour améliorer les performances de chargement des pages futures.

  8. Ensuite, les résultats sont affectés à la matrice self.nodes et une hiérarchie repose sur les objets à l’aide de linq.js affectation la sortie à un tableau self.heirarchy. Ce tableau est l’objet qui est lié à l’élément HTML. Cela dans la fonction toggleView() en passant l’objet automatique à la fonction ko.applyBinding() . Ainsi, puis la matrice hiérarchie lier le code HTML suivant :

    <div data-bind=”foreach: hierarchy” class=”noindex ms-core-listMenu-horizontalBox”>

    Pour finir, les gestionnaires d’événements pour mouseenter et mouseexit sont ajoutés à la navigation de niveau supérieur pour gérer les menus déroulants sous-site qui s’effectue dans la fonction addEventsToElements() .

    Les résultats de la navigation peuvent être vues dans la capture d’écran ci-dessous :

    Capture d’écran des résultats de navigation

    Dans notre exemple de navigation complexes une nouvelle page charge sans le montre la mise en cache local le temps passé sur le serveur a été supprimée vers le bas de la navigation structurelle d’évaluation pour obtenir un résultat similaire à l’approche navigation gérée.

    Capture d’écran de SPRequestDuration 301

    L’un des principaux avantages de cette approche sont qu’à l’aide de stockage local HTML5, la navigation est stockée localement pour l’utilisateur au prochain que chargement de la page.

Améliorations des performances principales la bonne d’utiliser la recherche API pour la navigation structurelle ; Cependant, il prend certaines fonctions technique pour exécuter et personnaliser cette fonctionnalité. Dans l’implémentation d’exemple, les sites sont triées de la même façon que la navigation structurelle de prédéfinies ; par ordre alphabétique. Si vous souhaitez écarter cet ordre, il est plus complexe développer et maintenir. En outre, cette approche nécessite que vous écarter les pages maîtres pris en charge. Si la page maître personnalisée n’est pas conservée, votre site sera manquez améliorations par Microsoft aux pages maîtres et mises à jour.

Le code ci-dessus comporte les dépendances suivantes :

La version actuelle de LinqJS ne contient-elle pas la méthode ByHierarchy utilisée dans le code ci-dessus et sauts de page le code de navigation. Pour résoudre ce problème, ajoutez la méthode suivante dans le fichier Linq.js avant la ligne « écraser : fonction () ».

ByHierarchy: function(firstLevel, connectBy, orderBy, ascending, parent) {
     ascending = ascending == undefined ? true : ascending;
     var orderMethod = ascending == true ? 'OrderBy' : 'OrderByDescending';
     var source = this;
     firstLevel = Utils.CreateLambda(firstLevel);
     connectBy = Utils.CreateLambda(connectBy);
     orderBy = Utils.CreateLambda(orderBy);
    
     //Initiate or increase level
     var level = parent === undefined ? 1 : parent.level + 1;

    return new Enumerable(function() {
         var enumerator;
         var index = 0;

        var createLevel = function() {
                 var obj = {
                     item: enumerator.Current(),
                     level : level
                 };
                 obj.children = Enumerable.From(source).ByHierarchy(firstLevel, connectBy, orderBy, ascending, obj);
                 if (orderBy !== undefined) {
                     obj.children = obj.children[orderMethod](function(d) {
                         return orderBy(d.item); //unwrap the actual item for sort to work
                     });
                 }
                 obj.children = obj.children.ToArray();
                 Enumerable.From(obj.children).ForEach(function(child) {
                     child.getParent = function() {
                         return obj;
                     };
                 });
                 return obj;
             };

        return new IEnumerator(

        function() {
             enumerator = source.GetEnumerator();
         }, function() {
             while (enumerator.MoveNext()) {
                 var returnArr;
                 if (!parent) {
                     if (firstLevel(enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }

                } else {
                     if (connectBy(parent.item, enumerator.Current(), index++)) {
                         return this.Yield(createLevel());
                     }
                 }
             }
             return false;
         }, function() {
             Utils.Dispose(enumerator);
         })
     });
 },

Remarque : Avertissement traduction automatique : cet article a été traduit par un ordinateur, sans intervention humaine. Microsoft propose cette traduction automatique pour offrir aux personnes ne maîtrisant pas l’anglais l’accès au contenu relatif aux produits, services et technologies Microsoft. Comme cet article a été traduit automatiquement, il risque de contenir des erreurs de grammaire, de syntaxe ou de terminologie.

Développez vos compétences
Découvrez des formations
Accédez aux nouvelles fonctionnalités en avant-première
Rejoignez le programme Office Insider

Ces informations vous ont-elles été utiles ?

Nous vous remercions pour vos commentaires.

Merci pour vos commentaires. Il serait vraisemblablement utile pour vous de contacter l’un de nos agents du support Office.

×