javascript - HTML5 文件上传速度慢?

标签 javascript html file-upload filereader

我将版本 1:标准 html 文件上传与版本 2:html5 fileApi 和 ajax 上传进行了比较。结果发现html5的fileApi和ajax上传比老的html文件上传慢了很多。

  1. 为什么版本 2 的上传速度比版本 1 慢很多?
  2. 如何在版本 2 中加速上传?

版本 1:

HTML

<g:form method="post" accept-charset="utf-8" enctype="multipart/form-data"  
     name="imageUploaderForm" id="imageUploaderForm" url="someurl">

    <input type="file" accept="image/jpeg, image/gif, image/png" 
            name="image" id="image" />

</form>

JS(我用 JQueryForm )

$("#image").change(function() {

  $("#imageUploaderForm").ajaxForm({
    complete: function(response){
        console.log("upload complete");
    }
  });
  $("#imageUploaderForm").submit();

});

服务器代码 Grails 2.2.4:

CommonsMultipartFile file = (CommonsMultipartFile) request.getFile('image')
byte [] imageBytes = file.getBytes()

版本 2:

HTML

<g:form method="post" accept-charset="utf-8" enctype="multipart/form-data"  
         name="imageUploaderForm" id="imageUploaderForm" url="someurl"></form>

<input id="UploadFileInput" class="UploadFileInput" type="file" name="image" accept="image/jpeg, image/gif, image/png" />

JS(我使用 filereader.js,它只是包装了 jquery 的文件读取器 api)我将上传的图像加载到 html5 Canvas 中,因为我需要在上传之前操作图像。

var fileReaderOpts = {
        readAsDefault: 'BinaryString',
        on: {
            load: function(event, file) {

                var $img = $('<img>'), 
                    imgWidth, imgHeight;

                $img.load(function() {

                    // Create the canvas.
                    $originalCanvas = $('<canvas data-caman-hidpi-disabled>');
                    var originalContext = $originalCanvas[0].getContext('2d');  

                    // Save image to canvas
                    $originalCanvas[0].width = this.width;
                    $originalCanvas[0].height = this.height;
                    originalContext.drawImage(this, 0, 0);

                    // some image modification on the canvas

                    // send image to server

                    var imageUrl = $originalCanvas[0].toDataURL();

                    $("#imageUploaderForm").ajaxForm({
                        data: { 
                            img : imageUrl,
                        },
                        complete: function(response){
                                console.log("upload complete");
                        } 
                    }); 

                    $("#imageUploaderForm").submit();



                }); // end $img.load

                // Set the src of the img, which will trigger the load event when done
                $img.attr('src', event.target.result);


            },// end load           
            beforestart: function(file) {
                // Accept only images. Returning false will reject the file.
                return /^image/.test(file.type);
            }
        }
};


// Bind the fileReader plugin the upload input and the drop area.
$("UploadFileInput").fileReaderJS(fileReaderOpts);

服务器代码 Grails 2.2.4:

String imgBase64 = params.image
imgBase64 = imgBase64.trim().replaceFirst("data:image/png;base64,", "")
byte[] imageBytes = Base64.decode(imgBase64.getBytes())

这是我测量的结果:

我已经上传了一个 7.5MB 大小的 jpg 图片,包括版本 1 和版本 2,还有 pinterest 和 flickr。在提交表单时在客户端处理完图像后,我启动了版本 1 和版本 2 的计时器。

注意:canvas相关的代码不在时间之内。之后我开始测量。

结果:

  • 版本 1:1.16 分钟
  • 版本 2:3.43 分钟
  • pinterest:1.09 分钟
  • flickr:1.11 分钟

最佳答案

版本 2 Base64 对 toDataUrl() 中的数据进行编码。与仅发送原始二进制文件的版本 1 相比,这将是通过网络发送的更多数据。要看到这一点,请使用 Fiddler 观察 HTTP 流量并比较两者。 Statistics 选项卡将向您显示“已发送的字节数”,我认为在您的第 2 版方法中会更多。测量时,请小心开始和停止计时器的位置。我知道您在评论中说您排除了 Canvas 工作,但除非您是从 after toDataUrl() 直到完全触发进行测量,否则这不是网络时间的“公平”比较。简而言之,它变慢是因为 a) 您要发送更多数据,并且 b) toDataUrl 必须将图像从 Canvas 复制到表单。

至于如何使其更快,要做到这一点并保持您的功能有点棘手。你在客户端做更多的工作,所以它必然会变慢。 AFAIK, Canvas 没有办法将数据作为原始字节(不是 base64)流式传输到服务器,这正是您想要的。 jQuery File Upload 至少可以帮助它变得更加用户友好,或者可能有一些魔力我不清楚除了 base64 之外还可以通过某种方式发送数据:https://github.com/blueimp/jQuery-File-Upload/wiki/Client-side-Image-Resizing .

根据您在 Canvas 中所做的事情和您的服务器资源,在服务器上进行图像处理可能更有意义。这肯定会使上传速度更快,但会占用服务器 CPU 和内存。

关于javascript - HTML5 文件上传速度慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19030451/

相关文章:

javascript - 更新后重新加载 AJAX 加载的页面

html - 如何将旋转的元素居中并将其与顶部对齐?

javascript - 为什么我的 javascript onclick 不能与 div 一起使用?

php - PHP 中是否可以中断文件上传(使用 APC)?

javascript - 最好将图像文件作为数据 URI 或二进制形式数据从浏览器上传到服务器?

javascript - 如何在 javascript 中进行漂亮而简单的文件上传?

javascript - 使用 Angular 工厂中的参数进行自定义 header

javascript - Jquery Promise 主干提取

javascript - javascript中如何显示小数点后20位以上?

javascript - 未捕获的类型错误 : Cannot read property 'width' of undefined in JavaScript