Skip to content

Commit 9ce315d

Browse files
committed
minor #1608 [Icons] Rework cache warm (smnandre)
This PR was squashed before being merged into the 2.x branch. Discussion ---------- [Icons] Rework cache warm The warm cache took a lot of time because - the regexp was very open (due to the non-prefix icon names) - twig templates were listed multiple times (due to the namespace system) And a looot of false positives caused lot of cache locks for nothing. On ux.symfony.com project with this component, the PR make the icons detected from 1000+ to 1 :) And the command is now way quicker to run. The prefix-less icons are warmed by simply listing the SVG at the root of the asset/icons directory Commits ------- 99b19f6 [Icons] Rework cache warm
2 parents f4fd991 + 99b19f6 commit 9ce315d

File tree

3 files changed

+35
-22
lines changed

3 files changed

+35
-22
lines changed

src/Icons/config/services.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,16 @@
5050
])
5151
->tag('twig.runtime')
5252

53-
->set('.ux_icons.twig_icon_finder', IconFinder::class)
53+
->set('.ux_icons.icon_finder', IconFinder::class)
5454
->args([
5555
service('twig'),
56+
abstract_arg('icon_dir'),
5657
])
5758

5859
->set('.ux_icons.cache_warmer', IconCacheWarmer::class)
5960
->args([
6061
service('.ux_icons.cache_icon_registry'),
61-
service('.ux_icons.twig_icon_finder'),
62+
service('.ux_icons.icon_finder'),
6263
])
6364

6465
->set('.ux_icons.command.warm_cache', WarmCacheCommand::class)

src/Icons/src/DependencyInjection/UXIconsExtension.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ protected function loadInternal(array $mergedConfig, ContainerBuilder $container
8787
])
8888
;
8989

90+
$container->getDefinition('.ux_icons.icon_finder')
91+
->setArgument(1, $mergedConfig['icon_dir'])
92+
;
93+
9094
$container->getDefinition('.ux_icons.icon_renderer')
9195
->setArgument(1, $mergedConfig['default_icon_attributes'])
9296
;

src/Icons/src/Twig/IconFinder.php

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
*/
2525
final class IconFinder
2626
{
27-
public function __construct(private Environment $twig)
28-
{
27+
public function __construct(
28+
private Environment $twig,
29+
private string $iconDirectory,
30+
) {
2931
}
3032

3133
/**
@@ -35,42 +37,48 @@ public function icons(): array
3537
{
3638
$found = [];
3739

38-
foreach ($this->files($this->twig->getLoader()) as $file) {
40+
// https://regex101.com/r/WGa4iF/1
41+
$token = '[a-z0-9]+(?:-[a-z0-9]+)*';
42+
$pattern = "#(?:'$token:$token')|(?:\"$token:$token\")#i";
43+
44+
// Extract icon names from strings in app templates
45+
foreach ($this->templateFiles($this->twig->getLoader()) as $file) {
3946
$contents = file_get_contents($file);
47+
if (preg_match_all($pattern, $contents, $matches)) {
48+
$found[] = array_map(fn ($res) => trim($res, '"\''), $matches[0]);
49+
}
50+
}
51+
$found = array_merge(...$found);
4052

41-
if (preg_match_all('#["\']([\w:-]+)["\']#', $contents, $matches)) {
42-
$found[] = $matches[1];
53+
// Extract prefix-less SVG files from the root of the icon directory
54+
if (is_dir($this->iconDirectory)) {
55+
$icons = (new Finder())->files()->in($this->iconDirectory)->depth(0)->name('*.svg');
56+
foreach ($icons as $icon) {
57+
$found[] = $icon->getBasename('.svg');
4358
}
4459
}
4560

46-
return array_unique(array_merge(...$found));
61+
return array_unique($found);
4762
}
4863

4964
/**
5065
* @return string[]
5166
*/
52-
private function files(LoaderInterface $loader): iterable
67+
private function templateFiles(LoaderInterface $loader): iterable
5368
{
54-
$files = [];
55-
5669
if ($loader instanceof FilesystemLoader) {
70+
$paths = [];
5771
foreach ($loader->getNamespaces() as $namespace) {
58-
foreach ($loader->getPaths($namespace) as $path) {
59-
foreach ((new Finder())->files()->in($path)->name('*.twig') as $file) {
60-
$file = (string) $file;
61-
if (!\in_array($file, $files, true)) {
62-
yield $file;
63-
}
64-
65-
$files[] = $file;
66-
}
67-
}
72+
$paths = [...$paths, ...$loader->getPaths($namespace)];
73+
}
74+
foreach ((new Finder())->files()->in($paths)->name('*.twig') as $file) {
75+
yield (string) $file;
6876
}
6977
}
7078

7179
if ($loader instanceof ChainLoader) {
7280
foreach ($loader->getLoaders() as $subLoader) {
73-
yield from $this->files($subLoader);
81+
yield from $this->templateFiles($subLoader);
7482
}
7583
}
7684
}

0 commit comments

Comments
 (0)