erdfisch Blog

Drupal 8 Roundup (Kalenderwoche 38, 2014)

Body: 

Diese Blog-Serie soll einen Überblick über die aktuellen Geschehnisse rund um die Entwicklung von Drupal 8 geben. Heute möchte ich etwas über Kontextuelles Caching berichten.

Bisherige Themen:

Hintergrund

Wie wir alle wissen, ist Cache-Invalidierung ein nicht triviales Problem. Leider sind die Zeiten vorbei, in denen man eine Drupal-Seite einfach ungecached ausliefern konnte und sich um Performance-Fragen keine Sorgen machen musste. Seiten für nicht eingeloggte Benutzer zu cachen funktioniert seit eh und je sehr gut in Drupal und macht die Seite auch schön flott. Sobald sich Benutzer einloggen, wird es allerdings schwierig. Die komplette Seite zu cachen ist in der Regel nicht möglich, da fast immer irgendein Teil der Seite benutzerspezifische Informationen enthält. In Drupal 8 wurde nun schon viel dafür getan, dass man einzelne Komponenten einer Seite separat cachen kann, sodass die Teile die doch für alle Benutzer gleich sind nicht immer neu aufgebaut werden müssen.

Das löst aber nur die eine Hälfte des Problems. Aufgrund der hochdynamischen Natur von Drupal ist es schwierig zu wissen, wie die dynamischen Komponenten einer Seite sich unter welchen Umständen und für welchen Benutzer ändern. Allein das HTML für ein einzelnes Menü zu cachen ist enorm schwierig, weil jeder Menü-Link potentiell an bestimmte Berechtigungen gebunden sein kann, jedem Benutzer aber wiederum eine andere Kombination von Rollen zugeordnet sein kann. Außerdem kann es Links geben, die sich sogar pro Benutzer unterscheiden, wenn sie etwa auf einen Pfad zeigen, der die jeweilige Benutzer-ID enthält. Ein weiteres Problem sind Datums- und Zeitangaben. Denn selbst wenn sich eine bestimmte Zeitangabe an sich nicht ändert (wie etwas der Erstellungszeitpunkt einer Node) variiert die Anzeige je nach Zeitzone des Benutzers. Im Zentrum der Problematik steht hier der Begriff der Cache-Granularität, der verbunden ist mit der Frage:

Muss ich ein Stück HTML pro Rolle speichern, pro Benutzer, pro Zeitzone, pro Mondzyklus, ...?

.

Caching vs. Zugangsberechtigungen

Dass für Menüs und Menü-Links die Cache-Granularität mit den Zugangsberechtigungen des eingeloggten Benutzers zusammenhängen, ist keine Ausnahme. Viel mehr stellt man fest, dass diese beiden Bereiche konzeptionell eng miteinander verwoben sind. Wenn - wie oben - der Zugang zu einem Menü-Link an eine Berechtigung gekoppelt ist, genau dann kann der entsprechende Output beispielsweise pro Rollenkombination gecached werden. Das wiederum heißt, sobald ich irgendwo den Zugriff zu einem Menü-Link anhand einer Berechtigung überprüfe, müsste ich dem System nicht nur das Resultat der Überprüfung (TRUE oder FALSE) mitteilen können, sondern ich müsste zusätzlich sagen können:

Merk dir das Ergebnis und frag mich erst wieder, wenn es um einen Benutzer mit einer anderen Rollen-Kombination geht!

Oder mit anderen Worten: Drupals Zugangsberechtigungssystem müsste um Caching-Metadaten erweitert werden.

Eben dies ist nun in Drupal 8 passiert. Statt einer reinen Ja/Nein Aussage geben Drupal's Access-Checker ein sogenanntes AccessResult Objekt zurück. Dieses Objekt kann ich zum einen fragen, ob der Zugriff erlaubt ($access_result->isAllowed()) oder verboten ($access_result->isForbidden()) wurde, aber ich kann eben auch die Information abrufen, unter welchen Umständen sich der Wert ändert - den sogenannten Cache-Kontext.

Ausblick

Diese Veränderung bereitet den Weg in Richtung von hochdynamischen und trotzdem hochperformanten Seiten in Drupal 8. Man muss allerdings bemerken, dass dies lediglich der erste Schritt ist. Es ist jetzt beispielsweise klar geworden, dass Drupals Pfad-System ebenfalls um solche Caching-Metadaten erweitert werden muss. Denn ein Menü-Link, der auf node/1 zeigt, kann z.B. auf einer mehrsprachigen Seite je nach Sprache entweder zu de/node/1 oder zu fr/node/1 verarbeitet werden. Dementsprechend muss die Cache-Granularität des Menü-Links zusätzlich pro Sprache sein. Dennoch scheint das Caching von gesamten Menü-Bäumen nach Langem nun endlich in Reichweite zu sein. Allein das wäre ein großer Leistungs-Boost für typische Drupal-Webseiten - von weiteren Komponenten, die sich nun cachen lassen, ganz abgesehen.

Schließlich - und nur am Rande - sei bemerkt, dass nach Feedback von einigen Entwicklern die genaue API des AccessResult Objekts ggf. noch etwas angepasst wird, um das Arbeiten mit solchen Objekten etwas zu vereinfachen und selbstdokumentierter zu machen.

Kommentare

Comments