Release 3.8.1.1: lighter idle UI poll, core cache, multicore ping.

Reduce idle CPU (cheap PollUI, binary cache, logbuf cap, DOM fingerprint),
speed ping/AWG HostPort, CopyBuffer pool; ship arm64 build and update notes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
M4
2026-07-30 02:27:17 +03:00
co-authored by Cursor
parent bec6c8392d
commit 6b6c13c933
29 changed files with 559 additions and 100 deletions
+22 -2
View File
@@ -202,6 +202,22 @@
(pings || []).forEach((p) => { pingMap[p.name] = p; });
}
let listFP = "";
function profilesFingerprint(state) {
const parts = [
state.connected ? "1" : "0",
state.active_profile || state.profile || "",
];
(state.profiles || []).forEach((p) => {
parts.push(p.name + "|" + (p.protocol || "") + "|" + (p.host || ""));
});
(state.pings || []).forEach((p) => {
parts.push(p.name + "|" + (p.ok ? 1 : 0) + "|" + (p.ms || 0) + "|" + (p.error || ""));
});
return parts.join("\n");
}
function fillProfiles(list, active) {
profiles = list || [];
const cur = profile.value;
@@ -361,7 +377,11 @@
btn.disabled = busy;
rememberPings(state.pings || []);
fillProfiles(state.profiles || [], state.active_profile || state.profile);
const fp = profilesFingerprint(state);
if (syncForm || fp !== listFP) {
listFP = fp;
fillProfiles(state.profiles || [], state.active_profile || state.profile);
}
renderUpdate(state.update, state.version);
if (typeof state.subscription_url === "string" && !dirty) {
subUrl.value = state.subscription_url;
@@ -641,5 +661,5 @@
setMeta(String(e), "err");
}
})();
setInterval(() => { if (!busy && !modal.classList.contains("open")) refresh().catch(() => {}); }, 2500);
setInterval(() => { if (!busy && !modal.classList.contains("open")) refresh().catch(() => {}); }, 4000);
+1 -1
View File
@@ -46,7 +46,7 @@
<div class="brand-wrap">
<div class="brand-row">
<h1 class="brand">Navis</h1>
<span class="badge-ver" id="badgeVer">3.8.0</span>
<span class="badge-ver" id="badgeVer">3.8.1</span>
</div>
<p class="tagline">Быстрый клиент · Naive · Hy2 · AWG · Xray</p>
</div>