• このエントリーをはてなブックマークに追加


メモ

※ 「drop イベント云々」というよりは「DataTransfer#files が」という方が正しいですかね.

Dropzone.js を用いた,ローカルファイルをブラウザにドロップすることによるファイルアップロード機能の実装を試していて,Firefox と Chrome とで,その挙動の時間にあまりに差があったので,ちょっと確認.

気になる個所

Dropzone.js のソースコードを読んでたりした結果,Dropzone#drop での e.transferData.files の部分が怪しいのではないかということに.

ごく簡単な確認

drop イベントハンドラ内で DragEvent#transferData.files を呼び出す前後の時刻差を計算してみる.これが,ドロップするファイル数に対してどのように変化するのか.

マシン

  • MacBook Pro 15-inch, Late 2011
  • プロセッサ 2.5 GHz Intel Core i7
  • メモリ 16 GB 1333 MHz DDR3
  • ソフトウェア OS X 10.9.4(13E28)

古い.

ブラウザ

  • Firefox 32
  • Chrome 37

準備したファイル

  • 2500 点の JPEG ファイル
  • 5.5GB (2.25MB / ファイル)

コード

まっさらから準備するのがメンドウだったので,実装中のアプリケーションに対して,Dropzone#drop を上書きして上記の処理を行うだけにするなどして環境を準備:

class DZX extends Dropzone
    drop: (ev) ->
        [t1, t2] = [(new Date()).getTime(), null]
 
        files = ev.dataTransfer.files   # (A)
 
        t2 = (new Date()).getTime()
        result = (t2 - t1) / 1000
        console.log result
 
class DZModel
    dz: null
    constructor: (args) ->
        {target} = args
        dz_opts =
            url:                   'foobar'
            createImageThumbnails: false
            autoProcessQueue:      false
            autoQueue:             false
        @dz = new DZX(target, dz_opts)
 
window.onload = () ->
    new DZModel(target: '#dzmodel')

この状態でリロードしてはファイルをドロップしては...を繰り返す原始的な方法.特定のファイル数につき一度ずつしか計測していません.

結果

グラフについて,横軸がファイル数,縦軸が処理前後の「時刻差」(単位は「秒」).

A

ss-1410892971

Chrome は常にほぼ 0 なのにたいして,Firefox ではファイル数の増加に伴い指数関数的に処理時間が増加しているように伺える.

B

意味があるのかどうかわからないけど,先のコードの (A) の部分を「代入しない」形にしてみる.

        ev.dataTransfer.files   # (B)
ss-1410893217

A の場合と変わりはないみたい.

C

Event#dataTransfer にだけアクセスしてみた場合:

        ev.dataTransfer   # (C)
ss-1410894391

Firefox,Chrome 両者ファイル数に関係なくほぼ 0.

TSV データ

上記 A 〜 C の TSV データ:

まとめ

Firefox では,DataTransfer#files の参照処理時間が,ファイル数に対して指数関数的に増大する傾向にあるのではないか,という気がする.

実装するアップロード機能,最低 5000 ファイルくらいのドロップには対応できるようにしたいところだけど,Dropzone.js の問題でもなさげだしどうしたものかなぁ...