今回PyCon JP 2019にスタッフとして参加し、Webサイトの運用(と最適化アルゴリズムを用いたタイムテーブルの提案)を行いました。そこで得られた知見と反省をまとめて、今後他のカンファレンスなどでWebサイトの開発運用をする方の参考になれば幸いです。
本当はポスター参加記とまとめたかったのですが、ポスターの記事が長めになったので分けました。
セッションへの感想はこちら。
Webサイト
サイトはVue.js製のフレームワークであるNuxt.jsとマテリアルデザインライブラリであるVuetifyで作成しました。見て目に関しては、デザイナーの方にしっかりデザインしていただき、マテリアルデザインというよりそちらに合わせたので、「あまりVuetifyっぽくない」かもしれません。
Vue Material Design Component Framework — Vuetify.js
またNuxt.jsはすべてgenerat
して静的サイトとしてホスティングしました。
構成
かなり一般的な構成かと思いますが、GitHubでの更新をCircleCIが検知してFirebase Hostingにデプロイするという構成です。
ありがたいことに見やすい、という意見もいただきました。
#pyconjp 今年の https://t.co/ouqSBEZNYr のサイトは見やすいなぁ
— Hiroki KIYOHARA (@hirokiky) September 16, 2019
動的なコンテンツ
「セッション情報」「スポンサー情報」はスピーカーやスポンサーから情報が届き次第変更される動的なコンテンツです。実は昨年はGoogle Apps Scriptを使ってGoogle SpreadsheetをAPI化していました。
しかし、「誰かが本番用のSpreadsheetを触ってしまう」という事件が起こったり、「GASのデプロイがなんだかドキドキするし、本番使用するほど保証するされているものなのかわからない(無料だし)」というような不安・不満がありました。
なので今年は、「Spreadsheetを都度ダウンロードしJSON化しアプリケーションの一部としてデプロイする」という手法を取りました。これは昨年「思っていたよりは更新回数が少なかった」という体感値から取った方法でもありました。
「CSVをJSON化する」部分はスクリプトを書いたのですが、あとから「Webpackにcsv-loader
がある」ことに気づき、最初からこれを使えばよかったことがわかりました。
良かった点
デプロイフローが整えられており、テスト環境を本番環境と全く同じ環境を用意することができたことです。これにより、イベント開催中の要望に積極的に答えることができました。
ご指摘ありがとうございます。対応させていただきました。タイムテーブルでモーダルを開くとトークごとのリンクが生成され、共有できるようになりました。 #pyconjp https://t.co/PD2b7fj8HR https://t.co/pYHMgvXN4E
— PyCon JP (@PyConJ) September 16, 2019
また、セッションの資料と動画のリンクはすべて都度都度自分が手作業で入れたのですが、これはデプロイへのストレスが相当低かったからできたことだと思います。(ここに関しては改善点でもあるので後述) 「もともと自動化できるように準備しとけよ」と思われた方もいると思いますが、実は「元々資料と動画はWebに入れる予定はなく当日現場の判断で入れた」ため特に準備をしていませんでした。
昨日の発表の資料と動画へのリンクをWebに掲載しています。もし間違いなどあれば指摘していただければ幸いです。 We've added urls of yesterday session's materials and movies. Let us know if links are wrong. #pyconjphttps://t.co/At34zrSwm4 pic.twitter.com/6Ic8mQggvK
— PyCon JP (@PyConJ) September 17, 2019
クロージング最中にデプロイし直した、自分のスライドもサイトにリンク付けてもらえました。感謝 #pyconjp https://t.co/BwJLEt9gnG
— kAZUYA tAKEI (@attakei) September 17, 2019
反省・改善点
意外とデプロイが多かった 点です。下の図のように、イベント開催直後でCircleCI上で合計で1082ジョブ走っていました。一回のワークフローで4ジョブ走るので、概算して250回以上はデプロイが行われたことになります。正直、「動的なコンテンツ」の更新は想像していたよりも多かったです。
「動的なコンテンツ」の更新においては本来は「Nuxt.jsのビルド・デプロイ」は不要です。今回は自動化されているとは言え、無駄なCircleCI実行やデプロイ待ち時間が発生してしまっていました。
そうなると「動的コンテンツ」のみLambdaや小さいアプリケーションサーバーでAPI化して、更新できるようにする選択が考えられますが、正直管理画面的なものは作りたくありませんし、毎回結果が変わるようなものではないのでできれば静的にホストしたいのです。
「どうするのが良かったのだろう」と考えていたのですが、「静的API」を作るというのがいいような気がしました。図にすると下記のような形です。SpreadsheetからJSONを作成し、「動的コンテンツ」をAPI化するのですが、「単なるJSONファイルとしてS3などのストレージサービスでホスティングする」という方法です。まだ思いつきベースなので、もっと練る必要があると思いますが、一度試してみたいです。
図ではSpreadsheetからになっていますが、Google Formなどをフックにすれば自動更新もできると思います。
また発展的な構想として、静的にホストされたAPIは参加者にも広く公開するということも考えられます。 「入門 自作検索エンジン」で「PyCon JPのセッションの検索エンジンを作る」というようなイベント自体のコンテンツを生かして発表してくださった方もいたので、そういった用途に使ってもらえるのもいいのではないかと思います。※これは別に静的にホストされたAPIでなくてもできるのですが、より負荷などを考えずに公開できる、という意味です。
(おまけ)最適化問題を使ったタイムテーブルの提案
こちらはおまけですが、昨年に引き続き最適化問題を活用したタイムテーブルの割当も行いました。考え方については以前記事にまとめています。
今回のPyCon JP 2019でも「PythonとGoogle Optimization Toolsの最適化ライブラリで、「人と人の相性を考慮したシフトスケジューラ」を作ってみた。」で「Google OR Tools(Google Optimization Toolsと同じものを指している)」についての発表があったのと「婚活・恋活領域におけるPythonを使ったマッチング最適化」でも「安定結婚問題」という同じ数理計画の問題が取り上げられていて、ORの社会実装が垣間見えたのも印象的でした。
www.slideshare.net
www.slideshare.net
さいごに
今回のWebサイト開発は自分は本職がフロントエンドエンジニアでないので勉強になることが多かったです。「もっとこんな風にしたらスマートだよ」など、アドバイスあれば是非教えてください。