我有一个Web应用程序,允许用户上传DICOM和非DICOM文件。我使用JavaScript,HTML5,Webkitdirectory和Datatable来填充UI上的选定文件。我面临的问题是 -
如果该文件夹包含超过768个DCM文件(准确地说),则边缘浏览器会冻结,并且用户无法执行任何操作,直到用户点击“恢复此页面”按钮。 DCM文件的大小和数字研究无关紧要。
很少有观察到:
- 阅读1
总研究数量:4,DCM文件总数:768,文件夹总大小:~500 MB,在UI上显示的时间:40秒
- 阅读2
总研究数量:5,DCM文件总数:769,文件夹总大小:~500 MB,在UI上显示的时间:浏览器冻结
- 阅读3
总研究数量:2,DCM文件总数:768,文件夹总大小:~30 MB,在UI上显示的时间:40秒
- 阅读4
总研究数量:3,DCM文件总数:769,文件夹总大小:~30 MB,在UI上显示的时间:浏览器冻结。
注意:这项工作就像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);
分析:
我相信这可能是由于浏览器内存或函数调用堆栈,因为
readAsArrayBuffer
一旦完成读取就会生成onload事件。
任何解决方法或任何想法,如果这是MS Edge浏览器本身的问题?
我很好奇你的_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)
}
}
另一个最好的事情可能是将其移动到Web worker并将文件postMessage到它
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))