Slide 1

Slide 1 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. T O R A N O A N A L a b 2024 Deno Deploy で Web Cache API を 使えるようになったので試した知見 2024/10/02 toranoana.deno #18 虎の穴ラボ株式会社 奥谷 一陽

Slide 2

Slide 2 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 自己紹介 奥谷 一陽 所属:虎の穴ラボ株式会社 興味:Deno、TypeScript 最近買ったもの:数字であそぼ 12巻 X:@okutann88 github:Octo8080X

Slide 3

Slide 3 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 アジェンダ - Deno Deploy で Web Cache APIを使える - Web Cache API ? - Deno の Web Cache API 実装状況 - Deno Deploy で Web Cache API こう使う

Slide 4

Slide 4 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API を使える


Slide 5

Slide 5 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API を使える


Slide 6

Slide 6 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache APIを使える - Deno Deploy で Web Cache API をベータサポート - Web Standard の Cache API と同様に、 リクエスト(または文字列)とレスポンスをペアを保存するストレージを提供 - 半永久的(少なくとも30日)キャッシュする - パフォーマンスの向上に使うことが期待される - ベータ期間中は無料。それ以降はDeno KVの費用の1/10程度が見込まれる

Slide 7

Slide 7 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache APIを使える 告知では、以下のような使い方が紹介されている。

Slide 8

Slide 8 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 で Web Cache API ? 
 


Slide 9

Slide 9 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Web Cache API ? - Web Cache APIは、Web standard のAPI - サービスワーカーで仕様定義されているが、サービスワーカーで使うことを強 制しない

Slide 10

Slide 10 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno の Web Cache API 実装状況 
 


Slide 11

Slide 11 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno の Web Cache API 実装状況 - Deno で実装のある Web Cache APIは3メソッド。 - put - match - delete

Slide 12

Slide 12 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno の Web Cache API 実装状況 - Deno で実装のあるWeb Cache APIには、ないものがある。 https://developer.mozilla.org/ja/docs/Web/API/Cache

Slide 13

Slide 13 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno の Web Cache API 実装状況 4メソッド無い - add - addAll - keys - matchAll 確認してから使うと、後から困ることを避けられる。 しかし、現在の実装でも使える場面は十分ある。

Slide 14

Slide 14 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API 
 こう使う


Slide 15

Slide 15 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API こう使う 前提 - Freshを使用し、背後の microCMS にコンテンツを保持する構成

Slide 16

