mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-07-09 17:08:29 +00:00
Stop WebUI startup scripts from blocking render
Load startup vendor scripts with defer and serve Bootstrap locally so the first WebUI mount no longer depends on a parser-blocking CDN request. Add a focused regression that rejects undeferred classic startup scripts in index.html and documents the vendor/startup contract.
This commit is contained in:
parent
7aba42d46e
commit
5ac4f75a47
6 changed files with 80 additions and 8 deletions
40
tests/test_webui_startup_assets.py
Normal file
40
tests/test_webui_startup_assets.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
from pathlib import Path
|
||||
from html.parser import HTMLParser
|
||||
|
||||
|
||||
PROJECT_ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
class ScriptParser(HTMLParser):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
self.scripts: list[dict[str, str | None]] = []
|
||||
|
||||
def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
|
||||
if tag == "script":
|
||||
self.scripts.append(dict(attrs))
|
||||
|
||||
|
||||
def test_bootstrap_is_local_and_deferred() -> None:
|
||||
index_html = (PROJECT_ROOT / "webui" / "index.html").read_text(encoding="utf-8")
|
||||
|
||||
assert "cdn.jsdelivr.net/npm/bootstrap" not in index_html
|
||||
assert '<script defer src="vendor/bootstrap/bootstrap.bundle.min.js"></script>' in index_html
|
||||
assert (PROJECT_ROOT / "webui" / "vendor" / "bootstrap" / "bootstrap.bundle.min.js").is_file()
|
||||
|
||||
|
||||
def test_classic_startup_scripts_are_deferred() -> None:
|
||||
index_html = (PROJECT_ROOT / "webui" / "index.html").read_text(encoding="utf-8")
|
||||
parser = ScriptParser()
|
||||
parser.feed(index_html)
|
||||
|
||||
blocking_scripts = [
|
||||
script["src"]
|
||||
for script in parser.scripts
|
||||
if script.get("src")
|
||||
and script.get("type") != "module"
|
||||
and "defer" not in script
|
||||
and "async" not in script
|
||||
]
|
||||
|
||||
assert blocking_scripts == []
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
- Component HTML loaded by the shared loader may include `<title>`, module scripts, body content, and scoped styles; modal content uses the same loader path.
|
||||
- Do not bypass WebSocket origin/auth/CSRF assumptions from frontend code.
|
||||
- Avoid editing vendored files unless intentionally updating the vendor asset.
|
||||
- Startup scripts in `index.html` must be local and non-parser-blocking: use ES modules, `defer`, or `async` for every script with `src`.
|
||||
- Rubik (`--font-family-main`) is the default WebUI text and control font; use the code/mono font tokens only for code, logs, paths, and fixed-width data.
|
||||
- Hover, focus, and active border treatments should follow existing neutral border/background patterns; avoid hard-coded blue border highlights unless matching an established specialized surface.
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<!-- Flatpickr for datetime picker -->
|
||||
<link rel="stylesheet" href="vendor/flatpickr/flatpickr.min.css">
|
||||
<script src="vendor/flatpickr/flatpickr.min.js"></script>
|
||||
<script defer src="vendor/flatpickr/flatpickr.min.js"></script>
|
||||
|
||||
<script>
|
||||
globalThis.safeCall = function (name, ...args) {
|
||||
|
|
@ -34,15 +34,14 @@
|
|||
<script type="module" src="index.js"></script>
|
||||
|
||||
<!-- Bootstrap JS (only for logic, importing bundled CSS => UI conflicts) -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
|
||||
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
|
||||
crossorigin="anonymous"></script>
|
||||
<script defer src="vendor/bootstrap/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<!-- Then load Alpine.js -->
|
||||
<!-- <script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.14.3/dist/cdn.min.js"></script> -->
|
||||
<script defer src="vendor/ace-min/ace.js"></script>
|
||||
<script defer src="vendor/qrcode.min.js"></script>
|
||||
<script type="module" src="js/initFw.js"></script>
|
||||
|
||||
<script src="vendor/ace-min/ace.js"></script>
|
||||
<link href="vendor/ace-min/ace.min.css" rel="stylesheet">
|
||||
<!-- KaTeX CSS -->
|
||||
<link rel="stylesheet" href="vendor/katex/katex.min.css" crossorigin="anonymous">
|
||||
|
|
@ -51,9 +50,6 @@
|
|||
<script defer src="vendor/katex/katex.min.js" crossorigin="anonymous"></script>
|
||||
<script defer src="vendor/katex/katex.auto-render.min.js" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- QR Code Library -->
|
||||
<script src="vendor/qrcode.min.js"></script>
|
||||
|
||||
<!-- Google Icons -->
|
||||
<link rel="stylesheet" href="vendor/google/google-icons.css" />
|
||||
|
||||
|
|
|
|||
1
webui/vendor/AGENTS.md
vendored
1
webui/vendor/AGENTS.md
vendored
|
|
@ -35,6 +35,7 @@ Direct child DOX files:
|
|||
| [_ace/AGENTS.md](_ace/AGENTS.md) | Minimal Ace editor subset used by core editor surfaces. |
|
||||
| [ace-min/AGENTS.md](ace-min/AGENTS.md) | Full minified Ace distribution and supporting assets. |
|
||||
| [alpine/AGENTS.md](alpine/AGENTS.md) | Vendored Alpine.js core and collapse plugin. |
|
||||
| [bootstrap/AGENTS.md](bootstrap/AGENTS.md) | Vendored Bootstrap JavaScript bundle for collapse and tooltip behavior. |
|
||||
| [dompurify/AGENTS.md](dompurify/AGENTS.md) | Vendored DOMPurify sanitizer module. |
|
||||
| [flatpickr/AGENTS.md](flatpickr/AGENTS.md) | Vendored Flatpickr date/time picker assets. |
|
||||
| [google/AGENTS.md](google/AGENTS.md) | Vendored Google Material Symbols font and stylesheet. |
|
||||
|
|
|
|||
27
webui/vendor/bootstrap/AGENTS.md
vendored
Normal file
27
webui/vendor/bootstrap/AGENTS.md
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Bootstrap Vendor DOX
|
||||
|
||||
## Purpose
|
||||
|
||||
- Own the vendored Bootstrap JavaScript bundle used for collapse and tooltip behavior.
|
||||
|
||||
## Ownership
|
||||
|
||||
- `bootstrap.bundle.min.js` owns Bootstrap runtime behavior.
|
||||
|
||||
## Local Contracts
|
||||
|
||||
- Do not hand-edit the minified vendor file for application behavior.
|
||||
- Keep `webui/index.html` synchronized with the local bundle path.
|
||||
- Bootstrap must be served locally and loaded with `defer` so startup does not wait on an external parser-blocking script.
|
||||
|
||||
## Work Guidance
|
||||
|
||||
- Replace from a clean upstream release when updating.
|
||||
|
||||
## Verification
|
||||
|
||||
- Smoke-test sidebar collapse controls and tooltips after changes.
|
||||
|
||||
## Child DOX Index
|
||||
|
||||
No child DOX files.
|
||||
7
webui/vendor/bootstrap/bootstrap.bundle.min.js
vendored
Normal file
7
webui/vendor/bootstrap/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue