Obwohl im Blog als auch im Wiki dieselbe Suche (FuseJS) verwendet wird, dauert es im Blog deutlich länger bis die Ergebnisse angezeigt werden, als im Wiki, wo die Ergebnisse fast sofort zu sehen sind.

Meine erst Vermutung war, dass es unter anderem daran liegt, dass es im Blog um die 2600 Beiträge gibt, während es im Wiki “nur” 578 Seiten sind. Daraus ergibt sich für den Blog eine Dateigröße für die index.json-Datei von über 3,8 MiB, während es im Wiki 0,87 MiB sind.

Die genannte json-Datei muss der Client-Browser herunterladen, um darin dann per JavaScript lokal die Suche anzuwenden. Und bei einer Datei um 3,8 MiB dauert das dann sehr lange.

Erst später stellte ich fest, dass es weit mehr Optimierungspotential durch die Konfiguration der Suche via FuseJS gibt.

Es gibt also zwei Ansätze für die Optimierung der Suchfunktion im Blog.

Letzteres kann man auch umsetzen, wenn man bestimmte Inhalte generell aus der Suche ausschließen möchte.

FuseJS optimieren (das größte Potential)

Es gibt viele Einstellungen für FuseJS. Die Wirkung der meisten Einstellungen verstehe ich nicht wirklich. Ich habe also erst einmal im Blog das selbe eingestellt wie auch in der Suche im Wiki:

shouldSort: true,
includeMatches: true,
threshold: 0.0,
tokenize:true,
location: 0,
distance: 100,
maxPatternLength: 32,
minMatchCharLength: 3,

(Die Syntax für die Einstellungen im Wiki ist eine andere als im Blog. Denn dort sind die Einstellunen nicht im Front Matter hinterlegt, sondern direkt im JavaScript, da ich die Originalsuchfunktion im Wiki selbst durch FuseJS ersetzt hatte)

Im Blog wird daraus in der Datein config.toml im Bereich params:

search.fuse.threshold = 0.0
search.fuse.location = 0
search.fuse.distance = 100
search.fuse.minMatchCharLength = 3

Hier die Hilfeseite zu FuseJS, wie es im Blog verwendet wird.

Hier die vollständige Liste der Einstellungen für FuseJS gibt es hier.

Ergebnis der vom Wiki übernommenen Einstellungen

Vor den Änderungen hatte eine Suche nach z. B. “ettlingen und zurück” im Chromium-Browser 20 Sekunden gedauert und es wurden 1741 Ergebnisse gefunden, von denen nur das erste Ergebnis alle Begriffe beinhaltete.

Die vielen weiteren Ergebnise sind vermutlich dem Fuzzy-Search geschuldet. Aber damit kann ich persönlich eh nichts anfangen, das konnte also eh weg.

Suchergebnisse im Blog nach den Begriffen ’ettlingen und zurück’. Das erste Ergebnis passt, der Rest beinhaltet nicht alle Begriffe.
Suche im Blog mit alten Einstellungen.

Nach der Änderung der Sucheinstellungen dauert die Suche weniger als 1 Sekunde und es wird nur das einzig passende Ergebnis angezeigt:

Suchergebnisse im Blog nach den Begriffen ’ettlingen und zurück’. Das einzigen beiden Ergebnisse passen.
Suche im Blog mit neuen Einstellungen.

Bei anderen Suchbegriffen, wie z. B. “Staatsanwaltschaft”, wurden wegen Fuzzy-Search Ergebnisse gefunden, die den Begriff “Staatsanwaltschaft” gar nicht beinhalteten sondern nur eine Teilmenge der selben Buchstaben in anderen Konstellationen und Wörtern. So war ein Ergebnis z. B. der Blogbeitrag mit dem Titel “Fotografie: Landschaft”, der nur Fotos und gar keinen Text beinhaltete.

Erweiterte Suche aktiviert

Ich habe im Blog für FuseJS auch gleich die erweiterte Suche aktiviert, denn damit kann man tolle Dinge machen, wie man hier nachlesen kann.

So findet man z. B. alle Blogbeiträge, die mit dem String “Fotos” beginnen:

^Fotos

Oder mit dem String “werfen” enden:

werfen$

Mit den alten Einstellungen für die Suche findet diese für “werfen” 2216 Ergebnisse und die meisten beinhalten den Begriff nicht einmal.

Leerzeichen werden als AND verwendet und für OR nutzt man Pipe-Zeichen (|).

Zur Aktivierung der erweiterten Suche fügt man in die Datei config.toml im Bereich [params] ein:

search.fuse.useExtendedSearch = true

Man findet zusätzlich noch ein paar mehr relevante Ergebnisse auch ohne explizite Verwendung der erweiterten Möglichkeiten.

Ergebnis der Optimierung der FuseJS-Einstellungen

Jetzt bin ich auch im Blog mit der Suchfunktion sehr zufrieden. Ich habe bisher alles gefunden, wonach ich testweise gesucht habe, und das ohne viele, viele weitere unnötige Suchergebnisse.

