From 601296aa4a98c91a1558e40ca4dea591dcea1a4e Mon Sep 17 00:00:00 2001 From: Martin Hauser Date: Mon, 16 Feb 2026 15:23:12 +0100 Subject: [PATCH] feat(ui): Add lazy loading and decoding options for ImageAttr 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 --- netbox/netbox/ui/attrs.py | 30 ++++++++++++++++++++++++++++ netbox/templates/ui/attrs/image.html | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/netbox/netbox/ui/attrs.py b/netbox/netbox/ui/attrs.py index 999e02f94..37cc1ba12 100644 --- a/netbox/netbox/ui/attrs.py +++ b/netbox/netbox/ui/attrs.py @@ -24,11 +24,13 @@ __all__ = ( PLACEHOLDER_HTML = '' +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): """ diff --git a/netbox/templates/ui/attrs/image.html b/netbox/templates/ui/attrs/image.html index 3c10113c4..895b1788f 100644 --- a/netbox/templates/ui/attrs/image.html +++ b/netbox/templates/ui/attrs/image.html @@ -1,3 +1,3 @@ - {{ value.name }} + {{ value.name }}