dsh-perf-boost 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -0
- package/README.md +4 -0
- package/lib/client.js +133 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
package/lib/client.js
CHANGED
|
@@ -28,9 +28,16 @@ window.__ModuleLoader__.load({
|
|
|
28
28
|
var STYLE_ID = 'dpb-style';
|
|
29
29
|
var CV_CLASS = 'dpb-cv'; // 挂在滚动列表容器上,子项的 content-visibility 交给 CSS
|
|
30
30
|
var CV_VAR = '--dpb-cis';
|
|
31
|
-
var VERSION = '0.2.
|
|
31
|
+
var VERSION = '0.2.3';
|
|
32
32
|
// 更新公告:只用「新增了…的功能 / 修复了…的问题 / 优化了…的效果」三种句式。
|
|
33
33
|
var RELEASE_NOTES = [
|
|
34
|
+
{
|
|
35
|
+
version: '0.2.3',
|
|
36
|
+
items: [
|
|
37
|
+
'新增了后台回收内存的开关,窗口隐藏一会儿就把视频缓冲和资源记录放掉的功能',
|
|
38
|
+
'新增了设置页里显示当前 JS 堆占用的效果',
|
|
39
|
+
],
|
|
40
|
+
},
|
|
34
41
|
{
|
|
35
42
|
version: '0.2.2',
|
|
36
43
|
items: [
|
|
@@ -75,6 +82,7 @@ window.__ModuleLoader__.load({
|
|
|
75
82
|
hiddenTimers: true,
|
|
76
83
|
mediaPause: true,
|
|
77
84
|
listGate: true,
|
|
85
|
+
bgTrim: true,
|
|
78
86
|
// 默认关:会改观感或动画
|
|
79
87
|
noBlur: false,
|
|
80
88
|
reduceMotion: false,
|
|
@@ -258,6 +266,7 @@ window.__ModuleLoader__.load({
|
|
|
258
266
|
timerMs: 0, timerRuns: 0, timerSkipped: 0,
|
|
259
267
|
setMs: 0, setRuns: 0, setMerged: 0,
|
|
260
268
|
lazyItems: 0, mediaPaused: 0, mediaLazy: 0,
|
|
269
|
+
trimRuns: 0, trimMedia: 0,
|
|
261
270
|
};
|
|
262
271
|
function metPer(x, n) { return n > 0 ? x / n : 0; }
|
|
263
272
|
// rAF 那部分不算「省下」:页面隐藏时压住回调只是推迟,回到前台会一次性补跑,
|
|
@@ -1020,6 +1029,7 @@ window.__ModuleLoader__.load({
|
|
|
1020
1029
|
MET.rafSkipped, MET.timerSkipped,
|
|
1021
1030
|
g ? g.published : 0, g ? g.coalesced : 0,
|
|
1022
1031
|
MET.lazyItems, MET.mediaLazy, MET.mediaPaused,
|
|
1032
|
+
MET.trimRuns, heapMb(),
|
|
1023
1033
|
].join('|');
|
|
1024
1034
|
};
|
|
1025
1035
|
var tick = function () {
|
|
@@ -1087,6 +1097,13 @@ window.__ModuleLoader__.load({
|
|
|
1087
1097
|
warmupCall(v).then(function (real) { if (real !== null) setWarmupOn(real); });
|
|
1088
1098
|
},
|
|
1089
1099
|
})),
|
|
1100
|
+
React.createElement(Row, { label: '后台回收内存', hint: '窗口隐藏超过 45 秒后放掉视频缓冲、清空资源计时,观察器也停掉。可能会导致回到前台时视频要重新缓冲一下。默认开。' + lastTrimText() },
|
|
1101
|
+
React.createElement('div', { style: { display: 'flex', gap: 8, alignItems: 'center', flex: '0 0 auto' } },
|
|
1102
|
+
React.createElement('button', {
|
|
1103
|
+
type: 'button', className: 'dpb-btn',
|
|
1104
|
+
onClick: function () { try { if (typeof window.__dpbTrim === 'function') window.__dpbTrim(); } catch (e) { void e; } bump(function (n) { return n + 1; }); },
|
|
1105
|
+
}, '立即回收'),
|
|
1106
|
+
React.createElement(Sw, { label: '后台回收内存', value: !!cfg.bgTrim, onChange: function (v) { setCfg({ bgTrim: v }); } }))),
|
|
1090
1107
|
React.createElement(Row, { label: '关闭背景模糊', hint: '浮层从磨砂变纯色底,能看出来。默认关。' },
|
|
1091
1108
|
React.createElement(Sw, { label: '关闭背景模糊', value: !!cfg.noBlur, onChange: function (v) { setCfg({ noBlur: v }); } })),
|
|
1092
1109
|
React.createElement(Row, { label: '减少动画', hint: '关掉 CSS 动画和过渡,弹窗不再逐帧动。默认关。' },
|
|
@@ -1098,6 +1115,7 @@ window.__ModuleLoader__.load({
|
|
|
1098
1115
|
React.createElement('div', { className: 'dpb-card' },
|
|
1099
1116
|
React.createElement('div', { className: 'dpb-stat' },
|
|
1100
1117
|
React.createElement('span', null, '版本 ', React.createElement('b', null, update.installed ? 'v' + update.installed : 'v' + VERSION)),
|
|
1118
|
+
React.createElement('span', null, '堆 ', React.createElement('b', null, heapMb() === null ? '—' : heapMb() + ' MB')),
|
|
1101
1119
|
React.createElement('span', null, '最新 ', React.createElement('b', null,
|
|
1102
1120
|
update.state === 'checking' ? '检查中…'
|
|
1103
1121
|
: update.available ? 'v' + update.latest
|
|
@@ -1122,6 +1140,7 @@ window.__ModuleLoader__.load({
|
|
|
1122
1140
|
else installRafThrottle();
|
|
1123
1141
|
installTimerPause();
|
|
1124
1142
|
applyStyle();
|
|
1143
|
+
onVisibilityForTrim();
|
|
1125
1144
|
// 首屏别抢:等空闲再扫,扫描期间若在流式输出会往后推。
|
|
1126
1145
|
idleRun(function () {
|
|
1127
1146
|
try { applyLazyList(); } catch (e) { void e; }
|
|
@@ -1143,6 +1162,118 @@ window.__ModuleLoader__.load({
|
|
|
1143
1162
|
else root.classList.remove('dpb-quiet');
|
|
1144
1163
|
}
|
|
1145
1164
|
|
|
1165
|
+
// ————————————————— 后台回收内存 —————————————————
|
|
1166
|
+
// 隐藏超过 45 秒才动手:切走一下去看文件不动它,免得回来视频要重新缓冲。
|
|
1167
|
+
// 长期最小化时,把能放的全放掉:视频缓冲、资源计时、观察器、记录表。
|
|
1168
|
+
var BG_TRIM_AFTER_MS = 45000;
|
|
1169
|
+
var bgTrimTimer = 0;
|
|
1170
|
+
|
|
1171
|
+
function heapMb() {
|
|
1172
|
+
var m = null;
|
|
1173
|
+
try { m = performance.memory; } catch (e) { m = null; }
|
|
1174
|
+
if (!m || !m.usedJSHeapSize) return null;
|
|
1175
|
+
return Math.round(m.usedJSHeapSize / 1048576);
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
function trimMedia() {
|
|
1179
|
+
var n = 0;
|
|
1180
|
+
var vids = document.querySelectorAll('video');
|
|
1181
|
+
for (var k = 0; k < vids.length; k++) {
|
|
1182
|
+
var v = vids[k];
|
|
1183
|
+
try {
|
|
1184
|
+
// 后台正在出声的不碰:用户可能在听。
|
|
1185
|
+
if (!v.paused && !v.muted && v.volume > 0) continue;
|
|
1186
|
+
if (v.getAttribute('data-dpb-src') !== null) continue;
|
|
1187
|
+
var src = v.getAttribute('src') || '';
|
|
1188
|
+
var kids = v.querySelectorAll('source');
|
|
1189
|
+
var sources = [];
|
|
1190
|
+
for (var j = 0; j < kids.length; j += 1) {
|
|
1191
|
+
sources.push({ src: kids[j].getAttribute('src') || '', type: kids[j].getAttribute('type') || '' });
|
|
1192
|
+
}
|
|
1193
|
+
v.setAttribute('data-dpb-src', src);
|
|
1194
|
+
v.setAttribute('data-dpb-pre', v.getAttribute('preload') || '');
|
|
1195
|
+
if (sources.length) v.setAttribute('data-dpb-sources', JSON.stringify(sources));
|
|
1196
|
+
v.setAttribute('preload', 'none');
|
|
1197
|
+
// 只把 src 摘掉再 load(),浏览器才真正丢弃已缓冲的媒体数据;
|
|
1198
|
+
// 留着 src 只是标记「别预载」,缓冲还在内存里(实测 buffered 不归零)。
|
|
1199
|
+
if (src || sources.length) {
|
|
1200
|
+
v.removeAttribute('src');
|
|
1201
|
+
for (var m = kids.length - 1; m >= 0; m -= 1) kids[m].remove();
|
|
1202
|
+
v.load();
|
|
1203
|
+
}
|
|
1204
|
+
n += 1;
|
|
1205
|
+
} catch (e) { void e; }
|
|
1206
|
+
}
|
|
1207
|
+
return n;
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
function lastTrimText() {
|
|
1211
|
+
var t = window.__dpbLastTrim;
|
|
1212
|
+
if (!t) return '';
|
|
1213
|
+
var mins = Math.max(1, Math.round((Date.now() - t.at) / 60000));
|
|
1214
|
+
return ' 上次回收:' + mins + ' 分钟前,放掉 ' + t.freed + ' 个视频缓冲。';
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
function trimMemory(why) {
|
|
1218
|
+
if (!cfg.bgTrim) return;
|
|
1219
|
+
var freed = 0;
|
|
1220
|
+
try { if (performance.clearResourceTimings) performance.clearResourceTimings(); } catch (e) { void e; }
|
|
1221
|
+
try { freed = trimMedia(); } catch (e) { void e; }
|
|
1222
|
+
try { if (mediaObserver) mediaObserver.disconnect(); } catch (e) { void e; }
|
|
1223
|
+
try { if (timerRecs.length > 200) timerRecs.splice(0, timerRecs.length - 200); } catch (e) { void e; }
|
|
1224
|
+
try { if (typeof window.gc === 'function') window.gc(); } catch (e) { void e; }
|
|
1225
|
+
MET.trimRuns += 1;
|
|
1226
|
+
MET.trimMedia += freed;
|
|
1227
|
+
try { window.__dpbLastTrim = { at: Date.now(), why: why, freed: freed, heap: heapMb() }; } catch (e) { void e; }
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
// 设置页的「立即回收」与自检脚本都走这里。
|
|
1231
|
+
try { window.__dpbTrim = function () { trimMemory('manual'); return window.__dpbLastTrim || null; }; } catch (e) { void e; }
|
|
1232
|
+
|
|
1233
|
+
function restoreMediaPreload() {
|
|
1234
|
+
var list = document.querySelectorAll('[data-dpb-src]');
|
|
1235
|
+
for (var i = 0; i < list.length; i++) {
|
|
1236
|
+
try {
|
|
1237
|
+
var v = list[i];
|
|
1238
|
+
var src = v.getAttribute('data-dpb-src') || '';
|
|
1239
|
+
var pre = v.getAttribute('data-dpb-pre') || '';
|
|
1240
|
+
var srcs = null;
|
|
1241
|
+
try { srcs = JSON.parse(v.getAttribute('data-dpb-sources') || 'null'); } catch (e) { srcs = null; }
|
|
1242
|
+
if (src) v.setAttribute('src', src);
|
|
1243
|
+
if (srcs && srcs.length) {
|
|
1244
|
+
for (var j = 0; j < srcs.length; j += 1) {
|
|
1245
|
+
var el = document.createElement('source');
|
|
1246
|
+
if (srcs[j].src) el.setAttribute('src', srcs[j].src);
|
|
1247
|
+
if (srcs[j].type) el.setAttribute('type', srcs[j].type);
|
|
1248
|
+
v.appendChild(el);
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
if (pre) v.setAttribute('preload', pre); else v.removeAttribute('preload');
|
|
1252
|
+
v.removeAttribute('data-dpb-src');
|
|
1253
|
+
v.removeAttribute('data-dpb-pre');
|
|
1254
|
+
v.removeAttribute('data-dpb-sources');
|
|
1255
|
+
// 把源接回去后重新 load 一次,浏览器才会重新按需取流。
|
|
1256
|
+
if (src || (srcs && srcs.length)) v.load();
|
|
1257
|
+
} catch (e) { void e; }
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
function onVisibilityForTrim() {
|
|
1262
|
+
if (bgTrimTimer) { window.clearTimeout(bgTrimTimer); bgTrimTimer = 0; }
|
|
1263
|
+
if (document.hidden) {
|
|
1264
|
+
if (!cfg.bgTrim) return;
|
|
1265
|
+
bgTrimTimer = window.setTimeout(function () {
|
|
1266
|
+
bgTrimTimer = 0;
|
|
1267
|
+
if (document.hidden) trimMemory('hidden');
|
|
1268
|
+
}, BG_TRIM_AFTER_MS);
|
|
1269
|
+
} else {
|
|
1270
|
+
try { restoreMediaPreload(); } catch (e) { void e; }
|
|
1271
|
+
idleRun(function () {
|
|
1272
|
+
try { applyViewportMedia(); } catch (e) { void e; }
|
|
1273
|
+
}, 300);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1146
1277
|
function mount() {
|
|
1147
1278
|
applyAll();
|
|
1148
1279
|
// 采样快照自己走:不依赖设置页开着,否则百分比只在打开设置后才更新。
|
|
@@ -1153,6 +1284,7 @@ window.__ModuleLoader__.load({
|
|
|
1153
1284
|
}
|
|
1154
1285
|
document.addEventListener('visibilitychange', flushTimers);
|
|
1155
1286
|
document.addEventListener('visibilitychange', applyHiddenClass);
|
|
1287
|
+
document.addEventListener('visibilitychange', onVisibilityForTrim);
|
|
1156
1288
|
applyHiddenClass();
|
|
1157
1289
|
watchBusy();
|
|
1158
1290
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-perf-boost",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "DSH 桌面端性能优化(纯客户端):长对话省渲染、窗口隐藏不排帧默认开,关背景模糊/减少动画/空闲降帧按需打开,设置页显示实测省下的主线程时间。Client-side rendering optimizations for DeepSeek Harness Desktop.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|