diff options
| author | Markus Heiser <markus.heiser@darmarit.de> | 2025-08-19 10:05:42 +0200 |
|---|---|---|
| committer | Markus Heiser <markus.heiser@darmarIT.de> | 2025-08-21 09:07:08 +0200 |
| commit | d2b3c92e81efbba7ec62395ed5203d819c75d74a (patch) | |
| tree | 539a44d5eeae862aa57e3f28a68d632d78cdd1e4 | |
| parent | 41a4a3e224f5fa90522253da4236dd9a6f4083cb (diff) | |
[fix] move initial "JS is enabled?" (no-js) to client side
To avoid an `unsafe-inline` in the CSP header, the JS code must be moved to the
client side [1].
The `<script>` tag at the end of the HTML originates from the old implementation
of the JS client. Since PR-5073 [2] was merged, the `type` is now `module`, and
the tag must be moved to the beginning of the HTML.
> We need to inline this "JS is enabled?" thing to prevent layout shifts and
> temporary "no JS enabled" visuals as ESM scripts loads and evals everything
> deferred from initial DOM render [3]
That's true in theory, but in practice, this effect is unnoticeable because it's
masked by another effect (which we can't avoid): If we load the page with a
severely throttled connection, the HTML (result list) takes a long time to
load. Then the CSS is loaded, which also takes longer. Until the CSS has loaded,
there's no layout. A layout shift is therefore largely determined by the loading
of the HTML and CSS itself.
The running times of the ESM script can be neglected compared to the loading
times of HTML & CSS.
[1] https://github.com/searxng/searxng-docker/pull/424#issuecomment-3199494256
[2] https://github.com/searxng/searxng/pull/5073
[3] https://github.com/searxng/searxng-docker/pull/424#issuecomment-3199622504
| -rw-r--r-- | client/simple/src/js/core/index.ts | 1 | ||||
| -rw-r--r-- | client/simple/src/js/core/nojs.ts | 8 | ||||
| -rw-r--r-- | searx/templates/simple/base.html | 7 |
3 files changed, 10 insertions, 6 deletions
diff --git a/client/simple/src/js/core/index.ts b/client/simple/src/js/core/index.ts index 48d166f7d..59e64182c 100644 --- a/client/simple/src/js/core/index.ts +++ b/client/simple/src/js/core/index.ts @@ -1,5 +1,6 @@ // SPDX-License-Identifier: AGPL-3.0-or-later +import "./nojs.ts"; import "./router.ts"; import "./toolkit.ts"; import "./listener.ts"; diff --git a/client/simple/src/js/core/nojs.ts b/client/simple/src/js/core/nojs.ts new file mode 100644 index 000000000..65c62dd90 --- /dev/null +++ b/client/simple/src/js/core/nojs.ts @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { ready } from "./toolkit.ts"; + +ready(() => { + document.documentElement.classList.remove("no-js"); + document.documentElement.classList.add("js"); +}); diff --git a/searx/templates/simple/base.html b/searx/templates/simple/base.html index bd2e41a33..3ddc62ace 100644 --- a/searx/templates/simple/base.html +++ b/searx/templates/simple/base.html @@ -10,6 +10,7 @@ <meta name="robots" content="noarchive"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>{% block title %}{% endblock %}{{ instance_name }}</title> + <script type="module" src="{{ url_for('static', filename='js/searxng.core.min.js') }}" client_settings="{{ client_settings }}"></script> {% block meta %}{% endblock %} {% if rtl %} <link rel="stylesheet" href="{{ url_for('static', filename='css/searxng-rtl.min.css') }}" type="text/css" media="screen"> @@ -19,11 +20,6 @@ {% if get_setting('server.limiter') or get_setting('server.public_instance') %} <link rel="stylesheet" href="{{ url_for('client_token', token=link_token) }}" type="text/css"> {% endif %} - <script> - // update the css - document.documentElement.classList.remove('no-js'); - document.documentElement.classList.add('js'); - </script> {% block head %} <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"> {% endblock %} @@ -83,6 +79,5 @@ {% endfor %} </p> </footer> - <script type="module" src="{{ url_for('static', filename='js/searxng.core.min.js') }}" client_settings="{{ client_settings }}"></script> </body> </html> |