Dazu gibt es jetzt noch erweiterte Suchfunktionen, wie oben beschrieben. Damit muss ich mich nur erinnern, welche Begriffe ich in einem Beitrag verwendet haben könnte.

Zum Beispiel hatte ich mal den Spruch “rechter Reifen Mittelstreifen” verwendet, den ich jetzt so auch finde. Zusätzlich kann ich Beiträge finden, die genau diesen String enthalten ODER mit dem String “bußgeldstelle” beginnen mit "rechter reifen mittelstreifen"|^bußgeldstelle und das Ergebnis beinhaltet 17 Blogbeiträge:

Sucht man nur nach “bußgeldstelle”, dann werden 26 Blogbeiträge gefunden.

Und die Suche ist jetzt schnell, die Ergebnisse sind immer nach circa einer Sekunde da (in Chromium, in Firefox aus dem selben Rechner nach ca. 3 bis 4 Sekunden..

Und als mir dann noch einfiel, dass die Bußgeldstelle mir gegenüber mal die Kombination “scharf rechts” verwendete, kann ich auch danach noch suchen mit dem Suchbegriff bußgeldstelle "scharf rechts" und das Ergebnis ist:

Kurz: Die neue Suche rockt 👍 😄

Bestimmte Dinge aus der Suche ausschließen (wenig Potenzial)

Mein erster Ansatz war es, bestimmte Dinge aus dem Suchindex auszuschließen. Erst danach probierte ich die Optimierung der Einstellungen von FuseJS aus, das letzlich zum erhofften Performanceschub führte.

Ich will das hier aber trotzdem stehen lassen, da es vielleicht je nach Website nützlich sein kann, bestimmte Kategorien oder alte Blogbeiträge vom Suchindex auszuschließen.

Kategorien ausschließen

Man kann Kategorien ausschließen, die sowieso wenig gesucht werden, weil sie z. B. fast nur Fotos enthalten oder auch Kategorien, zu denen es schon lange keine Inhalte mehr gab, wie hier im Blog z. B. “Spiele”.

Alte Beiträge ausschließen

Genau. Siehe unten. 😊

Inhalt (teilweise) aus der Suche entfernen

Derzeit beinhaltet die json-Datei noch den kompletten Inhalt eines Blogbeitrags. Das könnte man ändern und nur noch z. B. Tags, Kategorien, Daten aus dem Front Matter und vielleicht noch die ersten 250 Zeichen des Inhalts jedes Blogbeitrags in die json-Datei einfügen.

Das gefällt mir aber nicht, da man dann auch nur Dinge findet, die in diesen ersten 250 Zeichen enthalten sind.

Umsetzung an einem Beispiel

Hier beispielhaft eine Erläuterung, wie man Blogbeiträge von der Suche (bzw. von der Eintragung in die index.json) ausschließt, die die folgenden Bedingungen erfüllen.

Zur Umsetzung muss man die Datei themes/hugo-theme-bootstrap/layouts/index.json nach layouts/index.json kopieren und wie folgt anpassen:

{{- $.Scratch.Add "index" slice -}}
{{- range .Site.RegularPages -}}
    {{- if ge (sub now.Year .Date.Year) 4 -}}
    {{- else if or (in .Params.categories "Musik") (in .Params.categories "Fotografie") (in .Params.categories "Mumble") (in .Params.categories "Spiele") -}}
    {{- else -}}
        {{- $date := .Date.Format $.Site.Params.dateFormat -}}
        {{- $title := .Title }}
        {{- if $.Site.Params.titleCase -}}
            {{- $title = title $title -}}
        {{- end -}}
        {{- $img := "" -}}
        {{- if .Params.Images -}}
        {{- $img = index .Params.Images 0 | absURL -}}
        {{- else -}}
        {{- $images := .Resources.ByType "image" -}}
        {{- $featured := $images.GetMatch "*feature*" -}}
        {{- if not $featured }}{{ $featured = $images.GetMatch "{*cover*,*thumbnail*}" }}{{ end -}}
        {{- with $featured -}}
            {{- $img = $featured.Permalink -}}
        {{- end -}}
        {{- end -}}
        {{- $item := (dict "title" $title "tags" .Params.tags "categories" .Params.categories "series" .Params.series "content" .Plain "permalink" .Permalink "date" $date "img" $img) -}}
        {{- $.Scratch.Add "index" $item -}}
    {{ end }}
{{- end -}}
{{- $.Scratch.Get "index" | uniq | jsonify -}}

Um einen Hinweis auf der Suchseite einfügen zu können, kopiert man die Datei themes/hugo-theme-bootstrap/layouts/_default/search.html nach layouts/_default/search.html und trägt z. B. ein:

<p><a href="/ueber/suche/">Hinweis: Einige Blogbeiträge sind von der Suche ausgeschlossen. Für Details hier klicken.</a></p>

Ergebnis der Optimierung via Weglassen

Im Ergebnis wurde die index.json statt 3,8 MiB nur noch ca. 1,4 MiB groß. Ohne Optimierung der Sucheinstellungen von FuseJS wurde das aber nur etwas schneller.