如果目录包含768个以上的文件,则Edge浏览器将在选择要上传的文件时冻结

时间:2018-08-29 08:22:58

标签: javascript webkit microsoft-edge

我有一个Web应用程序,允许用户上传DICOM和Non-DICOM文件。我正在使用JavaScript,HTML5,Webkitdirectory和Datatable填充UI上的选定文件。我面临的问题是-

如果该文件夹包含超过768个DCM文件(准确地说),则Edge浏览器将冻结,并且用户只有在用户点击“恢复此页”按钮后才能执行任何操作。 DCM文件的大小和数量研究并不重要。

  

很少观察到:

     
      
  • 阅读1
  •   
     

研究总数:4,DCM文件总数:768,总大小   文件夹的大小:〜500 MB,在UI上显示的时间:40秒

     
      
  • 阅读2
  •   
     

研究总数:5,DCM文件总数:769,总大小   文件夹的大小:〜500 MB,在用户界面上显示的时间:浏览器冻结

     
      
  • 阅读3
  •   
     

研究总数:2,DCM文件总数:768,总大小   文件夹的大小:〜30 MB,在UI上显示的时间:40秒

     
      
  • 阅读4
  •   
     

研究总数:3,DCM文件总数:769,总大小   文件夹的大小:〜30 MB,在用户界面上显示的时间:浏览器冻结

     

注意:此功能就像Chrome和Firefox中的超级按钮一样。

这是我对每个DICOM文件(Inside forEach)执行的代码-

var fileReader = new FileReader();
fileReader.onload = function(evt){
    console.log("Completed Reading");
    var arrayBuffer = fileReader.result;

    var byteArray = new Uint8Array(arrayBuffer);
    _parseDicom(byteArray);
    try {
        if (fileReader.readyState !== 2) {
            fileReader.abort();
        }
    }
    catch (err) {
        console.log('error occured: '+err);
    }
}
var blob = f.slice(0, 50000);
console.log("Starting to Read");
fileReader.readAsArrayBuffer(blob);

分析:

  • Edge浏览器在记录“ 开始阅读” 20-25次后冻结,而从未记录“ 完成阅读”。
  • 我试图检查浏览器是否有效运行,是否通过在读取文件子集后增加一些延迟来减轻浏览器的负担。 这样它就可以开始处理少量文件,并且用户可以看到一些进度。但这似乎也不符合预期。最终,此行为会影响在UI上呈现所有文件所需的总时间。
  • 我尝试查看DICOMDIR文件,但其中不包括我们在研究网格中显示的所有信息,例如身体部位,机构名称,转诊医师姓名以及图像UID,图像帧丢失。要获取这些信息,我们需要为每个研究分析每个DICOM文件以检索丢失的信息。m要读取文件,我们需要访问用户的文件系统以检索文件的完整路径。但是由于JavaScript,JQuery安全性原因,这是不可行的。
  

我认为这可能是由于浏览器内存或函数调用堆栈   readAsArrayBuffer完成后将生成onload事件   阅读。

是否有任何解决方法或任何想法,如果这是MS Edge浏览器本身的问题?

1 个答案:

答案 0 :(得分:1)

我在想您的_parseDicom剂量是多少...如果可以对其进行优化以检查其中是否有魔术数字来指示文件是否为DCM文件(我不知道DCM文件是什么)是)

也许您不应该在forEach循环中执行所有这些文件读取操作,因为这将并行读取所有文件,如果一次执行一个,则可以优化内存。

async function doWork(fileList) {
  for (const file of FileList) {
    const res = new Response(file.slice(0, 50000))
    const arrayBuffer = await res.arrayBuffer()
    const byteArray = new Uint8Array(arrayBuffer)
    _parseDicom(byteArray)
  }
}

如果您的_parseDicom可以接受流而不是字节数组,那么可能会更好一些

async function doWork(fileList) {
  for (const file of fileList) {
    const res = new Response(file.slice(0, 50000))
    const stream = res.body.getReader()
    await _parseDicom(stream)
  }
}

另一个最好的办法是将其移动到网络工作者中,然后将消息发送到该消息中

es5解决方案

function doWork(files) {
  var file = files.pop()
  file && new Response(file.slice(0, 50000)).arrayBuffer(function(arrayBuffer){
     var byteArray = new Uint8Array(arrayBuffer)
     _parseDicom(byteArray)
     doWork(files)
  })
}

doWork(Array.from(fileList))