Javascript 如何在隐藏选项卡中绕过设置超时限制?

Javascript 如何在隐藏选项卡中绕过设置超时限制?,javascript,webgl,Javascript,Webgl,我正在做一个繁重的科学ie,而不是显示数据webgl计算。Webgl不能放在一个worker中,而且做很多Webgl会阻塞整个浏览器,所以我将计算分块,在调用getError刷新opengl队列后,我在setTimeout函数中计算每个块。我在块之间留了一点时间,以便浏览器有时间刷新主UI队列中的一些UI事件,从而使整个过程感觉不那么缓慢 我的问题是,当选项卡被隐藏时,setTimeout被限制为1秒,这对我来说太慢了 有比我做的更好的解决方案吗?显然requestAnimationFrame不

我正在做一个繁重的科学ie,而不是显示数据webgl计算。Webgl不能放在一个worker中,而且做很多Webgl会阻塞整个浏览器,所以我将计算分块,在调用getError刷新opengl队列后,我在setTimeout函数中计算每个块。我在块之间留了一点时间,以便浏览器有时间刷新主UI队列中的一些UI事件,从而使整个过程感觉不那么缓慢

我的问题是,当选项卡被隐藏时,setTimeout被限制为1秒,这对我来说太慢了

有比我做的更好的解决方案吗?显然requestAnimationFrame不起作用,因为它从未在隐藏选项卡中调用,而且在可见选项卡中速度太慢

是否存在处于隐藏状态的非限制时间事件?我尝试使用window.postMessage,但仍然太快,整个浏览器感觉很慢

以下是我的研究现状:

            function drawTile(sequenceIndex) {
                if (sequenceIndex < sequence.length) {
                    var x = sequence[sequenceIndex][0];
                    var y = sequence[sequenceIndex][1];
                    setTilePos(x, y);
                    modelStage.render(renderer, modelBuffer);
                    minkowskiPass.render(renderer, minkowskiBuffer, modelBuffer);
                    copyPass.quad.position.x = x;
                    copyPass.quad.position.y = y;
                    copyPass.render(renderer, null, minkowskiBuffer);
                    var gl = renderer.getContext();
                    gl.getError();
                    sequenceIndex++;
                    if (document.visibilityState != "hidden") {
                        setTimeout(function () {
                            drawTile(sequenceIndex);
                        }, 10);
                    } else {
                        //window.postMessage is not rate limited then the tab is hidden
                        // we need to slow the computation by an event, otherwise the whole browser is unresponsive.
                        $(window).one('message', function () {
                            drawTile(sequenceIndex);
                        });
                        window.postMessage('lol', '*');
                    }
                } else
                    console.timeEnd('computation');
            }
            console.time('computation');
            drawTile(0);

也许有一个工作线程也运行一个
postMessage循环和每n次迭代的一小部分时间,暂停或恢复主线程?

这里有另一个复杂的解决方法,可供需要它的人使用;您可以使用Web Audio API生成函数调用:

var setTimeout2 = (function () {
    var samples = 2048;
    var fns = [];
    var context = new AudioContext();
    var source = context.createBufferSource();
    var node = context.createScriptProcessor(samples, 1, 1);

    // This gets fired every ~46 milliseconds. You can change 
    // `samples` to another valid value (256, 512, 1024, 2048,
    // 4096, 8192, or 16384); then it'll get called every 
    // `samples / context.sampleRate` seconds (~46 ms for 
    // `samples == 2048` and `context.sampleRate == 44100`).
    node.onaudioprocess = function (e) {
        fns = fns.filter(function (fn) {
            return !fn(Date.now() - fn.t);
        });
    };
    source.connect(node);
    node.connect(context.destination);
    window.do_not_garbage_collect = [context, source, node];

    return function (fn) {
        fn.t = Date.now();
        fns.push(fn);
    };
}());

// Use like this:
setTimeout2(function (t) {
    console.log(t);

    // End after 1 second.
    if (t > 1000)
        return true;  
})

我发现了一个复杂的解决方案,将setTimeout放在一个似乎不像主线程那样受速率限制的工作线程中。我仍然对一个更简单的系统持开放态度。您不能强制客户机进行计算。您的实际用例是什么?太慢意味着什么?我发布的代码直接来自我的应用程序,您还需要什么详细信息?我正在用webgl做一些几何变换。太慢意味着滴答声的速度不够快,这会减慢全局计算。你说你做的科学计算不应该用于显示。你在变换什么几何图形?你为什么不想在服务器端做呢?我不需要细节,我想了解整体情况。我使用了100%的客户端路由,存储在firebase上。我现在不想把服务器的钱花在那个项目上。即使使用服务器,当用户更改应用程序中的参数时,我至少需要实时预览。我的一位朋友也建议这样做。疯狂的头脑。