🍡
AWS SDK for JavaScript v2 の方が小さかった話
はじめに
きっかけは以下のブログ
AWS SDK for JavaScript in the Browser用のSDK Builderができました! | DevelopersIO
2015 年の記事なので、今は v3 使えばファイルサイズ気にすることないよなぁと 2 つのバージョンで作り比べてみたところ v2 の方が小さかったというお話。
AWS SDK for JavaScript には、v2 と v3 という 2 つのバージョンがあり、v3 ではサービスごとに個別のパッケージを使用できるようになっています。
そのため、v2 と比べて v3 の方がファイルサイズの削減ができると説明されています。
結果
Parcel を使用してビルドした結果、v3 のサイズが v2 のほぼ 3 倍に。。。
version | file | size | misc |
---|---|---|---|
v2 | main.js + aws-sdk.min.js | 356.1KB | 2.1KB + 354KB |
v3 | main.js | 1.1MB |
考察
- v3 でモジュール化されたが、TypeScript をトランスパイルする関係で個々のモジュール自体のサイスは大きくなってしまった?
- サンプルが簡易過ぎ?
-
Build your own AWS SDK for JavaScript で使用するサービスのみ選択するのは反則?
ちなみに上記サイトで、Select default services
を選択した場合のファイルサイズは2MB、Select all services
を選択した場合、ファイルサイズは 5.5MB になるので、v3 の方が小さくなるという説明は間違いではない 😅
まとめ
今のとこ、ブラウザに限れば、v2 + Build your own AWS SDK for JavaScript を使用した方がファイルサイズ的に優位に立てそう。
やったこと
以下、「ブラウザから Amazon S3 に写真をアップロード」を参考に、ブログ に書かれている仕様を実装してみた。
SDK v2, v3 共通
ディレクトリ構成
├── package.json
└── src
├── index.html
└── js
├── aws-sdk.min.js (SDK v2 版のみ)
├── env.js
└── main.js
index.html
index.hgml
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>S3へアップロードサンプル</title>
<!-- <script src="./js/aws-sdk.min.js"></script> SDK v2 版のみ -->
<script src="./js/main.js"></script>
</head>
<body>
<h1 id="heading">S3へアップロードサンプル</h1>
<form method="post" action="#" class="">
<input type="file" id="uploader" accept="image/*"><br>
<hr>
<input type="button" id="submit" value="送信">
</form>
</body>
</html>
env.js
js/env.js
export const S3_BUCKET_NAME = 'アップロードするバケット名';
export const S3_REGION = 'バケットのリージョン';
export const IDENTITY_POOL_ID = 'Cognito ID プールの ID';
package.json 共通部分
package.json
{
"private": true,
"main": "main.js",
"scripts": {
"build": "rimraf dist && parcel build --no-source-maps src/index.html",
"start": "parcel src/index.html"
},
"devDependencies": {
"autoprefixer": "^10.3.5",
"parcel-bundler": "^1.12.5",
"sass": "^1.42.1"
},
"browserslist": [
"since 2017-06"
]
}
以下、AWS 側での設定は出来てる想定
- S3 バケットの作成
- Amazon Cognito ID プールの作成
- IAM ロールのポリシー設定
- S3 の CORS 設定
SDK v2 版
使用するライブラリの準備
- Build your own AWS SDK for JavaScript にアクセス
- 以下のライブラリを選択してダウンロード
- AWS.CognitoIdentity
- AWS.S3
- ダウンロードしたファイルを、
aws-sdk.min.js
にリネーム
package.json と main.js
package.json
{
"dependencies": {
"env": "^0.0.2",
"env.js": "^0.1.0"
}
}
main.js
/* global AWS */
import { S3_BUCKET_NAME, S3_REGION, IDENTITY_POOL_ID } from './env.js';
AWS.config.update({
region: S3_REGION,
credentials: new AWS.CognitoIdentityCredentials({
IdentityPoolId: IDENTITY_POOL_ID,
}),
});
window.addEventListener('DOMContentLoaded', () => {
'use strict';
const btn = document.getElementById('submit');
btn.addEventListener(
'click',
async () => {
const files = document.getElementById('uploader').files;
if (!files.length) {
alert('ファイルを選択してください。');
return false;
}
const file = files[0];
const params = {
Bucket: S3_BUCKET_NAME,
Key: file.name,
ContentType: file.type,
Body: file,
};
try {
const upload = new AWS.S3.ManagedUpload({ params });
const data = await upload.promise();
console.log(data);
} catch (err) {
console.log(err);
}
return false;
},
false
);
});
SDK v3 版
package.json と main.js
package.json
{
"dependencies": {
"@aws-sdk/client-cognito-identity": "^3.34.0",
"@aws-sdk/client-s3": "^3.34.0",
"@aws-sdk/credential-provider-cognito-identity": "^3.34.0",
"env": "^0.0.2",
"env.js": "^0.1.0"
}
}
main.js
import { S3_BUCKET_NAME, S3_REGION, IDENTITY_POOL_ID } from './env.js';
const { CognitoIdentityClient } = require('@aws-sdk/client-cognito-identity');
const {
fromCognitoIdentityPool,
} = require('@aws-sdk/credential-provider-cognito-identity');
const { S3Client, PutObjectCommand } = require('@aws-sdk/client-s3');
const s3 = new S3Client({
region: S3_REGION,
credentials: fromCognitoIdentityPool({
client: new CognitoIdentityClient({ region: S3_REGION }),
identityPoolId: IDENTITY_POOL_ID,
}),
});
window.addEventListener('DOMContentLoaded', () => {
'use strict';
const upload = async (file) => {
const params = {
Bucket: S3_BUCKET_NAME,
Key: file.name,
Body: file,
};
try {
const data = await s3.send(new PutObjectCommand(params));
console.log(data);
} catch (err) {
console.log(err);
}
};
const btn = document.getElementById('submit');
btn.addEventListener(
'click',
() => {
const files = document.getElementById('uploader').files;
if (!files.length) {
alert('ファイルを選択してください。');
return false;
}
upload(files[0]);
return false;
},
false
);
});
Discussion