Просмотр исходного кода

Closes #21369: Add lazy loading and decoding options for ImageAttr (#21444)

Introduces `load_lazy` and `decoding` parameters to `ImageAttr` for
enhanced image handling. Lazy loading improves page performance, while
configurable decoding options provide greater flexibility. Updates the
template to conditionally include these attributes in rendered HTML.

Fixes #21369
Martin Hauser 19 часов назад
Родитель
Сommit
2c200a4fd3
2 измененных файлов с 31 добавлено и 1 удалено
  1. 30 0
      netbox/netbox/ui/attrs.py
  2. 1 1
      netbox/templates/ui/attrs/image.html

+ 30 - 0
netbox/netbox/ui/attrs.py

@@ -24,11 +24,13 @@ __all__ = (
 
 PLACEHOLDER_HTML = '<span class="text-muted">&mdash;</span>'
 
+IMAGE_DECODING_CHOICES = ('auto', 'async', 'sync')
 
 #
 # Attributes
 #
 
+
 class ObjectAttribute:
     """
     Base class for representing an attribute of an object.
@@ -193,9 +195,37 @@ class ColorAttr(ObjectAttribute):
 class ImageAttr(ObjectAttribute):
     """
     An attribute representing an image field on the model. Displays the uploaded image.
+
+    Parameters:
+        load_lazy (bool): If True, the image will be loaded lazily (default: True)
+        decoding (str): Image decoding option ('async', 'sync', 'auto', None)
     """
     template_name = 'ui/attrs/image.html'
 
+    def __init__(self, *args, load_lazy=True, decoding=None, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.load_lazy = load_lazy
+
+        if decoding is not None and decoding not in IMAGE_DECODING_CHOICES:
+            raise ValueError(
+                _('Invalid decoding option: {decoding}! Must be one of {image_decoding_choices}').format(
+                    decoding=decoding, image_decoding_choices=', '.join(IMAGE_DECODING_CHOICES)
+                )
+            )
+
+        # Compute default decoding:
+        # - lazy images: async decoding (performance-friendly hint)
+        # - non-lazy images: omit decoding (browser default/auto)
+        if decoding is None and load_lazy:
+            decoding = 'async'
+        self.decoding = decoding
+
+    def get_context(self, obj, context):
+        return {
+            'decoding': self.decoding,
+            'load_lazy': self.load_lazy,
+        }
+
 
 class RelatedObjectAttr(ObjectAttribute):
     """

+ 1 - 1
netbox/templates/ui/attrs/image.html

@@ -1,3 +1,3 @@
 <a href="{{ value.url }}">
-  <img src="{{ value.url }}" alt="{{ value.name }}" class="img-fluid" />
+  <img src="{{ value.url }}" alt="{{ value.name }}" class="img-fluid" {% if load_lazy %}loading="lazy" {% endif %} {% if decoding %}decoding="{{ decoding }}" {% endif %}/>
 </a>