Alternativer for navigering for SharePoint Online

Viktig: Denne artikkelen er maskinoversatt, se ansvarsfraskrivelsen. Du finner den engelske versjonen av artikkelen her som referanse.

Denne artikkelen beskriver hvordan du forbedrer sidelastingstider for SharePoint Online ved å bruke strukturell navigasjon og søkebaserte navigasjon.

Global navigasjon og spørringer som kreves for å bygge strukturell navigasjon kan gjøre sidene laste inn flere langsomt i SharePoint Online. Dette er fordi hver av disse spørringene sender en annen forespørsel til SQLServer. For hvert område og sekundært område du har forespørsler flere til SQLServer. Dette problemet gjelder også for hoveddokumentene. Dette betyr at berøres også global navigasjon.

Noen SharePoint-områder krever store og kompliserte strukturer. Ved hjelp av den ut av esken strukturell navigasjonen, som bruker innhold som spørring, kan føre til treg sidelastingstider på grunn av flere lag for området. Hver av lagene på sekundære områder, opprettes det også en annen spørring.

Det finnes to alternativer for ut av esken hovednavigasjonen i SharePoint i tillegg til en tredjepart, egendefinert, søkebaserte måte. Hvert alternativ har fordeler og ulemper som beskrevet i tabellen nedenfor.

Strukturell navigasjon

Administrert navigasjon

Søkebaserte navigasjon

Teknikere:

  • Enkelt å konfigurere

  • Sikkerhet trimmet

  • Oppdateres automatisk etter hvert som legges områder

Teknikere:

  • Enkel å vedlikeholde

Teknikere:

  • Sikkerhet trimmet

  • Oppdateres automatisk etter hvert som legges områder

  • Rask innlasting av tid og bufret lokalt navigasjonsstruktur

Ulemper:

  • Kan utføre dårlig med komplekse områdestruktur

Ulemper:

  • Oppdateres ikke automatisk for å gjenspeile områdestruktur

Ulemper:

  • Ikke mulighet til å enkelt rekkefølge områder

  • Krever tilpassing av hoveddokumentet (tekniske ferdigheter kreves)

Hvis du har et område med mye sekundære områder, og du bruker strukturell navigasjon, kan være senke laster siden betydelig. Alternativet passer best for området vil avhenger av krav til området og det tekniske funksjonaliteten. Hvis du vet hvordan du bruker et egendefinert hoveddokument og har noen funksjonaliteten i organisasjonen til å vedlikeholde endringene som kan oppstå i standard hoveddokument for SharePoint Online, vil alternativet søkebaserte produsere beste brukeropplevelsen. Hvis du vil ha en enkel grunnen av midt mellom ut av esken strukturell navigasjon, og søk, er administrert navigasjon et godt alternativ. Alternativet administrert navigasjon kan vedlikeholdes gjennom konfigurasjon av involverer ikke filer for tilpassing av koden, og det er betydelig raskere enn den ut av esken strukturell navigasjonen.

En annen metode er å strukturere det eksisterende nettstedet og redusere antall navigasjonselementer og sekundære områder kreves. Dette er fordi strukturell navigasjon utfører utmerket så lenge områdestrukturen og navigasjon ikke er for komplisert.

Denne artikkelen sammenligner de ulike metodene i en områdesamling for eksempel. Eksempel områdesamlingen har 11 sekundære områder, og hver sekundært webområde har minst fire flere sekundære områder.

Skjermbilde som viser områder og sekundære områder

Bruke strukturell navigasjon i SharePoint Online

Dette er ut av esken navigasjonen brukes som standard og er den mest enkle og riktige løsningen i de fleste tilfeller. Hvis det ikke er en kompleks struktur av flere sekundære områder eller mange nivåer med sekundære områder, utfører strukturell navigasjon bra. Hovedfordelene med denne metoden er at det er sikkerhet trimmet, oppdateres automatisk når nye områder legges og krever ikke enhver tilpasning av hoveddokumentet for. En ikke-tekniske brukere kan også enkelt legge til elementer, skjule elementer og behandle navigasjonen fra innstillinger-siden.

Når du slår på strukturell navigasjon i SharePoint Online

Å illustrere hvordan ytelsen i en standard SharePoint Online løsning med strukturell navigasjon og viser sekundære områder alternativet aktivert. Nedenfor er et skjermbilde innstillingene på siden Innstillinger for område > Navigasjon.

Skjermbilde som viser sekundære områder

Analysere strukturell navigasjon ytelse i SharePoint Online

For å analysere ytelsen til en SharePoint-side, bruker du kategorien nettverk av utviklerverktøy F12 i Internet Explorer.

Skjermbilde som viser Nettverk-fanen i F12-utviklerverktøyet

Klikk på ASPX-siden som lastes og klikk deretter kategorien Detaljer i kategorien nettverk.

