Javascript 在创建多个HTMLAudioElement DOM元素时,有没有办法不冻结UI
标题中的问题不言自明。我有这个网站,允许用户一次上传多个文件。然后它将遍历并检索每一个的持续时间Javascript 在创建多个HTMLAudioElement DOM元素时,有没有办法不冻结UI,javascript,web-audio-api,Javascript,Web Audio Api,标题中的问题不言自明。我有这个网站,允许用户一次上传多个文件。然后它将遍历并检索每一个的持续时间 getDuration(file) { return new Promise(resolve => { let reader = new FileReader(); reader.onload = e => { let audio = new Audio(); audio.onloadeddata =
getDuration(file) {
return new Promise(resolve => {
let reader = new FileReader();
reader.onload = e => {
let audio = new Audio();
audio.onloadeddata = () => {
this.duration = audio.duration;
resolve();
};
audio.src = e.target.result;
};
reader.readAsDataURL(file);
});
}
但是,至少在Chrome中,当用户界面进行所有处理时,它会非常糟糕地冻结用户界面。我是否可以避免这种情况,或者以不同的方式处理这种情况?您可以先不使用
文件读取器和data://uri
FileReader会将磁盘中的所有文件读取到内存中,其中包含大量文件,即大量IO,您的磁盘(HDD或SSD)将不喜欢它
然后从该文件创建data://URL不是免费操作,因此需要一些CPU时间。
最后,浏览器必须将该数据解码回原始二进制文件的URL,然后才能尝试将该数据解码为音频。这里再次出现了一些不必要的步骤,浪费了大量内存
相反,您可以简单地从用户发送的文件中创建一个blob://URL,并将
的src设置为该文件。这将是一个指向磁盘上实际文件的简单指针,因此浏览器将能够对其进行流式解码,并只在内存中追加所需的数据块
要创建这样一个blob://URL,必须使用URL.createobejctur()
方法
请注意,即使对于来自磁盘的文件来说,这并不是那么重要,但您应该养成在使用此类blob://URL后撤消此类blob://URL的好习惯,因为它们会阻止文件被垃圾收集
函数getDuration(文件){
返回新承诺(解决=>{
const audio=新音频();
audio.onloadedmetadata=()=>{
revokeObjectURL(文件)
解析(音频、持续时间);
};
audio.src=URL.createObjectURL(文件);
});
}
document.querySelector(“输入”).oninput=async(evt)=>{
log(等待getDuration(evt.target.files[0]);
}