我有一个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);
分析:
我认为这可能是由于浏览器内存或函数调用堆栈
readAsArrayBuffer
完成后将生成onload事件 阅读。
是否有任何解决方法或任何想法,如果这是MS Edge浏览器本身的问题?
答案 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)
}
}
另一个最好的办法是将其移动到网络工作者中,然后将消息发送到该消息中
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))