慢HTML5文件上传?

时间:2013-09-26 14:02:58

标签: javascript html html5 file-upload filereader

我将VERSION1:标准html文件上传与VERSION2进行了比较:html5 fileApi和ajax upload。事实证明,html5 fileApi和ajax上传比旧的html文件上传慢得多。

  1. 为什么版本2中的上传速度比版本1慢?
  2. 如何加快版本2的上传速度?
  3. VERSION1:

    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()
    

    VERSION2:

    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只包装文件阅读器api for jquery)我将上传的图像加载到html5画布中,因为我需要在上传之前操作图像。

    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的计时器。

    注意:与画布相关的代码不包含在时间中。我在测量之后开始了。

    结果:

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

1 个答案:

答案 0 :(得分:1)

版本2 Base64对toDataUrl()中的数据进行编码。这将是通过线路发送的大量数据,而不是版本1,它只是发送原始二进制文件。要看到这一点,请使用Fiddler观察HTTP流量并比较两者。 “统计信息”选项卡将显示“发送的字节数”,我认为将更多地使用您的第2版方法。测量时,请注意启动和停止计时器的位置。我知道你在评论中说你排除了画布工作,但除非你在之后测量 toDataUrl()直到完全触发,否则它不是网络时间的“公平”比较。简而言之,它的速度较慢,因为a)你发送的数据更多,而b)toDataUrl必须将图像从画布复制到表格。

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

根据您在画布和服务器资源中所做的工作,在服务器上执行图像处理可能更有意义。这肯定会使上传更快,代价是服务器CPU和内存。