Slide 16 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API こう使う 方針 - Cache 全体を消すために、 Keysでキー一覧を取得はできないので、 「キャッシュ名」で丸ごとキャッシュを切り替える - 「キャッシュ名」自体はDeno KVで保持する import { getCacheVersion } from "./kvStorage.ts"; export async function getWebCache() { return await caches.open(await getCacheVersion()); // cacheName from KV }

Slide 17

Slide 17 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API こう使う Deno KV で「キャッシュ名」 の発行と管理 - キャッシュキー - あれば返す - なければ発行 /// import { CONSTS } from "./consts.ts"; const WEB_CACHE_VERSION = "web-cache-version" as const; async function getKvStorage() { return await Deno.openKv(); } export async function getCacheVersion() { const kvStorage = await getKvStorage(); const version = await kvStorage.get([WEB_CACHE_VERSION]); if (!version.value) { console.log(`${WEB_CACHE_VERSION} not found`); const newVersion = crypto.randomUUID(); await setCacheVersion(newVersion); return newVersion; } console.log(`${WEB_CACHE_VERSION} found: ${version.value}`); return version.value; } export async function setCacheVersion(version: string) { const kvStorage = await getKvStorage(); return await kvStorage.set([WEB_CACHE_VERSION], version, { expireIn: CONSTS.microCms.contentsExpiresIn * 1000, }); }

Slide 18

Slide 18 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API こう使う import { FreshContext, PageProps } from "$fresh/server.ts"; import { Pagination } from "../components/Pagination.tsx"; import { CONSTS } from "../utils/consts.ts"; import { contentDigest, getNewsList, News } from "../utils/microcms.ts"; import { getWebCache } from "../utils/webCache.ts"; export const handler = { GET: async function (req: Request, ctx: FreshContext) { console.time("GET /"); const cache = await getWebCache(); const cached = await cache.match(req.url); if (cached) { console.log(`cache hit ${req.url}`); console.timeEnd("GET /"); return cached; } console.log(`cache miss ${req.url}`); const page = Number(ctx.url.searchParams.get("page")) || 1; const newsListRes = await getNewsList(page); if (!newsListRes.status) { return ctx.renderNotFound({}); } const res = await ctx.render({ newsList: newsListRes.contents, currentPage: page, totalCount: newsListRes.totalCount, }); res.headers.set( "Expires", new Date(Date.now() + CONSTS.microCms.contentsExpiresIn * 1000) .toUTCString(), ); await cache.put(req.url, res.clone()); console.timeEnd("GET /"); return res; }, }; キャッシュの引き当て レンダリング結果を キャッシュに設定

Slide 19

Slide 19 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 Deno Deploy で Web Cache API こう使う // import 省略 export const handler = { GET: async function (req: Request, _ctx: FreshContext) { const cache = await getWebCache(); const cached = await cache.match(req.url); if (cached) { console.log(`cache hit ${req.url}`); return cached; } console.log(`cache miss ${req.url}`); // 本来のURLに戻して、リソースを取得 const res = await fetch( resourceDomainConvertBack(new URL(req.url).pathname), ); const blob = await res.blob(); const newResponse = new Response(blob, { headers: { ...res.headers, "Expires": new Date(Date.now()      + CONSTS.microCms.contentsExpiresIn * 1000).toUTCString(), }, }); await cache.put(req.url, newResponse.clone()); return newResponse; }, }; micro CMSに置いた画像は、 リクエスト結果を そのままキャッシュする 結果をそのままキャッシュ

Slide 20

Slide 20 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 実際の動作 


Slide 21

Slide 21 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 動作確認 https://xocto8080x-fresh-micro.deno.dev/

Slide 22

Slide 22 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 パフォーマンスは上がったのか? - 未キャッシュ:600ms程度 - キャッシュ済:2~300ms程度(ローカル実行では10ms以下) => パフォーマンスは上がった

Slide 23

Slide 23 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 注意事項


Slide 24

Slide 24 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 キャッシュの有効期限 Deno.landのブログ記事によると - Cache-Controlヘッダー - Expires ヘッダー により有効期限が設定ができるとあるが、 「有効期限が来ても残っている」 ような挙動に見える const res = await ctx.render({ newsList: newsListRes.contents, currentPage: page, totalCount: newsListRes.totalCount, }); res.headers.set( "Expires", new Date(Date.now() + CONSTS.microCms.contentsExpiresIn * 1000) .toUTCString(), ); await cache.put(req.url, res.clone()); return res; }, };

Slide 25

Slide 25 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 キャッシュの有効期限 Deno.landのブログ記事によると - Cache-Controlヘッダー - Expires ヘッダー により有効期限が設定ができるとあるが、 「有効期限が来ても残っている」 ような挙動に見える Issue出したら、 「need investigation」(要調査) になったので、回答を待ちます。 https://github.com/denoland/deno/issues/25795

Slide 26

Slide 26 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 まとめ


Slide 27

Slide 27 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 まとめ - Deno Deployで Web Cache APIが使える - Web Cache API は リクエスト(および文字列)とレスポンスのペアを保存する - Deno には Web Cache APIの中で実装がないメソッドがある。 - 代替として、Deno KVで管理し、「キャッシュごと切り替える」戦略が取れる - 今回のケースでは、microCMS自体のレスポンスが十分早いので 感じにくい面はあるが、パフォーマンスは上がっている - より遅い、より容量の大きいものがレスポンスに関わる場合 より効果的であることが想像できる - 有効期限周りの挙動は、気をつけて検証する

Slide 28

Slide 28 text

Copyright (C) 2023 Toranoana Lab Inc. All Rights Reserved. 2024 ありがとうございました