[fix] preferences: opening preferences page is very slow (multiple seconds on bad hardware) (#6090)

I've been profiling the `/preferences` endpoint using werkzeug's
`ProfilerMiddleware` (i.e. just do `app.wsgi_app = ProfilerMiddleware(app.wsgi_app)`)
and look at the outputs in the terminal when doing `make run`.

It turns out that 95%+ of the time spent were inside babel's
Locale parsing (> 700ms on my machine). That's because, when opening the settings,
we loaded the full engine traits of each engine and checked if it matches
the user-defined search language. As we have 250+ engines, and babel is
very slow when parsing Locale's, this took a very long time.

By removing this feature that shows whether the selected search language
is supported by the engine, the load time went down from 800ms to 50ms
on my machine (which is still very slow, but well, that's future work on
optimizing).
This commit is contained in:
Bnyro
2026-05-21 21:15:09 +02:00
committed by GitHub
parent d3deacc6d4
commit b9340f50c2
3 changed files with 2 additions and 28 deletions
-13
View File
@@ -116,19 +116,6 @@ class EngineTraits:
return self.all_locale
return locales.get_engine_locale(searxng_locale, self.regions, default=default)
def is_locale_supported(self, searxng_locale: str) -> bool:
"""A *locale* (SearXNG's internal representation) is considered to be
supported by the engine if the *region* or the *language* is supported
by the engine.
For verification the functions :py:func:`EngineTraits.get_region` and
:py:func:`EngineTraits.get_language` are used.
"""
if self.data_type == "traits_v1":
return bool(self.get_region(searxng_locale) or self.get_language(searxng_locale))
raise TypeError("engine traits of type %s is unknown" % self.data_type)
def copy(self):
"""Create a copy of the dataclass object."""
return EngineTraits(**dataclasses.asdict(self))
@@ -23,7 +23,6 @@
<th class="checkbox-col">{{- _("Allow") -}}</th>{{- '' -}}
<th class="name">{{- _("Engine name") -}}</th>{{- '' -}}
<th class="shortcut">{{ _("!bang") -}}</th>{{- '' -}}
<th>{{- _("Supports selected language") -}}</th>{{- '' -}}
<th>{{- _("SafeSearch") -}}</th>{{- '' -}}
<th>{{- _("Time range") -}}</th>{{- '' -}}
<th>{{- _("Weight") }}</th>
@@ -70,9 +69,6 @@
<td class="shortcut">{{- '' -}}
<span class="bang">{{ '!' + shortcuts[search_engine.name] }}</span>{{- '' -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['supports_selected_language'], true) -}}
</td>{{- '' -}}
<td>
{{- checkbox(None, supports[search_engine.name]['safesearch'], true) -}}
</td>{{- '' -}}
+2 -11
View File
@@ -918,9 +918,6 @@ def preferences():
'rate80': rate80,
'rate95': rate95,
'warn_timeout': e.timeout > settings['outgoing']['request_timeout'],
'supports_selected_language': e.traits.is_locale_supported(
str(sxng_request.preferences.get_value('language') or 'all')
),
'result_count': result_count,
}
# end of stats
@@ -956,15 +953,9 @@ def preferences():
# supports
supports = {}
for _, e in filtered_engines.items():
supports_selected_language = e.traits.is_locale_supported(
str(sxng_request.preferences.get_value('language') or 'all')
)
safesearch = e.safesearch
time_range_support = e.time_range_support
supports[e.name] = {
'supports_selected_language': supports_selected_language,
'safesearch': safesearch,
'time_range_support': time_range_support,
'safesearch': e.safesearch,
'time_range_support': e.time_range_support,
}
return render(