From 1367a85b44c6fdd607e0abb49194185760dd17dc Mon Sep 17 00:00:00 2001 From: MAEDA Go Date: Wed, 2 Sep 2026 11:54:54 +0900 Subject: [PATCH] Resolve each icon sprite path only once per request --- app/helpers/icons_helper.rb | 7 ++++++- test/helpers/icons_helper_test.rb | 11 +++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/helpers/icons_helper.rb b/app/helpers/icons_helper.rb index 026a49ced..4d21ebedf 100644 --- a/app/helpers/icons_helper.rb +++ b/app/helpers/icons_helper.rb @@ -150,9 +150,14 @@ module IconsHelper css_classes += " #{css_class}" unless css_class.nil? css_classes += " icon-rtl" if rtl + # Resolve each sprite path only once per request: asset_path is not + # cheap and this helper runs for every icon on a page + @sprite_asset_paths ||= {} + path = @sprite_asset_paths[sprite] ||= asset_path(sprite) + content_tag( :svg, - content_tag(:use, '', { 'href' => "#{asset_path(sprite)}#icon--#{icon_name}" }), + content_tag(:use, '', { 'href' => "#{path}#icon--#{icon_name}" }), class: css_classes, aria: { hidden: true diff --git a/test/helpers/icons_helper_test.rb b/test/helpers/icons_helper_test.rb index 5ccc983bd..7ca29dd81 100644 --- a/test/helpers/icons_helper_test.rb +++ b/test/helpers/icons_helper_test.rb @@ -144,6 +144,17 @@ class IconsHelperTest < Redmine::HelperTest assert_match expected, icon end + def test_sprite_icon_should_resolve_each_sprite_path_once + expects(:asset_path).with('icons.svg').once.returns('/assets/icons-abc.svg') + expects(:asset_path).with('custom.svg').once.returns('/assets/custom.svg') + + 3.times { sprite_icon('edit') } + 2.times { sprite_icon('edit', sprite: 'custom') } + + assert_match %r{href="/assets/icons-abc.svg#icon--edit"}, sprite_icon('edit') + assert_match %r{href="/assets/custom.svg#icon--edit"}, sprite_icon('edit', sprite: 'custom') + end + def test_sprite_icon_should_return_svg_with_custom_sprite expected = %r{$} icon = sprite_icon('edit', sprite: 'custom') -- 2.55.0