可以在浏览器中检查 'available memory' 吗?
Possible to check 'available memory' within a browser?
我只是在编一个场景,假设我有一个 500MB 的文件,我想提供一个 html table 供客户端查看数据。假设有两种情况:
- 他们正在通过具有 1.2GB 可用内存的桌面查看它。他们可以下载整个文件。
- 稍后,他们尝试在 phone 上查看相同的 table。我们检测到他们只有 27MB 的可用内存,因此向他们发出警告:“我们检测到您的设备没有足够的内存来查看整个 table。您想下载一个示例吗?”
忽略诸如分页或虚拟 tables 之类的东西,我只关心“完整数据集是否适合用户的可用内存”。这是否可以在浏览器中检测到(即使有用户的确认)。如果是这样,如何做到这一点?
更新
这个答案大约是 6 年前的答案,the question 指向 10 年前的答案。我想知道当前状态是什么,因为从那时起浏览器已经发生了很大变化,而且还有 webassembly 等。
有点。
截至撰写本文时,正在开发设备内存规范。它指定 navigator.deviceMemory
属性 包含粗略的 order-of-magnitude 设备总内存估计值(以 GiB 为单位);此 API 仅适用于通过 HTTPS 服务的站点。这两个限制都是为了减少对客户端进行指纹识别的可能性,尤其是第三方。 (该规范还定义了一个“客户端提示”HTTP header,它允许直接在服务器端检查可用内存。)
但是,W3C Working Draft is dated September 2018, and while the Editor’s Draft is dated November 2020, the changes in that time span are limited to housekeeping and editorial fixups. So development on that front seems lukewarm at best. Also, it is currently only implemented in Chromium derivatives.
请记住:仅仅因为客户端确实有一定数量的内存,并不意味着它可供你使用。也许还有其他目的,他们想使用它。知道存在大量内存并不意味着可以完全使用它直到排除其他人。此 API 的最佳用途可能与问题中指定的用途类似:检测我们要发送的数据是否太大而客户端无法处理。
使用performance.memory.usedJSHeapSize
。虽然它是非标准的并且正在开发中,但它足以测试所使用的内存。您可以在 edge/chrome/opera 上试用它,但不幸的是不能在 firefox 或 safari 上试用(截至撰写本文时)。
属性 (performance.memory
)
jsHeapSizeLimit
:上下文可用的堆的最大大小(以字节为单位)。
totalJSHeapSize
:分配的总堆大小,以字节为单位。
usedJSHeapSize
: 当前活跃的JS堆段,以字节为单位。
阅读更多关于 performance.memory
的信息:https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory。
CanIUse.com: https://caniuse.com/mdn-api_performance_memory
CanIUse.com 2020/01/22
我 运行 前一段时间正好遇到这个问题(JSON table 的非分页渲染,因为我们不能使用分页,因为 :-( ),但问题比你描述的还要严重:
- 客户端有8GB内存并不代表浏览器可以使用内存。
- 通用设备上的任何“可用内存”报告最终都是虚假的(有多少用作缓存和缓冲区?)。
- 即使确切知道“Javascript 有多少内存可用”也会导致维护噩梦,因为 t运行slation 公式从 可用内存 到可显示行涉及未知的“单行内存大小”,并且在平台、浏览器和版本之间变量。
经过一番激烈的讨论,我和我的同事一致认为这是一个 XY 问题。我们不想知道客户端有多少内存,我们想知道 它可以合理安全地显示多少 table 行 .
我们 运行 的一些测试 - 但这是在大流行之前的几个月或三个月,所以 2019 年 9 月,情况可能已经改变 - 显示了以下有趣的效果:如果我们在屏幕外渲染, client-side,一个table同行,重复,和运行dom数据,并计时添加每行需要多长时间,这个时间大致与设备性能和限制相关,并且允许对我们可以显示的允许的实际行数进行合理估计。
我试图根据我的记忆重新实现一个非常粗略的此类测试,它 运行 沿着这些路线并且它 运行 通过登录时的 AJAX 调用发送了结果:
var tr = $('<tr><td>...several columns...</td></tr>')
$('body').empty();
$('body').html('<table id="foo">');
var foo = $('#foo');
var s = Date.now();
for (i = 0; i < 500; i++) {
var t = Date.now();
// Limit total runtime to, say, 3 seconds
if ((t - s) > 3000) {
break;
}
for (j = 0; j < 100; j++) {
foo.append(tr.clone());
}
var dt = Date.now() - t;
// We are interested in when dt exceeds a given guard time
if (0 == (i % 50)) { console.debug(i, dt) };
}
// We are also interested in the maximum attained value
console.debug(i*j);
以上是对更复杂的测试装置的重新创建(它被分配给了我的一个朋友,我不知道最初讨论后的细节)。在 Windows 10 上的 Firefox 上,我注意到 dt 呈线性增长,在 i=450 左右显着增加(我必须增加运行时间才能达到该值;我使用的笔记本电脑是一台胖 Precision M6800) . that 后大约一秒钟,Firefox 警告我脚本正在减慢机器速度(这确实是我们在将 JSON 数据发送到客户)。我确实记得曲线的“肘部”是我们最终使用的参数。
实际上,如果整体 i*j 足够高(测试以所有行结束),我们知道我们不必担心;如果它较低(测试因超时而终止),但没有“肘部”,我们会显示警告并提供继续选项;低于某个阈值或者如果“dt”超过了保护限制,甚至在超时之前诊断就停止了,我们只是告诉客户它无法完成,并下载 PDF 格式的综合报告。
您可能想要使用 IndexedDB API together with the Storage API:
使用 navigator.storage.estimate().then((storage) => console.log(storage))
您可以估计浏览器允许站点使用的可用存储空间。然后,您可以决定是将数据存储在 IndexedDB 中,还是提示存储空间不足的用户下载样本。
void async function() {
try {
let storage = await navigator.storage.estimate();
print(`Available: ${storage.quota/(1024*1024)}MiB`);
} catch(e) {
print(`Error: ${e}`);
}
}();
function print(t) {
document.body.appendChild(document.createTextNode(
t
));
}
(此代码段在此代码段上下文中可能不起作用。您可能需要 运行 在本地测试服务器上执行此操作)
广泛的浏览器支持
- IndexedDB 将来可用:All browsers except Opera
- 存储 API 将在未来可用,但有例外:All browsers except Apple and IE
我只是在编一个场景,假设我有一个 500MB 的文件,我想提供一个 html table 供客户端查看数据。假设有两种情况:
- 他们正在通过具有 1.2GB 可用内存的桌面查看它。他们可以下载整个文件。
- 稍后,他们尝试在 phone 上查看相同的 table。我们检测到他们只有 27MB 的可用内存,因此向他们发出警告:“我们检测到您的设备没有足够的内存来查看整个 table。您想下载一个示例吗?”
忽略诸如分页或虚拟 tables 之类的东西,我只关心“完整数据集是否适合用户的可用内存”。这是否可以在浏览器中检测到(即使有用户的确认)。如果是这样,如何做到这一点?
更新
这个答案大约是 6 年前的答案,the question 指向 10 年前的答案。我想知道当前状态是什么,因为从那时起浏览器已经发生了很大变化,而且还有 webassembly 等。
有点。
截至撰写本文时,正在开发设备内存规范。它指定 navigator.deviceMemory
属性 包含粗略的 order-of-magnitude 设备总内存估计值(以 GiB 为单位);此 API 仅适用于通过 HTTPS 服务的站点。这两个限制都是为了减少对客户端进行指纹识别的可能性,尤其是第三方。 (该规范还定义了一个“客户端提示”HTTP header,它允许直接在服务器端检查可用内存。)
但是,W3C Working Draft is dated September 2018, and while the Editor’s Draft is dated November 2020, the changes in that time span are limited to housekeeping and editorial fixups. So development on that front seems lukewarm at best. Also, it is currently only implemented in Chromium derivatives.
请记住:仅仅因为客户端确实有一定数量的内存,并不意味着它可供你使用。也许还有其他目的,他们想使用它。知道存在大量内存并不意味着可以完全使用它直到排除其他人。此 API 的最佳用途可能与问题中指定的用途类似:检测我们要发送的数据是否太大而客户端无法处理。
使用performance.memory.usedJSHeapSize
。虽然它是非标准的并且正在开发中,但它足以测试所使用的内存。您可以在 edge/chrome/opera 上试用它,但不幸的是不能在 firefox 或 safari 上试用(截至撰写本文时)。
属性 (performance.memory
)
jsHeapSizeLimit
:上下文可用的堆的最大大小(以字节为单位)。
totalJSHeapSize
:分配的总堆大小,以字节为单位。
usedJSHeapSize
: 当前活跃的JS堆段,以字节为单位。
阅读更多关于 performance.memory
的信息:https://developer.mozilla.org/en-US/docs/Web/API/Performance/memory。
CanIUse.com: https://caniuse.com/mdn-api_performance_memory
CanIUse.com 2020/01/22
我 运行 前一段时间正好遇到这个问题(JSON table 的非分页渲染,因为我们不能使用分页,因为 :-( ),但问题比你描述的还要严重:
- 客户端有8GB内存并不代表浏览器可以使用内存。
- 通用设备上的任何“可用内存”报告最终都是虚假的(有多少用作缓存和缓冲区?)。
- 即使确切知道“Javascript 有多少内存可用”也会导致维护噩梦,因为 t运行slation 公式从 可用内存 到可显示行涉及未知的“单行内存大小”,并且在平台、浏览器和版本之间变量。
经过一番激烈的讨论,我和我的同事一致认为这是一个 XY 问题。我们不想知道客户端有多少内存,我们想知道 它可以合理安全地显示多少 table 行 .
我们 运行 的一些测试 - 但这是在大流行之前的几个月或三个月,所以 2019 年 9 月,情况可能已经改变 - 显示了以下有趣的效果:如果我们在屏幕外渲染, client-side,一个table同行,重复,和运行dom数据,并计时添加每行需要多长时间,这个时间大致与设备性能和限制相关,并且允许对我们可以显示的允许的实际行数进行合理估计。
我试图根据我的记忆重新实现一个非常粗略的此类测试,它 运行 沿着这些路线并且它 运行 通过登录时的 AJAX 调用发送了结果:
var tr = $('<tr><td>...several columns...</td></tr>')
$('body').empty();
$('body').html('<table id="foo">');
var foo = $('#foo');
var s = Date.now();
for (i = 0; i < 500; i++) {
var t = Date.now();
// Limit total runtime to, say, 3 seconds
if ((t - s) > 3000) {
break;
}
for (j = 0; j < 100; j++) {
foo.append(tr.clone());
}
var dt = Date.now() - t;
// We are interested in when dt exceeds a given guard time
if (0 == (i % 50)) { console.debug(i, dt) };
}
// We are also interested in the maximum attained value
console.debug(i*j);
以上是对更复杂的测试装置的重新创建(它被分配给了我的一个朋友,我不知道最初讨论后的细节)。在 Windows 10 上的 Firefox 上,我注意到 dt 呈线性增长,在 i=450 左右显着增加(我必须增加运行时间才能达到该值;我使用的笔记本电脑是一台胖 Precision M6800) . that 后大约一秒钟,Firefox 警告我脚本正在减慢机器速度(这确实是我们在将 JSON 数据发送到客户)。我确实记得曲线的“肘部”是我们最终使用的参数。
实际上,如果整体 i*j 足够高(测试以所有行结束),我们知道我们不必担心;如果它较低(测试因超时而终止),但没有“肘部”,我们会显示警告并提供继续选项;低于某个阈值或者如果“dt”超过了保护限制,甚至在超时之前诊断就停止了,我们只是告诉客户它无法完成,并下载 PDF 格式的综合报告。
您可能想要使用 IndexedDB API together with the Storage API:
使用 navigator.storage.estimate().then((storage) => console.log(storage))
您可以估计浏览器允许站点使用的可用存储空间。然后,您可以决定是将数据存储在 IndexedDB 中,还是提示存储空间不足的用户下载样本。
void async function() {
try {
let storage = await navigator.storage.estimate();
print(`Available: ${storage.quota/(1024*1024)}MiB`);
} catch(e) {
print(`Error: ${e}`);
}
}();
function print(t) {
document.body.appendChild(document.createTextNode(
t
));
}
(此代码段在此代码段上下文中可能不起作用。您可能需要 运行 在本地测试服务器上执行此操作)
广泛的浏览器支持
- IndexedDB 将来可用:All browsers except Opera
- 存储 API 将在未来可用,但有例外:All browsers except Apple and IE