Electron+Vue3+Vite+Element-Plus,保持软后台全速运行(解决循环过多导致的界面不刷新问题,保证窗口失去焦点后setTimeOut可用)
问题描述
? 在开发时遇到的问题。我使用electron和vue建立的软件需要保证在后台能够全速运行,但在开发过程中遇到了一些问题,首先是对于几十万次甚至几百万次循环导致的界面卡死,无法刷新问题的解决;其次是浏览器内核使setTimeOut在窗口处于后台时,setTimeOut失效问题的解决。
问题一 大循环界面刷新不及时
? 第一次尝试使用js开发软件,软件需要处理几个、几十个甚至几百个拥有80万行的文本文件,循环次数到达了几百万次。
大循环解决
达夫设备
let arrayExample:string[] = [];
arrayExample.length = 10000;
arrayExample.fill('----------');
var len = arrayExample.length;
for (let i = 0; i < len; i++){
console.log(arrayExample[i])
}
const process = (i:number)=>{
console.log(arrayExample[i])
}
let startAt = len % 8,
iterations = Math.ceil(len/8),
j = 0;
do{
switch (startAt) {
case 0: process(j++);
case 7: process(j++);
case 6: process(j++);
case 5: process(j++);
case 4: process(j++);
case 3: process(j++);
case 2: process(j++);
case 1: process(j++);
}
startAt = 0;
} while (--iterations);
? 经过上述办法,循环的速度得到了改善,但是界面不刷新的问题依旧存在。
循环降速,保证刷新
? 如何做到循环速度的降低呢?
? 循环固定次数后暂停10ms?
? 我在代码中使用了一个sleep函数,并用async修饰了处理函数,得到的效果如下:
function sleep(i:number) {
return new Promise((resolve)={
setTimeout(resolve, i);
});
}
async function txtProcess(rootDirList:any) {
...
...
do {
await sleep(10);
switch (startAt) {
case 0: process(lineValue, j++);
...
}
}
}
? 经历了上面的改动,保证了界面的流畅刷新,但当我用控制台挡住运行界面时,发现软件的运行速度大大降低。
问题二 保证setTimeout的可用性
? 通过在网上的寻找,我在stackoverflow找到了问题的原因和解决办法。
方法来源地址:StackOverflow同时还有setInterval的解决办法。
原因:Most of the modern browsers (Chrome, Firefox and IE), intervals (window timers) are clamped to fire no more often than once per second in inactive tabs.
大多数现代浏览器(Chrome、Firefox 和 IE)、间隔(窗口计时器)都被限制为在非活动选项卡中每秒触发一次的频率不超过一次。
问题解决
? The Chromium insider also clarified that aggressive throttling will be automatically disabled for all background tabs “playing audio” as well as for any page where an “active websocket connection is present.”
对于所有“播放音频”的后台选项卡以及“存在活动的 websocket 连接”的任何页面,都会自动禁用激进的节流。
播放空声音会强制浏览器保留性能。
插件安装
npm i --save-dev howler
或者通过cnpm安装
cnpm i --save-dev howler
插件地址:Howler.js
使用
import {Howl, Howler} from 'howler';
const {Howl, Howler} = require('howler');
let sounds = new Howl({
src: ['empty_loop_for_js_performance.wav'],
volume:0.5,
autoplay: true, loop: true,
});
function performance_trick()
{
if(sounds.empty) return sounds.empty.play();
sounds.empty = new Howl({
src: ['empty_loop_for_js_performance.wav'],
volume:0.5,
autoplay: true, loop: true,
});
}
空白音源获取
empty_loop_for_js_performance.wav
|