feature image

2021年3月17日 | ブログ記事

ブログを10倍速にした【新歓ブログリレー2021 9日目】

この記事は新歓ブログリレー2021の9日目(3/17)の記事です。
また、SysAdTechBlogの第二回目の記事です。

こんにちは、19のSysAd班の翠(sappi_red)です。

ブログ、そうです、この今見ているブログです。
このブログのレスポンスが返ってくる時間を10分の1にする改善をしました。

技術

このブログではGhostというNode.js製のCMSを利用しています。

WordPressからGhostへ乗り換えました
🎃🎃🎃 HAPPY HALLOWEEN! 🎃🎃🎃 traP鯖管の@kaz [/author/kaz]です。 traPメンバーブログは10月なのにもうAdventCalendar企画中!今日はボクの担当日……でもなんでもないのですが、殴り込みで参加します。AdventCalendar 9日目の記事です。 -------------------------------------------------------------------------------- 今日は待ちに待ったハロウィン!ということでハロウィンっぽい名前のBlogging Platfromである …

実際にページが表示されるためには、以下のような流れで動作します。

  1. Node.jsでアクセスされたパスに対応するテンプレートを解釈する
  2. テンプレートで利用している情報をDB(MySQL)からデータを取得する
  3. 取得したデータをテンプレートに合うようにHTMLにして返す

Handlebarsというテンプレートエンジンによってテンプレートが解釈・実行されています。

調査

2021-02-07 23:59:43	
[2021-02-07 14:59:43] WARN {{#get}} helper took 234ms to complete

調査というほどではないのですが、ログにこのようなwarningが出力されていました。
この{{#get}}というのはテンプレート内でAPIを利用する場合に利用する記法です。
APIの取得はサーバー側で実行されて、レスポンスのHTMLに反映されます。
実際にレスポンスが返るのに300ms程度かかっていて、230ms程度をこれにかけているということは大半の時間がここにかかえているということなので、これを改善することにしました。

改善方法

こんな関数でレスポンスを返す箇所をくるみました

const cachedResults = {};

function returnCacheAndStartRefetch(key, fetchData) {
    const cache = cachedResults[key];

    if (cache) {
        if (!cache.isFetching) {
            cache.isFetching = true;
            const promise = fetchData();
            promise.then(function () {
                cache.promise = promise;
                cache.isFetching = false;
            });
        }
        return cache.promise;
    }

    const promise = fetchData();
    cachedResults[key] = {
        isFetching: true,
        promise: promise
    };

    promise.then(function () {
        cachedResults[key].isFetching = false;
    });

    return promise;
}

実際の改善したコミット

やってることとしては、

といった感じです。また、取得中の場合はその取得が完了するのを待ちます。

Cache-Controlヘッダのstale-while-revalidateの挙動に近いものですね。

前回取得がいくら前だとしても一度はキャッシュを返す挙動になっているので、前回取得が一定期間より前だった場合は待ってから返すようにするべきという点は要改善です。

結果

blog_response
これはSysAd班が部内サービスの監視に使っているgrafanaでのグラフですが、改善前が300ms程度だったのが30ms程度になっています。
実際に手元からトップページを開いたときの.htmlのレスポンスも同じくらいの時間でした。
.htmlのレスポンスが速くなると.js.cssのダウンロードの開始も早くなるので得られた結果はそこそこ大きいと思います。


明日は @Rozelin さんの記事です。お楽しみに!

sappi_red icon
この記事を書いた人
sappi_red

19B/22M。SysAd班。 JavaScript書いたりTypeScript書いたりGo書いたりRust書いたり…

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2021年3月19日
traPグラフィック班の活動紹介
NABE icon NABE
2021年4月2日
DXライブラリで重力パズルゲームを作る
Macky1_2 icon Macky1_2
2022年4月5日
アーキテクチャとディレクトリ構造
mazrean icon mazrean
2021年5月16日
CPCTFを支えたインフラ
mazrean icon mazrean
2023年12月24日
2024年はSolid.jsを使いませんか?【部内PaaS基盤 NeoShowcase フロント開発ログ】
d_etteiu8383 icon d_etteiu8383
2023年4月24日
traQを直すまで
noc7t icon noc7t
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記