3

VERSION1: 標準の html ファイルのアップロードと VERSION2: html5 fileApi および ajax のアップロードを比較しました。html5 fileApi と ajax のアップロードは、古い html ファイルのアップロードよりもはるかに遅いことがわかりました。

  1. バージョン 2 のアップロードがバージョン 1 よりもずっと遅いのはなぜですか?
  2. version2 でアップロードを高速化するにはどうすればよいですか?

バージョン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 ( jquery の filereader API をラップするだけのfilereader.jsを使用します) アップロードする前に画像を操作する必要があるため、アップロードした画像を 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())

これが私が測定したものです:

バージョン 1 とバージョン 2 の両方、および pinterest と flickr で 7.5 MB のサイズの jpg 画像をアップロードしました。フォームが送信された瞬間にクライアント側で画像が処理された後、バージョン 1 とバージョン 2 のタイマーを開始しました。

注: キャンバス関連のコードは時間に含まれません。この後、測定から始めました。

結果:

  • バージョン 1: 1.16 分
  • version2: 3.43 分
  • ピンタレスト: 1.09 分
  • フリッカー:1.11分
4

1 に答える 1

1

バージョン 2 Base64 は、toDataUrl() でデータをエンコードします。これは、生のバイナリを送信するだけのバージョン 1 よりも大量のデータが送信されることになります。これを確認するには、Fiddler を使用して HTTP トラフィックを監視し、2 つを比較します。[Statistics] タブには、'Bytes Sent'が表示されます。これは、バージョン 2 のアプローチでより多くなると思います。測定するときは、タイマーの開始位置と停止位置に注意してください。コメントでキャンバスの作業を除外すると言っていることは知っていますが、 toDataUrl() のから完全な発火までを測定していない限り、ネットワーク時間の「公正な」比較ではありません。つまり、a) より多くのデータを送信しており、b) toDataUrl がキャンバスからフォームに画像をコピーする必要があるため、処理が遅くなります。

高速化する方法に関しては、それを実行して機能を維持するのは少し難しいです。クライアントでより多くの作業を行っているため、必然的に遅くなります。私の知る限り、キャンバスにはデータを生のバイト(base64ではなく)としてサーバーにストリーミングする方法がありません。これはあなたが望むものです。jQuery File Upload は、少なくともよりユーザーフレンドリーにするのに役立つかもしれません。または、base64 以外の方法でデータを送信するための魔法があるかもしれません: https://github.com/blueimp/jQuery-File-Upload/ wiki/Client-side-Image-Resizing .

キャンバスとサーバー リソースで行っていることによっては、サーバー上で画像処理を行う方が理にかなっている場合があります。これにより、サーバーの CPU とメモリを犠牲にして、アップロードが確実に高速化されます。

于 2013-09-26T15:18:27.853 に答える