3年前のレガシーサービスをフルリニューアルするときに俺的やりたいことn選

3年前に作られたサービスをフルリニューアルする運びとなりました。
リファクタの文化がなければ、テストコードもない。インデントはタブなのスペースなの？そのCakePHPは本当にCakePHPなの？PHPは5.3。丁寧に `ssh` & `git pull` してデプロイ。gulp入ってるのに `.css` を git 管理。。。。
1年かけて徐々に耕してきましたが、念願のリニューアル！！
やりたいこと大爆発したので、個人的な趣味/独断/偏見/マイブームもりもりの構成を書きなぐります。
新卒2年目なので至らないところがあったらツッコミしていただけると幸いです。

あと前述の通り、普段の業務での開発は CakePHP なので Rails 周りの知識はおぼろげなのでご容赦ください

## 前提
- メディアサイト
- CVポイントはフォーム入力
- 脱社内ガラパゴス

## インフラ編

![AWS Design.png](https://qiita-image-store.s3.amazonaws.com/0/7442/6fa177cf-106d-b398-b203-7e0ee0b3b10d.png)

### 実現したいこと
1. 負荷対策
2. サーバ監視
3. アクセス解析
4. アクセス高速化

### アプリケーションサーバ
1. EC2
2. nginx
3. unicorn
4. fluentd （for アクセス解析）

### 画像リサイズ＆キャッシュサーバ
nginx の画像リサイズモジュールを使って画像のリサイズを行う
rails で paperclip などで行っても良いが、形式が書きられてしまうのがネック・・・
記事のサムネイルや後述の AMP のために使う
特に、 AMP は画像のサイズを事前に知らないといけないので重宝する予感

Cloudfront や最近教えてもらった Cloudinary などのサービスを使うのもありかなぁとも思います

[thoughtbot/paperclip: Easy file attachment management for ActiveRecord](https://github.com/thoughtbot/paperclip)
[nginxの画像キャッシュサーバにリサイズ機能を付けた - Qiita](https://qiita.com/zaru/items/1c21d418d69c3505a91a)
[Cloudinary - Cloud image and video service, upload, storage & CDN](https://cloudinary.com/)
[【AWS の CDN】Amazon CloudFront（高速コンテンツ配信ネットワーク） | AWS](https://aws.amazon.com/jp/cloudfront/)

### サーバ監視
1. mackerel
2. newrelic

外部監視は mackerel が社内スタンダード＆今使ってるので続投です
newrelic も今使っていて、スロークエリなど見やすいので続投します

[特長と機能 - 特長 - Mackerel（マカレル）: 新世代のサーバ管理・監視サービス](https://mackerel.io/ja/features/)
[Digital Performance Monitoring and Management | New Relic](https://newrelic.com/)

### アクセス解析
1. Amazon kinesis data stream
2. AWS Lambda
3. ClickHouse on EC2
4. Redash on EC2

アプリケーションサーバの fluentd で Webサーバ（ミドルウェア）のログを kinesis, lambda を経由して ClickHouse に溜め込む
主に計測するものはレスポンスにかかった時間やページの容量など、 Google Analytics で計測できないものを主に扱い、速度改善などのインフラ改善に役立てる狙い
単純な PV 数の計測は Google Analytics で行う

ClickHouse も最近教えてもらったデータウェアハウスです
select がクッソ早くてディスク圧迫も少ないけど、 update, delete ができない特徴があります

[Amazon Kinesis Data Streams](https://aws.amazon.com/jp/kinesis/data-streams/)
[ClickHouse — open source distributed column-oriented DBMS](https://clickhouse.yandex/)
[ClickHouseとMySQLのベンチマークをとってみた。 - Qiita](https://qiita.com/taro_sakura/items/d5a4d376012e4f2c9ed5)
[Make Your Company Data Driven | Redash](https://redash.io/)


#### httpサーバの選択
パラレルでリクエストを扱えるとか server push とか良さげ

他 rails サービスが nginx なので、それに揃えて nginx を使いたいところ
ただ、オープンソース版の nginx は server push が使えないです
なので、それができる、かつ nginx より高速と噂の H2O を使いたい気持ちもあります

ただ、 server push がどれだけ良いのか、設定が大変そうな雰囲気があるので nginx かなぁというところです

[H2O - the optimized HTTP/2 server](https://h2o.examp1e.net/)

## バックエンド編
1. ruby 2.4 系
2. ruby on rails 5.1 系
3. sidekiq（非同期メール配信用）

社内は rails がスタンダードなのでそれに揃える形での構成です
バージョンは思考停止で最新版を使います
ただ、 rails　に関しては Vue.js を使いたいので5.1系です

sidekiq か resque か、ですが、 CTO が sidekiq の方がいいって言ってるので思考停止でそうします

[Railsで非同期処理：キュー。Sidekiq（+ActiveJob）がResqueよりも、とても簡単便利。 - Qiita](https://qiita.com/zaru/items/8385fdddbd1be25fe370)

## フロントエンド編
- モダンな技術を取り入れる
    - AMP
    - PWA
    - Vue.js
- 構造化マークアップ

### AMP
メディアサイトなので、記事ページは AMP で構成しておきたい
ページロード高速化と、検索結果で上部にカルーセルで表示されることを狙って

ネックなのはサービス内で画像サイズのレギュレーションがなかったり複数の画像サイズを用意しないといけないこと
その辺を前述の画像リサイズサーバでカバーしたい

あと CSS を View に直書きしないといけないのがネックっぽい
必然的に1ファイルサイズが大きくなるのでコード書く時に辛そう
でも AMP の制限でそんなに凝ったこと出来ないからそんなに大きくはならないのかなぁ
パーシャルで切り出す案ももらったのでそれで解決できそう感

[Accelerated Mobile Pages Project – AMP](https://www.ampproject.org/ja/)
[Learn AMP by Example](https://ampbyexample.com/)

### PWA
service worker で記事のオフライン表示や、おすすめ記事を push 通知したりしたい
検索ページとかを切り出してアプリっぽく提供してもいいかもしれない

あとはアプリとしてインストールできるようにしたい
スマホではホーム画面からアプリにアクセスする動きが前提なので
"ホーム画面 → ブラウザ → Google 検索 → サービス" で2クッション入るのはだるい
"ホーム画面 → サービス" でダイレクトに来てもらえる方がいいはず

[Google I/O：プログレッシブウェブアプリ (PWA) の機能と成果 | Growth Hack Journal](https://growthhackjournal.com/google-io-whats-going-on-with-progressive-web-apps/)
[いまさら聞けないPWAとAMP - Qiita](https://qiita.com/edwardkenfox/items/4c0b9550ffa48c1f0445)
[やばい、iOSにネイティブアプリ要らなくなるかも。SafariもPWAに対応する可能性 - Qiita](https://qiita.com/Yatima/items/b9f1962da1a304dc7604)
[Progressive Web Apps  |  Web  |  Google Developers](https://developers.google.com/web/progressive-web-apps/)

### Vue.js
jQuery でゴリゴリ実装は辛いので js フレームワークを使います
React, Angular などありますが、あくまでメディアなのでそこまでがっつりしたものは不要です
なので小回りの効く Vue.js 採用です

[Vue.js](https://jp.vuejs.org/)
[他のフレームワークとの比較 — Vue.js](https://jp.vuejs.org/v2/guide/comparison.html)
[【2016年冬】最新CSSフレームワークまとめ - Qiita](https://qiita.com/R-Yoshi/items/ee49d90eb910dfdd104f)

### 構造化マークアップ
検索エンジンに情報を伝えるために使います
AMP でも必須になります

実装方法は json-ld と microdata があります
どっちを使おうか、という話ですが、microdata は html を直接変更して構造を表します
json-ld は要は json をページ内で読み込ませる方法です

microdata は html と構造が密な関係になるので管理がダルそう、ということで json-ld を採用します

rails で実装するなら、いい感じの記事があったのでこれを参考にしようかな、と思います

[JSON-LD - JSON for Linking Data](https://json-ld.org/)
[Microdata - HTML | MDN](https://developer.mozilla.org/ja/docs/Web/HTML/Microdata)
[JSON-LDとRails - Qiita](https://qiita.com/tkawa/items/8d8a509858aae03dba84)

## 開発周り編
- test
    - RSpec
- linter
    - eslint
    - rubocop
    - csscomb
- alt lang
    - sass
    - babel
    - pug
- styleguide
    - aigis
- chatops


### test
単体テストは RSpec で。
minitest の方がいい説もあるのでちょっと調べてみましたが、僕は RSpec の方がいいかなぁという結論に

ネックは、minitest は Fixture/plugin の管理、RSpec は DLS の学習コスト。
他プロジェクトでは RSpec を使っているので DLS 憶えないといけないのは必然、ということでネック以前の問題
minitest はシンプルで魅力的だけど、 Fixture 管理は PHPUnit で辛かったのと、 plugin 管理に時間取られるなら本末転倒感が辛い
ということで RSpec かな

[RSpecとMinitest、使うならどっち？ / #kanrk06 // Speaker Deck](https://speakerdeck.com/jnchito/number-kanrk06)
[rspecとminitestの比較　〜そうして僕は返事がない屍となった。〜 - Qiita](https://qiita.com/namitop/items/dc269e0514100df4549f)

### linter
コードの体裁をチェックするのは人間がやることじゃないのでコードにやらせます

javascript → eslint
ruby → rubocop
css → csscomb

[ESLint - Pluggable JavaScript linter](https://eslint.org/)
[bbatsov/rubocop: A Ruby static code analyzer, based on the community Ruby style guide.](https://github.com/bbatsov/rubocop)
[CSScomb: Makes your code beautiful](http://csscomb.com/)

### alt lang
sass(scss), babel は今使ってるので続投。

babel-preset-env という ES5 への変換度合いをよしなに決めてくれるものが出てきてたので使います

html は rails なら slim が使えますが、 pug がいい感じって CTO が言ってたのでそうします

[babel/packages/babel-preset-env at master · babel/babel](https://github.com/babel/babel/tree/master/packages/babel-preset-env)
[Getting Started – Pug](https://pugjs.org/api/getting-started.html)

### styleguide
スタイルガイドでパーツスタイルの統一と、ページ作成時にディレクターがそれを見て考えられるように用意します

今 aigis を使ってるので続投
ruby なので ruby系のスタイルガイドジェネレータがいいですが、Rails5.1系なら node.js 必須なのでまぁいいでしょう

[aigis - CSS Styleguide Generator](https://aigis-styleguide.github.io/aigis/)

### chatops
デプロイ時のオペレーションが複雑になってきた

- (STG環境の時は) STG を使っていないか確認
- PR作る（コメントに該当 issue のリンクを貼る）
- 開発メンバーに共有
- ディレクターに共有
- マージ
- デプロイ

手動でやるのはだるくなってきたのでまとめてやっちゃいたい感
あと chatops ってなんかいいやん？

bot といえば hubot ですが、 coffee script 使わないし ruby で rails なので ruboty が相性良さげ　
[r7kamura/ruboty: Ruby + Bot = Ruboty](https://github.com/r7kamura/ruboty)

## その他考察
### http/2 について
パラレルにリクエストを扱う、 server push でクライアントサーバ間の通信コストを減らすことでハヤイ！
インフラ周りはフルリニューアルでもなければ入れ替えが大変なのでこのタイミングで対応しておきたい気持ち

ちょっと疑問で残るのは、 ALB 挟んだら webサーバで HTTP/2 対応しなくていい説。
`client <-> ALB <-> server` の現状で chrome developer tools の Network で見た時にプロトコルが "h2 (HTTP/2 over TLS)" で表示されてる
まぁでも、Webサーバは HTTP/2 には対応していないので、きっと ALB が HTTP/2 に対応しているのでそう表示されてるだけだと思う
なので実質的に HTTP/2 の利益は得られてないんだよね、きっと
普通に考えて Webサーバで HTTP/2 対応しないとだよね、普通に

[HTTP/2 の概要  |  Web  |  Google Developers](https://developers.google.com/web/fundamentals/performance/http2/?hl=ja)
[普及が進む「HTTP/2」の仕組みとメリットとは | さくらのナレッジ](https://knowledge.sakura.ad.jp/7734/)

### turbolinks と Vue.js 相性悪い件
turbolinks を使うと Vue.js の動作が不安定になる
Vue.js がマウントする時に悪さをする様子・・・
加えて、 Google Analytics とも相性が悪いとの噂が他チームから聞こえてきたり・・・

turbolinks のロード高速化は魅力的ですが、開発効率を考えると個人的には削除したい気持ち

まだ検証していませんが、代替策として InstantClick が使えそうな雰囲気
しかも turbolinks よりも高速に動作するとの評判もあるのでより良さそう
ただ、 Google Analytics を使う時には turbolinks の様に専用の処理を加えないといけないので、一手間は必要になるよう

[InstantClick — JS library to make your website instant](http://instantclick.io/)
[2行追加するだけでWebサイトを高速化するInstantClick.io - atskimura-memo](http://atskimura.hatenablog.com/entry/2014/02/18/215538)

### js が webpacker と sprockets でダブる件
sprockets は css, js を1ファイルにまとめることでブラウザキャッシュに持たせて表示の高速化を図るものです
webpacker は Vue.js　や React など js フレームワークを webpack でコンパイルします
モダンフレームワークを使えるのと、 js をモジュール化できるので管理コストを削減できます

それぞれで管理する js ファイルは配置場所がそれぞれ指定されています
- sprockets → `app/assets/javascripts/` 以下
- webpacker → `app/javascript/` 以下

これにより js ファイルの置き場所が複数になるので管理がダルいのと、どんな時にどっちに置くのか、を気にしないといけないです
なので、どちらかにまとめておきたいところ

気持ち的には js モジュールを使って管理コストを抑えることを最優先にしたいので、 webpacker でまとめて管理するようにしたい

### watcher がいろいろ生まれる件
以上の構成だと、開発時にいろいろな watcher が必要になる
- linter
- webpacker
- styleguide

foreman でプロセスをまとめて管理するのが楽かな

[ddollar/foreman: Manage Procfile-based applications](https://github.com/ddollar/foreman)

### 管理画面不要説
Redash を使えば、管理画面で数字を見れるようにする必要はないので、実装する手間を省けそう
ただ、CMSは必要なので0にはできなさげ

## まとめ
やりたいことを詰め込んでみました
他にも面白げなやつあったら突っ込んでみたいです