🍡

AWS SDK for JavaScript v2 の方が小さかった話

2021/09/26に公開

はじめに

きっかけは以下のブログ
AWS SDK for JavaScript in the Browser用のSDK Builderができました! | DevelopersIO

2015 年の記事なので、今は v3 使えばファイルサイズ気にすることないよなぁと 2 つのバージョンで作り比べてみたところ v2 の方が小さかったというお話。

AWS SDK for JavaScript には、v2v3 という 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 側での設定は出来てる想定
  1. S3 バケットの作成
  2. Amazon Cognito ID プールの作成
  3. IAM ロールのポリシー設定
  4. S3 の CORS 設定

SDK v2 版

使用するライブラリの準備

  1. Build your own AWS SDK for JavaScript にアクセス
  2. 以下のライブラリを選択してダウンロード
    • AWS.CognitoIdentity
    • AWS.S3
  3. ダウンロードしたファイルを、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