feat(#54): 性能预算与懒加载策略引擎(首屏≤2s,图表懒加载)

纯标准库实现,对齐 PRD 5.5「⑤ 配置化驾驶舱」性能口径:

- perf_budget.py:PerformanceBudget(首屏 2000ms + 6 类资源预算)、
  ResourceMeasurement(block_render 区分关键路径)、BudgetVerifier
  (阻塞串行+非阻塞取最大口径,逐类型比对预算,PASS/FAIL/EMPTY +
  类型化优化建议,reason 可解释)。
- lazy_load.py:LazyLoadStrategy(immediate/visible/idle/never)、
  LazyLoadPolicy(视口行数+预加载+分页阈值+虚拟滚动)、LazyLoadPlanner
  (widget 坐标+滚动位置 → 决策+分页计划+虚拟滚动窗口)。
- tests:32 用例覆盖预算构造/查询、关键路径口径、达标/超预算场景、
  always_load 强制加载、视口边界、分页/虚拟滚动、输入校验。
- _sanity_check.py:冒烟验证达标/超预算/懒加载分流。
This commit is contained in:
2026-08-05 05:26:09 +08:00
parent 2afea16005
commit 5da367dfd8
8 changed files with 1286 additions and 0 deletions
@@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
"""性能预算与懒加载策略冒烟脚本(Issue #54)。
直接运行 ``python _sanity_check.py`` 验证:默认预算可构造、校验器对达标/超预算
场景给出正确状态、懒加载决策器对视口内外 widget 给出 immediate/idle。零第三方依赖。
"""
import importlib.util
import os
import sys
# perf-budget 目录名含连字符,按文件路径加载为合法包 perf_budget。
_PKG_DIR = os.path.dirname(os.path.abspath(__file__))
def _load_pkg(name, path):
if name in sys.modules:
return
spec = importlib.util.spec_from_file_location(
name, os.path.join(path, "__init__.py"),
submodule_search_locations=[path])
mod = importlib.util.module_from_spec(spec)
sys.modules[name] = mod
spec.loader.exec_module(mod)
_load_pkg("perf_budget", _PKG_DIR)
from perf_budget import ( # noqa: E402
BudgetStatus, BudgetVerifier, LazyLoadPlanner, PerformanceBudget,
ResourceMeasurement, ResourceType, WidgetLayout)
def main() -> int:
# 1) 性能预算:达标场景
budget = PerformanceBudget.default_cockpit()
report = BudgetVerifier(budget).verify([
ResourceMeasurement("app.js", ResourceType.JS, 700, block_render=True),
ResourceMeasurement("app.css", ResourceType.CSS, 250, block_render=True),
ResourceMeasurement("doc.html", ResourceType.HTML, 150, block_render=True),
])
assert report.status is BudgetStatus.PASS, report.reason
print(f"[OK] 性能预算达标:首屏 {report.first_paint_ms:.0f}ms "
f"≤ {report.budget_ms:.0f}ms({report.reason})")
# 2) 超预算场景
bad = BudgetVerifier(budget).verify([
ResourceMeasurement("big.js", ResourceType.JS, 950, block_render=True),
])
assert bad.status is BudgetStatus.FAIL
print(f"[OK] 性能预算告警:{bad.overrun[0].reason} → {bad.overrun[0].advice}")
# 3) 懒加载:视口内外分流
plan = LazyLoadPlanner().plan([
WidgetLayout("proc", "process_view", y=0, h=4, always_load=True),
WidgetLayout("trend", "trend", y=10, h=2),
], scroll_y_rows=0)
assert plan.immediate_ids == ["proc"]
assert plan.idle_ids == ["trend"]
print(f"[OK] 懒加载:immediate={plan.immediate_ids} idle={plan.idle_ids}")
print("性能预算与懒加载策略冒烟通过 ✅")
return 0
if __name__ == "__main__":
raise SystemExit(main())