0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Firebase Cloud Functionsのレスポンス遅延に対応する with TypeScript

Posted at

firebase cloud functionsで処理速度を高めるための遅延ローディングをTypeScriptでやる際に、namespaceとかを使っているとやりにくかったのでメモ。

前提

TypeScriptでfirebase cloud functionsのコードを書いていて全体像はなんとなくこんな感じでした。

index.ts

import { Foo } from "./foo";

export const doBar = Foo .bar;
export const doBaz = Foo .baz;
foo.ts

export namespace Foo {
   export const bar = functions.firestore
     .document("barDocuments/{barId}")
     .onWrite(async (snapshot, context) => {
        // do something...
     });
   export const baz= functions.https.onCall((data, context) => {
        // do something...
     });
}

動作が遅くなる問題

ただ、実はこれでは関数実行時の速度が遅くなります。

functionsは一つの関数呼び出しに対して仮想インスタンスが一つ作られ、一定時間アクセスがないと削除されます。
インスタンスの作成時(関数の実行時?)にindex.js が読み込まれるわけですが、上のようにべた書きにすると実行しない関数のimportまでしてしまい、処理が遅くなります。

。。。といったことと解決策が https://tech.ginco.io/post/ginco-engineer-meetup-2018-cloud-functions/ に書いてあったので試してみたのですが、最初詰まりました。

サイトには process.env.FUNCTION_NAME に実行予定の関数名が入っていることを利用して遅延読み込みするべしと書いてあります。

if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === 'Func1') {
    const Foo= require('./foo');
    exports.bar = Foo.bar; 
}

ただ、これをTypeScriptでやろうとしたときに問題に遭遇しました。

TypeScriptで速度改善するときの問題と解決策

deploy時に関数が認識されない

configとかいじればいけるのか(?)もしれませんが、index.js では最終的に

exports.baz = functions.https.onCall((data, context) => {
        // do something...
     });

と評価されないとfunctionだと認識してくれないようで、サイトのマルパクではdeployできませんでした。

これは、いったん関数はexportしたうえで、中で process.env.FUNCTION_NAME を評価して解決します。

index.ts
export const doBar= functions.https.onCall((data, context) => {
  if (
    !process.env.FUNCTION_NAME ||
    process.env.FUNCTION_NAME === "doBar"
  ) {
    // ...
  }
  return null;
});

namespace使ってるときに遅延読み込み & トランスパイル後の動作保証どうやるの問題

遅延読み込みは

import("hoge").then(loaded => /* do something... */ );

でいけますが、namespace?

結局、いろいろやっていたら

import("@/foo").then(({ Foo }) =>
   Foo.bar(data, context)
);

でいけました。(勉強不足)

完成形

index.ts
export const doBar= functions.firestore
  .document("barDocuments/{barId}")
  .onWrite(async (snapshot, context) => {
     if (
        !process.env.FUNCTION_NAME ||
        process.env.FUNCTION_NAME === "doBar"
     ) {
        return import("@/foo").then(({ Foo }) =>
           Foo.bar(data, context)
        );
     }
     return null;
});

export const doBaz= functions.https.onCall((data, context) => {
     if (
        !process.env.FUNCTION_NAME ||
        process.env.FUNCTION_NAME === "doBaz"
      ) {
         return import("@/foo").then(({ Foo }) =>
           Foo.baz(data, context)
        );
      }
      return null;
});

その他

  • もちろん、これ以外にリージョンを東京にしたら早くなるとかあります。(ジェニさえ払えば速くなんでぇ)
  • そもそもインスタンスのスペックを256MBのままにしてるのが無理ゲーという話もあります(ジェニさえ...(略))

ちゃんと勉強します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?