Voicy Tech Blog

Voicy公式Techブログ

Go1.8とAngular4をプロダクションで使ってみた!Voicy WEB版の開発裏話

こんにちは。Voicy CTOの窪田です。

7月18日にVoicyのWeb版をリリースいたしました!さっそく使っていただけたでしょうか?
https://voicy.jp/

f:id:voice-tech:20170725220611p:plain これにより、いままでiPhone/iPadでしか聴けなかったパーソナリティの声を、PCやAndroidのブラウザでもお聴きいただけます!リリース直後には多くの方がSNS上に喜びの声を書き込んでいただいたのを読んで、本当に作ってよかったなぁと感じました。どうもありがとうございます!こういった生の声を直接聴けるのは、toCサービスをやる醍醐味だと思います。

そこで今回はこのWEB版の開発裏話をさせていただきます。

開発言語

言語はサーバーサイドがGo1.8で、クライアントサイドがAngular4を使用しています。それぞれのバージョンは2月と3月にリリースされたばかりの最新で、エンジニアとしては開発していてとても楽しかったです。Goについては以前のブログでも書いているので、よければそちらもご覧ください。

SPAの必要性

WEB版を使っていただくとわかりますが、画面遷移した場合でも、再生プレーヤーが上部に固定で表示されています。動画であれば画面中央にどーんと表示されてユーザの目線はそこに固定されるのですが、音声の良いところは他のページを見ながら聴くという、ながら聴きができるところです。

言い方を変えれば、他のページへ遷移しても音声を止めずに再生し続けないといけないということです。普通であれば他のページへ遷移すると音声も動画も止まってしまいますので、必然的に1つのページ内で表示を切り返るSPA(Single Page Application)で作る必要あり、Angularで開発することにしました。

OGP対応

ありがたいことに、Voicyではパーソナリティを始めとしたユーザーのみなさまが各チャンネルをFacebookTwitterといったSNSで多くのシェアをしていただいています。現在iOSアプリからシェアするとURLが表示されるだけなのですが、WEB版のURLで表示していただくと、このようにシェアした配信を表す写真とテキストが表示されます。(アプリも対応予定です。しばらくお待ちください)

f:id:voice-tech:20170723212347p:plain

この表示を行うために設定しているのがOGP(Open Graph Protocol)です。HTMLのMETAタグに設定するのですが、SPAでは大きな問題があります。それはSPAはシングルページというだけあって、大元のHTMLファイルは1つだけです。つまりMETAタグに設定できるOGPの内容が1つしかありません。そのため、どの配信をシェアしても同じ写真+テキストしか表示されないことになります。

Voicyでは日々多くのパーソナリティの方が配信しており、シェアした時にはその人の写真と配信内容のテキストをどうしても表示したいという強い思いがあり、いろいろと試行錯誤を行いました。

METAタグにflagmentを設定する

AJAXページのSEO対策としてMETAタグに
 <meta name=“fragment” content=“!”>
を設定するとクローラーが良い感じにhogehogeしてくれるというのがあります。(詳細は省略)

OGP対応もそこでできるかなと思いましたが、シェアした場合に各SNSがどこまでクローラーと同じように処理してくれるかが不明で調べている時間もなかったこと、対応するのに思っていたよりも工数がかかりそうだったことの2点を理由に見送りました。

SSRを使用する

Angularは2からSSR(Server Side Rendering)にも対応しています。SSRとはAngularによる描画をサーバーサイドで行い、結果のHTMLをクライアントへ返す方法です。これによりリクエストURLに応じてOGPを設定したMETAタグをクライアントへ返すことができますが、それだと結局画面遷移のたびにHTMLを書き換えることになるため、再生を止めないというSPA採用の目的が果たせなくなってしまいます。

index.htmlを動的に作成する

最終的にはこの方法を採用しました。Angularだけで解決することは諦め、PHPでアクセスURLを元にサーバーから必要な情報を取得し、OGPのMETAタグを動的に生成しています。プログラム自体はそこまで複雑でもないので、その時オフィスに来ていたエンジニアの方にさくっと作っていただきました(笑)

課題

トップ画面パフォーマンス

WEB版のトップ画面では多くの配信情報を取得しているのですが、そのパフォーマンスがあまり良くないという課題があります。ここはDBからの取得部分で改善できそうなポイントがあるので近々対応予定です。

モバイルで連続再生できない

iPhoneAndroidのブラウザでアクセスした場合、1つの記事の再生が終わっても次が自動で再生されません。これはモバイルブラウザの仕様で、プログラムから自動で音声や動画の再生を開始することができないためです。メディアデータはサイズが大きいため、ユーザーが想定していないデータを裏側でダウンロードし、パケット通信量を使いすぎないようにこういった制限が掛かっています。そのため、再生を開始するには画面をタップする等のユーザアクションをトリガーにする必要があるのです。(ブラウザによって多少実装が異なる場合もあります)

実は最初の音声を再生するタイミングで他の音声も全てダウンロードしておけば連続再生できるという裏技も一応あります。実際1パーソナリティの1配信分だけであればそこまでのデータ量ではないのかもしれません。しかし、ユーザーがサイト内を回遊し、いろんな人の配信を少しずつ聴くといった行動をした場合、たいして聴いてもいないのに大量のパケットを消費してしまうことになります。この点ついては、今後の使われ方を見ながらどうすべきか判断させていただきたいと思います。ご不便をおかけして申し訳ありませんが、ご了承ください。

Angular遅延ロード

今はフロントサイドの全てのコードを1つのModuleとして作っています。そのため、最初にアクセスしたタイミングで全てのページのデータをブラウザ側にダウンロードしているのですが、その中には設定画面のような使用頻度の低い画面も含まれています。AngularではModuleを分割して必要になった時にだけダウンロードする遅延ロード(Lazy Loading)というのもできるので、今後画面が増えていくことも考えて早めに対応していきたいと思います。

開発体制

開発は6月からの約1ヶ月半かけて2名で行いました。企画やデザインはもう少し前から取り掛かっていましたが。

サーバーサイドのGoとクライアントサイドのAngularでそれぞれ担当を分け、私は主にクライアントサイドを担当しました。2人ともGo、Angularは今回が初めてで、最近Hello Worldからスタートしたばかりなのですが、そのわりには1ヶ月半でここまで作りきれたのはなかなかではないかと手前味噌ながら思っております。

ちなみにたった2名で作ったのは単純にVoicy社内にそれしかエンジニアがいなかったからです(`・ω・´)キリッ
つまりはエンジニアを100%つぎ込んでWEB版を作っていたので、その間アプリ版の改修が止まってしまい、ユーザーの皆さまには申し訳なく思っております。しかしながら、VoicyではWEB版に限らず他にも新しいサービスをどんどん立ち上げていこうと考えています!改善を止めずに新規サービスを立ち上げていく。そんな無茶を実現するためにも、現在Voicyではエンジニアを大募集中です!本当に立ち上げフェーズのベンチャーで自分の力を試してみたい方、まずは話を聞いてみたいだけでも全然かまいませんので、一度オフィスへ遊びに来て下さい!
https://open.talentio.com/1/c/voicy/requisitions/detail/4803