tekitoumemo’s diary

思ったことを書くだけ。長文版Twitter

みんなの洋楽ランキングを超絶アップデートした

mygkrnk.com

長かった〜(3週間)

「いいね!した曲の一覧が見れるようにしよう」

とひょんなことから大規模リファクタした。マジ週5で働いて、子育てして夜中やるみたいな感じで超疲労

もうやるだけやった(迫真)

やったこと(フロントエンド)

webpackを3から4にバージョンアップ

これやらないといろいろあかん。(主にTypescript最新)。webpack4からUglifyEsPluginとか使わなくてもminify出来るのでかなりシンプルになったりといろいろ良くなったのでwebpackをゴリゴリに変更した。というのもASP.NET Core 2.1で Reactテンプレート使って作成したもののwebpackやらpackageやらいらないものが多すぎたので削ぎ落とさないとアップデートするのが大変だった。

typescript3.6.3から4.0.3、react 16.9.0から16.13.1へ

今まで地味〜にアップデートしていたのでそこまで苦労せず。

axios導入

ライブラリ使わずにFetch APIを使ってきたのだが、Jsonパースするのにいちいち面倒だったりと使い心地が悪いのでaxiosを導入。インタセプタを使うためってのが一番の理由。Fetch APIにもインタセプタあると思うけど、調べる必要性が感じられず。

redux導入

リアルタイムにいいね !のstateを描画したかったので、この際にredux入れるかぁって感じで導入。最近のトレンドでFluxを多用するのはどうなの?って風潮だし個人的にもそこは同意なので必要がなければ入れないつもりだったけど、1アプリにグローバルな状態は大体必要になる。
f:id:tekitoumemo:20201013221756g:plain

ESLint導入

prettierしか入れてなかったけど、どうせリファクタするなら入れるかと思い導入。typescriptにESLint入れるのはちょっと一手間。調べればいくらでも出てくるから良いけど、1から調べるのは仕事じゃなきゃやりたくないなぁ。

any撲滅

と言いながらもESLintルールに"@typescript-eslint/no-explicit-any": 0が入ってるんだけど(笑)。Typescript信者じゃないし、最近のトレンドについていくためだけに使ってるって感じもあるからルールで縛られなくても良いかなと思って無効化した。とカッコつけたものの、結局はリファクタに心折れたときに無意識に無効化してた(笑)。まぁ、1年振りぐらい見ると本当にわからないから知らない人が書いたコード見るなら型はあった方が良いなぁ〜と思った。過去の自分は他人だと感じた。

ちょっと拘った実装

検索フォームの遅延リクエス

入力する度にリクエストを投げるといろいろ死ぬので、入力完了を遅延させている。
f:id:tekitoumemo:20201015001432g:plain

一般的なテクニックとしてはスタックアルゴリズムで入力時にpush、setTimeoutでpopしていくって感じだけど、それを意識せずに使いたかったのでこんな感じで使えるようにした。結局はスタックを隠蔽して戻りをPromiseにしたってだけだが。300msは人間が入力完了する平均的な時間らしい。

<input onChange={onChange} />

const interval = 300 // ms
const input = new Input(interval)

onChange = async (e) => {
  if (await input.on()) {
    // 入力完了
  }
}
ローディング

f:id:tekitoumemo:20201015005004g:plain
今までは思考停止して

this.setState({ loading: true })
// 通信
this.setState({ loading: false })

って感じだったけどあまりにも冗長すぎるし何よりダサいのでちょっと真剣に考えた。上記のように通信ごとに括ってローディングを設定するのが嫌だったので以下のようにした

<Loading>
 // 通信後に表示されるJSX
</Loading>

インタセプタでリクエスト数をreduxで保持、終了したらデクリメント。リクエスト数 > 0であればローディング表示みたいな。
複数のコンポーネントでリクエストが送信されてると詰むので頭の中にある案を実装したかったがやりすぎ感が強いので困ったら考える。本当は最低何msローディングを表示させるかとかオプションあるけど割愛する。

renovate導入→廃止

どうせ動作確認しなきゃだし、いらんな。って感じで廃止。便利そうに見えて全く便利じゃなかった。

やったこと(バックエンド)

Roslynator導入

C#の静的解析はディファクトスタンダードなものがないので、CLIでも使えるRoslynatorを導入。
github.com

う〜〜〜〜ん。。macだとcliが全く使いもんにならん(多分Linuxも)。Windowsであれば良いかもって感じ。現在のC#はWSL2で使い分けるのが楽しい開発スタイルだと思う(※WEBにおいては)。

パッケージはアップデートせず

やったことなのにやってないことを書くのはどうなのって感じだけど、.NET CoreとC#の魅力をちょびっとだけ。基本的に.NET Coreのコアアップデートで破壊的変更は結構少なめ。C#に関しては全くない。とにかくアップデートの容易さとLTSが3年と長期間サポートが魅力。今回、ここら辺の変更がなかったのでフロントエンドに注力出来たというのもある。言語仕様的にもある程度トレンドには乗っかってるし、バージョンアップによる変更がないのでなんか知らないけどパフォーマンスよくなってる的な感覚がある(実際に向上はしている模様)。とにかくライブラリや周辺ツールは貧弱の極みみたいな感じなので悪いところをあげたらキリないが、保守が他言語に比べてほぼないようなもんなのでモダンを維持し続けられるのは最高。ツール郡が貧弱すぎるので、構成するのが難しいのでおすすめは出来ないが、Rails等、フレームワークのアップデートに苦戦してる現場をみてるとやはりそこの容易さは強み。

ステージング環境導入

Azure App Service Linuxの無料プランがあるのでそこにデプロイしてる。releaseブランチにマージされたらステージングデプロイ。masterブランチはプロダクションって感じで。今回、超絶アップデートしたので流石に動作確認は必要だなと思い導入。CIはGithub Action
tekitoumemo.hatenablog.com

やってみて

みんなの洋楽ランキングは5万UU、15万PVで会員数も非公開ながらとそこそこスケールしてるので、継続的なアップデートとバグを生みにくい構成作りが必要なり、60点ぐらいの構成は組めたと思う。あとはテスト系の土台作りとコンテナ化かな。コンテナ化はGCPに移したいからってのがあるが、経費的にもAzureでも安いし大きな問題が起きてないのであと回しに。テスト系はやる気が起きない(笑)2020年はGihub Actionからフォーマッター、静的解析、コアアップデート等土台の再構築をやった年となった。機能的な面では去年と全く変わってないが、まぁ良いでしょう。あとは年末〜年明けに向けてアクセスが増加するので、様子をみつつスケールしていく感じで今年はおわろうかなと思います。