From 35a197d6093c45345f27baaa6421467fd21d1ab7 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Fri, 5 Jul 2024 09:06:34 +0100 Subject: [PATCH] Move sprite hashing out of module import time This speeds up application startup. The hash is now a query param, injected in the template. As this param is only needed for cache invalidation, it's optional. A helper method is provided to generate the URL, along with a template tag. This also migrates to an `lru_cache` over a global variable for simplicity. Fixes #11680 --- CHANGELOG.txt | 1 + docs/releases/6.2.md | 1 + wagtail/admin/icons.py | 43 +++++++++++++++++++ .../templates/wagtailadmin/skeleton.html | 2 +- .../admin/templatetags/wagtailadmin_tags.py | 4 ++ wagtail/admin/tests/test_icon_sprite.py | 33 ++++++-------- wagtail/admin/urls/__init__.py | 16 +------ wagtail/admin/views/home.py | 33 +------------- 8 files changed, 65 insertions(+), 68 deletions(-) create mode 100644 wagtail/admin/icons.py diff --git a/CHANGELOG.txt b/CHANGELOG.txt index e72d5b410695..9ece8154887c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -57,6 +57,7 @@ Changelog * Maintenance: Remove unused `docs/autobuild.sh` script (Sævar Öfjörð Magnússon) * Maintenance: Replace `urlparse` with `urlsplit` to improve performance (Jake Howard) * Maintenance: Optimise embed finder lookups (Jake Howard) + * Maintenance: Improve performance of initial admin loading by moving sprite hashing out of module import time (Jake Howard) 6.1.2 (30.05.2024) diff --git a/docs/releases/6.2.md b/docs/releases/6.2.md index 9dfcfd37deb6..7e55794ec8d1 100644 --- a/docs/releases/6.2.md +++ b/docs/releases/6.2.md @@ -81,6 +81,7 @@ This feature was implemented by Albina Starykova, with support from the Wagtail * Remove unused `docs/autobuild.sh` script (Sævar Öfjörð Magnússon) * Replace `urlparse` with `urlsplit` to improve performance (Jake Howard) * Optimise embed finder lookups (Jake Howard) + * Improve performance of initial admin loading by moving sprite hashing out of module import time (Jake Howard) ## Upgrade considerations - changes affecting all projects diff --git a/wagtail/admin/icons.py b/wagtail/admin/icons.py new file mode 100644 index 000000000000..1426eaa8753e --- /dev/null +++ b/wagtail/admin/icons.py @@ -0,0 +1,43 @@ +import hashlib +import itertools +import re +from functools import lru_cache + +from django.conf import settings +from django.template.loader import render_to_string +from django.urls import reverse + +from wagtail import hooks + +icon_comment_pattern = re.compile(r"") + + +@lru_cache(maxsize=None) +def get_icons(): + icon_hooks = hooks.get_hooks("register_icons") + all_icons = sorted(itertools.chain.from_iterable(hook([]) for hook in icon_hooks)) + combined_icon_markup = "" + for icon in all_icons: + symbol = ( + render_to_string(icon) + .replace('xmlns="http://www.w3.org/2000/svg"', "") + .replace("svg", "symbol") + ) + symbol = icon_comment_pattern.sub("", symbol) + combined_icon_markup += symbol + + return render_to_string( + "wagtailadmin/shared/icons.html", {"icons": combined_icon_markup} + ) + + +@lru_cache(maxsize=None) +def get_icon_sprite_hash(): + # SECRET_KEY is used to prevent exposing the Wagtail version + return hashlib.sha1( + (get_icons() + settings.SECRET_KEY).encode("utf-8") + ).hexdigest()[:8] + + +def get_icon_sprite_url(): + return reverse("wagtailadmin_sprite") + f"?h={get_icon_sprite_hash()}" diff --git a/wagtail/admin/templates/wagtailadmin/skeleton.html b/wagtail/admin/templates/wagtailadmin/skeleton.html index 2072c2d36de1..16410daefdda 100644 --- a/wagtail/admin/templates/wagtailadmin/skeleton.html +++ b/wagtail/admin/templates/wagtailadmin/skeleton.html @@ -19,7 +19,7 @@
- +