# -*- coding: utf-8 -*- """问题 1 取证:长会话渲染的真实 DOM 规模与耗时(离屏,临时库)""" import os import sys import time import json import tempfile sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..")) os.environ.setdefault("QT_QPA_PLATFORM", "offscreen") os.environ["QTWEBENGINE_CHROMIUM_FLAGS"] = "--disable-gpu" os.environ.setdefault("PYTHONIOENCODING", "utf-8") import core.db_manager as _dbm # noqa: E402 _dbm._DEFAULT_DB = os.path.join(tempfile.gettempdir(), f"haocode_q1_{os.getpid()}.db") _cfg = os.path.join(tempfile.gettempdir(), f"haocode_q1_{os.getpid()}.json") open(_cfg, "w", encoding="utf-8").write('{"providers": {}}') os.environ["HAOCODE_CONFIG_FILE"] = _cfg from PyQt6.QtWidgets import QApplication # noqa: E402 from PyQt6.QtTest import QTest # noqa: E402 from ui.views.main_window import MainWindow # noqa: E402 N = int(sys.argv[1]) if len(sys.argv) > 1 else 200 app = QApplication(sys.argv) w = MainWindow() w.resize(1200, 850) w.show() for _ in range(30): app.processEvents() QTest.qWait(20) sid = w.db.create_session(f"长会话渲染取证 {N} 条")["id"] parent = None # 造 N 轮(每轮 user + assistant,assistant 带代码块 + 工具时间线,贴近真实负载) for i in range(N // 2): parent = w.db.add_message(session_id=sid, role="user", content=f"第 {i} 个问题:帮我看看这段代码\n```python\nprint({i})\n```", parent_id=parent)["id"] tl = json.dumps([ {"t": "think", "text": "分析中…" * 20}, {"t": "text", "text": f"### 回答 {i}\n\n要点如下:\n\n- 第一条\n- 第二条\n\n```python\nfor j in range(10):\n print(j)\n```\n"}, {"t": "tool", "id": f"c{i}", "name": "bash", "args": '{"command":"echo hi"}', "ok": True, "result": "hi\n" * 30}, ], ensure_ascii=False) parent = w.db.add_message(session_id=sid, role="assistant", content=f"回答 {i}:见代码块与工具结果。", parent_id=parent, timeline=tl)["id"] chain = w.db.get_message_chain(sid) print(f"库内消息条数 = {len(chain)}") t0 = time.time() w.load_messages_to_web(sid) for _ in range(80): app.processEvents() QTest.qWait(25) dt = time.time() - t0 holder = {} done = [] def got(res): holder["dom"] = res done.append(1) w.browser.page().runJavaScript( "JSON.stringify({wrappers: document.querySelectorAll('.message-wrapper').length," " nodes: document.getElementsByTagName('*').length," " height: document.scrollingElement.scrollHeight," " codeBlocks: document.querySelectorAll('.code-block-wrapper').length," " katex: document.querySelectorAll('.katex').length})", got) for _ in range(60): app.processEvents() QTest.qWait(25) if done: break print(f"渲染耗时 ≈ {dt:.2f}s") print("DOM 统计 =", holder.get("dom")) if holder.get("dom"): d = json.loads(holder["dom"]) print(f" → 消息节点 {d['wrappers']} 个 / 全 DOM 节点 {d['nodes']} 个 / " f"页面总高 {d['height']}px / 代码块 {d['codeBlocks']} 个") print(f" → 平均每条消息 {d['nodes'] // max(1, d['wrappers'])} 个 DOM 节点") os.remove(_cfg)