Skjermbilde som viser Detaljer-fanen

Klikk Svarhoder.

Skjermbilde av Detaljer-fanen

SharePoint returnerer noen nyttige diagnostikk i sin svar overskriftene. En av de mest nyttige er SPRequestDuration    som er verdien i millisekunder i hvor lenge en forespørsel om tok å behandle på serveren.

Er merket for strukturell navigasjon i det følgende skjermbildet viser sekundære områder. Dette betyr at det er bare samling områdekoblingen i den globale navigasjonen:

Skjermbilde som viser innlastingstidene som varighet for forespørsel

Nøkkelen SPRequestDuration    har en verdi på 245 millisekunder. Dette representerer hvor lang tid det tok til å returnere forespørselen. Siden det er bare ett element i navigasjonen på webområdet, er dette et godt utgangspunkt hvordan SharePoint Online utfører uten tung navigasjon. Neste skjermbilde viser hvordan legge til i de sekundære områdene påvirker denne tasten.

Skjermbilde som viser varighet for forespørsel som 2502 ms

Legge til sekundære områder har økt betraktelig tiden det tar å gå tilbake til sideforespørsel.

Fordelene ved å bruke vanlige strukturerte navigasjonen er at du kan enkelt ordne rekkefølgen, skjule områder, legge til sider, resultatene trimmet sikkerhet, og du ikke er deviating fra støttede hoveddokumentene brukes i SharePoint Online. Hvis du strukturerer området nøye og redusere mengden sekundære områder i områdesamlingen deretter strukturell navigasjon, utfører bra.

Bruke administrert navigasjon og forvaltede metadata i SharePoint Online

Administrert navigasjon er et annet alternativ ut av esken du kan bruke til å opprette den samme typen funksjonalitet som strukturell navigasjon.

Fordelen med å bruke forvaltede metadata er at det er mye raskere å hente dataene enn å bruke innholdet av spørring til å bygge områdenavigasjonen. Selv om det er mye raskere det finnes ingen måte å trimme sikkerhet resultatene så hvis en bruker som ikke har tilgang til et bestemt område, koblingen vises fortsatt, men vil føre til en feilmelding.

Hvordan du implementerer administrert navigasjon og resultatene   

Det finnes flere artikler på TechNet detaljer om administrert navigasjon, for eksempel, kan du se Oversikt over administrert navigasjon i SharePoint Server 2013.

Hvis du skal implementere administrert navigasjon, må du ha term lagre administratortillatelser. Administrert navigasjon kan brukes til å erstatte strukturell navigasjon, ved å definere vilkår med adresser som samsvarer med strukturen i en områdesamling. Eksempel:

Skjermbilde av eksempelet Sekundært nettsted1

Følgende eksempel viser ytelsen til komplekse navigasjonen ved hjelp av administrert navigasjon.

Skjermbilde av eksempelet SPRequestDuration

Ved hjelp av administrert navigasjon konsekvent forbedrer ytelsen i forhold til innholdet av spørringen strukturell navigasjon tilnærming.

Ved hjelp av søkebaserte klientside

Du kan bruke indeksene som er bygget i bakgrunnen ved hjelp av kontinuerlig kravlesøk ved hjelp av søk. Dette betyr at det er ingen tung innhold spørringer. Søkeresultatene er hentet fra søkeindeksen, og resultatene er trimmet sikkerhet. Dette er raskere enn å bruke vanlige innhold spørringer. Ved hjelp av søk for strukturell navigasjon, spesielt hvis du har en kompleks områdestrukturen, vil raskere laster tid betydelig side. Den største fordelen av dette over administrert navigasjon er at du dra nytte av sikkerhetstrimming.

Denne metoden må du opprette et egendefinert hoveddokument og erstatte koden ut av esken navigasjon med egendefinerte HTML. Følg denne fremgangsmåten hvis du vil erstatte navigasjon koden i filen seattle.html.

I dette eksemplet vil du åpne filen seattle.html og erstatte hele elementet id = "DeltaTopNavigation" med den egendefinerte HTML-koden.

Eksempel: Erstatte ut av esken navigasjon-kode i et hoveddokument

  1. Gå til Siden for områdeinnstillinger.

  2. Åpne galleriet for hoveddokumenter ved å klikke Hoveddokumenter.

  3. Herfra kan du navigere gjennom biblioteket og laste ned filen seattle.master.

  4. Redigere koden ved hjelp av et tekstredigeringsprogram og slette kodeblokk i følgende skjermbilde.

    Skjermbilde av koden DeltaTopNavigation for å slette
  5. Fjerne koden mellom den < SharePoint:AjaxDelta id = "DeltaTopNavigation" > og < \SharePoint:AjaxDelta > koder og erstatte den med kodesnutten for følgende:

    <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. Erstatte URL-adressen i innlasting bilde ankerkode i begynnelsen, med en kobling til et bilde i områdesamlingen. Når du har gjort endringene, gi nytt navn til filen, og deretter laste den opp til galleriet for hoveddokumenter. Dette genererer en ny .master-fil.

  7. Denne HTML er grunnleggende markeringen som skal være fylt ut av søkeresultatene returneres fra JavaScript-kode. Du må redigere følgende kode for å endre verdien for var root = “site collection URL som vist i kodesnutten for følgende:

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

    Hele JavaScript-filen er som følger:

    //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");
    

    Hvis du vil summere koden ovenfor i funksjonen jQuery $(document).ready det er en viewModel -objekt som er opprettet, og deretter loadNavigationNodes() fungere på objektet kalles. Denne funksjonen laster enten tidligere bygd navigasjonshierarkiet lagret i HTML5 lokal lagring av klienten nettleseren eller kaller funksjonen queryRemoteInterface().

    QueryRemoteInterface() bygger en forespørsel om å bruke funksjonen getRequest() med spørringsparameter definert tidligere i skriptet, og returnerer data fra serveren. Disse dataene er i hovedsak en matrise med alle områdene i områdesamlingen representert som overføring dataobjekter med ulike egenskaper. Disse dataene, deretter analyseres til de tidligere definert SPO.Models.NavigationNode objektene som bruker Knockout.js til å opprette synlig egenskaper for bruk av data binde verdiene i HTML som ble definert tidligere. Objektene plasseres deretter i en matrise med resultater. Denne matrisen er analysert i JSON ved hjelp av utstansing og lagret i den lokale nettleser lagringsplassen for bedre ytelse på fremtidige sideinnlastingen.

  8. Resultatet er tilordnet til matrisen self.nodes , og et hierarki som er laget av objekter ved hjelp av linq.js tilordne utdataene til en matrise self.heirarchy. Denne matrisen er objektet som er bundet til HTML-koden. Dette gjøres i funksjonen toggleView() ved å sende selv objektet til funksjonen ko.applyBinding() . Dette forårsaker deretter hierarki matrisen skal være bundet til følgende HTML:

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

    Til slutt legges hendelsesbehandling for mouseenter og mouseexit til på øverste nivå navigasjonen til å håndtere rullegardinmenyer sekundært område som er gjort i funksjonen addEventsToElements() .

    Du kan se resultatene av navigasjonen i skjermbilde nedenfor:

    Skjermbilde av navigasjonsresultater

    I eksemplet vårt komplekse navigasjon en ny side lasting uten den lokale hurtigbufring viser tiden som er brukt på serveren har blitt klippe ut fra benchmark strukturell navigasjonen å få et lignende resultat som tilnærmingen administrert navigasjon.

    Skjermbilde av SPRequestDuration 301

    Én viktig fordel med denne metoden er at ved hjelp av HTML5 lokal lagring, navigasjonen er lagret lokalt for brukeren neste gang de laste inn siden.

Vi får hovedversjoner ytelsesforbedringer fra ved hjelp av søk API for strukturell navigasjon; men tar det litt teknisk mulighet til å kjøre og tilpasse denne funksjonaliteten. I eksempel-implementeringen er områdene organisert på samme måte som ut av esken strukturell navigasjon; alfabetisk rekkefølge. Hvis du ville avvike fra denne rekkefølgen, vil det være mer komplisert å utvikle og vedlikeholde. Denne fremgangsmåten krever du kan avvike fra støttede hoveddokumentene. Hvis det egendefinerte hoveddokumentet ikke vedlikeholdes, vil området gå glipp av oppdateringer og forbedringer som Microsoft lager til hoveddokumentene.

Ovennevnte kode har følgende avhengigheter:

Den gjeldende versjonen av LinqJS inneholder ikke ByHierarchy metoden som brukes i ovennevnte kode og brytes navigasjon-koden. Hvis du vil løse dette ved å legge til følgende metode i filen Linq.js før linje "Flatten: fungere ()".

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);
         })
     });
 },

Merknad: Ansvarsfraskrivelse for maskinoversettelse: Denne artikkelen er oversatt av et datasystem i stedet for en oversetter. Microsoft tilbyr disse maskinoversettelsene slik at brukere som ikke snakker engelsk, får tilgang til innhold om Microsoft-produkter, -tjenester og –teknologier. Ettersom artikkelen er maskinoversatt, kan den inneholde feil i vokabular, syntaks eller grammatikk.

Utvid ferdighetene dine
Utforsk opplæring
Vær først ute med de nye funksjonene
Bli med i Office Insiders

Var denne informasjonen nyttig?

Takk for tilbakemeldingen!

Takk for tilbakemeldingen! Det høres ut som det kan være lurt å sette deg i kontakt med én av våre Office-kundestøtteagenter.

×