架构微调

This commit is contained in:
2026-08-11 11:21:54 +08:00
parent 0dcf1fbb35
commit 5710da3acf
3 changed files with 48 additions and 22 deletions
+39 -13
View File
@@ -240,7 +240,13 @@ class GalleryCard {
this.node.querySelector(".perf-pending").textContent = observer.pending_frame_count ?? 0;
this.node.querySelector(".perf-dropped").textContent = observer.dropped_frame_count ?? 0;
this.node.querySelector(".perf-points").textContent = `${Number(dataShape.input_points || 0).toLocaleString()}${Number(dataShape.rendered_elements || 0).toLocaleString()}`;
this.node.querySelector(".perf-limit").textContent = limitNames[limit.current] || limit.current || "N/A";
const limitDurations = {frequency_limited: observer.target_interval_ns, paint_limited: observer.paint_duration_ns, render_limited: observer.render_duration_ns, consumer_limited: observer.consumer_interval_ns};
const limitName = limitNames[limit.current] || limit.current || "N/A";
const limitDuration = limitDurations[limit.current];
const limitValue = limitDuration === undefined ? limitName : `${limitName} · ${formatNanoseconds(limitDuration)}`;
const limitNode = this.node.querySelector(".perf-limit");
limitNode.textContent = limitValue;
limitNode.title = limitDuration === undefined ? limitName : `${limitName} · ${Number(limitDuration || 0).toLocaleString()} ns`;
this.node.querySelector(".perf-event").textContent = observer.last_event || "none";
this.node.querySelector(".perf-timeouts").textContent = this.frameTimeoutCount.toLocaleString();
this.node.querySelector(".perf-pixel-age").textContent = this.lastPixelReceivedAt ? `${Math.max(0, performance.now() - this.lastPixelReceivedAt).toFixed(0)} ms` : "—";
@@ -249,7 +255,7 @@ class GalleryCard {
const setLimitFlag = (selector, enabled, active, duration) => {
const flag = this.node.querySelector(selector);
flag.dataset.active = String(Boolean(active));
flag.querySelector("b").textContent = enabled ? `${active ? "受限" : "未受限"} · ${formatNanoseconds(duration)}` : "已关闭";
flag.querySelector("b").textContent = enabled ? `${active ? "当前瓶颈" : "未受限"} · ${formatNanoseconds(duration)}` : `已关闭 · ${formatNanoseconds(duration)}`;
};
setLimitFlag(".limit-frequency", observer.frequency_limit_enabled !== false, limit.current === "frequency_limited", observer.target_interval_ns);
setLimitFlag(".limit-paint", true, limit.current === "paint_limited", observer.paint_duration_ns);
@@ -514,22 +520,42 @@ function renderControl(item) {
if (item.input === "number") { input.min = item.minimum; input.max = item.maximum; input.step = item.step || "any"; }
}
input.className = "control-input"; input.title = item.description || item.api;
let submitTimer = 0;
const submit = () => {
clearTimeout(submitTimer); submitTimer = 0;
const value = item.input === "boolean" ? input.checked : item.input === "number" ? Number(input.value) : input.value;
if (item.input === "number" && (input.value === "" || !Number.isFinite(value))) return;
const submit = value => {
card.send("gallery_patch", {patch: {[item.id]: value}});
elements.menuStatus.textContent = `提交 ${item.api} · 等待后端回读`;
};
if (item.input === "number") {
input.addEventListener("input", () => {
clearTimeout(submitTimer);
submitTimer = setTimeout(submit, 120);
let committedValue = input.value;
const commit = () => {
const value = input.valueAsNumber;
const minimum = Number(item.minimum);
const maximum = Number(item.maximum);
if (input.value === "" || !Number.isFinite(value) ||
(Number.isFinite(minimum) && value < minimum) ||
(Number.isFinite(maximum) && value > maximum)) {
input.value = committedValue;
return;
}
if (value === Number(committedValue)) {
input.value = committedValue;
return;
}
committedValue = input.value;
item.value = value;
submit(value);
};
input.addEventListener("blur", commit);
input.addEventListener("keydown", event => {
if (event.key === "Enter") {
event.preventDefault();
commit();
} else if (event.key === "Escape") {
event.preventDefault();
event.stopPropagation();
input.value = committedValue;
}
});
input.addEventListener("change", submit);
input.addEventListener("keydown", event => { if (event.key === "Enter") submit(); });
} else input.addEventListener("change", submit);
} else input.addEventListener("change", () => submit(item.input === "boolean" ? input.checked : input.value));
row.append(copy, input); return row;
}
function renderAction(item) {