私は、EvaporateJSを使用して大規模なファイルをマルチパートアップロードを使用してAmazon S3にアップロードするWebアプリケーションを構築しています。新しいチャンクが開始されるたびにブラウザが約2秒間フリーズするという問題に気づいた。アップロードが進行中にユーザーが自分のアプリを使い続けることができるようにしたいと思っています。このフリーズはそのことを悪い経験にしています。ChromeのワーカーブロッキングUIスレッド
私はChromeのタイムラインを使用して、これを引き起こしていたことを調べ、SparkMD5のハッシュであることを確認しました。そこで、アップロードプロセス全体をWorkerに移しました。問題を解決すると思っていました。
問題は現在、EdgeとFirefoxでは修正されていますが、Chromeではまったく同じ問題があります。あなたが見ることができるように、フリーズ中に私のメインスレッドがその時に実行されるJavaScriptの<速度8msで、基本的に何もしていない
:
は、ここに私のタイムラインのスクリーンショットです。すべての作業は私のワーカースレッドで発生していて、それは〜600ms程度しか実行されておらず、私のフレームがとる1386msではありません。
私は実際に何が問題を引き起こしているのかよく分かりません。私が気づくべきである労働者との間に問題がありますか?それはAWS公開鍵、AWSバケット名とAWSリージョン、AWSのオブジェクトキーと入力Fileオブジェクトでそれを提供するために、呼び出し元のスレッドに依存していることを
var window = self; // For Worker-unaware scripts
// Shim to make Evaporate work in a Worker
var document = {
createElement: function() {
var href = undefined;
var elm = {
set href(url) {
var obj = new URL(url);
elm.protocol = obj.protocol;
elm.hostname = obj.hostname;
elm.pathname = obj.pathname;
elm.port = obj.port;
elm.search = obj.search;
elm.hash = obj.hash;
elm.host = obj.host;
href = url;
},
get href() {
return href;
},
protocol: undefined,
hostname: undefined,
pathname: undefined,
port: undefined,
search: undefined,
hash: undefined,
host: undefined
};
return elm;
}
};
importScripts("/lib/sha256/sha256.min.js");
importScripts("/lib/spark-md5/spark-md5.min.js");
importScripts("/lib/url-parse/url-parse.js");
importScripts("/lib/xmldom/xmldom.js");
importScripts("/lib/evaporate/evaporate.js");
DOMParser = self.xmldom.DOMParser;
var defaultConfig = {
computeContentMd5: true,
cryptoMd5Method: function (data) { return btoa(SparkMD5.ArrayBuffer.hash(data, true)); },
cryptoHexEncodedHash256: sha256,
awsSignatureVersion: "4",
awsRegion: undefined,
aws_url: "https://s3-ap-southeast-2.amazonaws.com",
aws_key: undefined,
customAuthMethod: function(signParams, signHeaders, stringToSign, timestamp, awsRequest) {
return new Promise(function(resolve, reject) {
var signingRequestId = currentSigningRequestId++;
postMessage(["signingRequest", signingRequestId, signParams.videoId, timestamp, awsRequest.signer.canonicalRequest()]);
queuedSigningRequests[signingRequestId] = function(signature) {
queuedSigningRequests[signingRequestId] = undefined;
if(signature) {
resolve(signature);
} else {
reject();
}
}
});
},
//logging: false,
bucket: undefined,
allowS3ExistenceOptimization: false,
maxConcurrentParts: 5
}
var currentSigningRequestId = 0;
var queuedSigningRequests = [];
var e = undefined;
var filekey = undefined;
onmessage = function(e) {
var messageType = e.data[0];
switch(messageType) {
case "init":
var globalConfig = {};
for(var k in defaultConfig) {
globalConfig[k] = defaultConfig[k];
}
for(var k in e.data[1]) {
globalConfig[k] = e.data[1][k];
}
var uploadConfig = e.data[2];
Evaporate.create(globalConfig).then(function(evaporate) {
var e = evaporate;
filekey = globalConfig.bucket + "/" + uploadConfig.name;
uploadConfig.progress = function(p, stats) {
postMessage(["progress", p, stats]);
};
uploadConfig.complete = function(xhr, awsObjectKey, stats) {
postMessage(["complete", xhr, awsObjectKey, stats]);
}
uploadConfig.info = function(msg) {
postMessage(["info", msg]);
}
uploadConfig.warn = function(msg) {
postMessage(["warn", msg]);
}
uploadConfig.error = function(msg) {
postMessage(["error", msg]);
}
e.add(uploadConfig);
});
break;
case "pause":
e.pause(filekey);
break;
case "resume":
e.resume(filekey);
break;
case "cancel":
e.cancel(filekey);
break;
case "signature":
var signingRequestId = e.data[1];
var signature = e.data[2];
queuedSigningRequests[signingRequestId](signature);
break;
}
}
注:ここでは
は私の労働者のためのコードですこれらはすべて「init」メッセージで提供されます。署名されたものが必要な場合、親スレッドに「signingRequest」メッセージを送信します。このメッセージは、APIの署名エンドポイントからフェッチされた「署名」メッセージに署名を提供することが期待されます。
これはまったく役に立ちますか? https://github.com/TTLabs/EvaporateJS/issues/257 – user650881
私はEvaporateJSのオーバーヘッドを認識しており、パフォーマンス上の問題が発生していました。これがワーカースレッドを使用した理由です。私の質問は、たとえすべての作業がワーカーで起きていてもUIスレッドがまだフリーズしている理由です。 –
好奇心で、これを解決しましたか? – tony19