GYAO!のWebリニューアルの舞台裏

浜田真成氏(以下、浜田):本日はご来場いただき、誠にありがとうございます。「拡張性あるデザインシステム構築から挑む、GYAO!のWebリニューアル」という題で、浜田がお話しさせていただきます。どうぞ、よろしくお願いいたします。

改めまして、浜田と申します。

Yahoo! JAPANのエンジニアで、現在は動画部門GYAO!でエンジニアリングとデザインに携わっています。2015年に入社し、これまで刷新の業務に多く関わってきました。主にフロントエンドのエンジニアリングと、デザイン面の改善を行っています。

思い返してみますと、これまでWebの刷新、プレイヤーの刷新や、iOSのSwift化などを担当して、リファクタリングばかりを行っています。わたしを見かけたら「リファクタリングをされるな」と覚悟してもらったほうが良いかもしれません。

今日は、GYAO!のWeb刷新の事例についてお話しします。冒頭の基調講演では、藤門から「未来に続く」と話がありました。GYAO!は今まさに、快適なWeb環境を実現するために、未来に続くための基盤工事をゴリゴリと行っている最中です。

フロントエンド技術とデザインの両観点から、どういった手順で刷新を進めているのか。今回は、その具体的な戦略をご紹介しようと思います。来場者の方の中にも、レガシーな環境での開発に悩まされている方も多くいらっしゃると思いますので、一例として参考にしていただければと思います。

このなかで、GYAO!をご存知の方はいらっしゃいますか?

(会場挙手)

けっこういらっしゃいますね。ありがとうございます。

ご存知ない方へ、簡単に紹介しますと、GYAO!は無料動画配信サービスです。VODサービスと呼ばれるものの1つで、最近ではオリジナルコンテンツを展開していたりもします。

実はGYAO!はかなり古くからあるサービスです。GYAO!がYahoo! JAPANとの共同運営になってから、今年で10年になります。それ以前も含めますと、さらに長い期間存続しています。しかしながら、現在も成長が著しいサービスで、Webだけにとどまらず、モバイルアプリからテレビデバイスまで幅広いデバイスで動画を楽しむことができます。ぜひ利用してみてください。

本日のトピックは「➀課せられたミッション」「②敵を知る」「③技術戦略」「④組織を変える」の4つです。

課せられたミッション

まず、本日、自分たちに課せられたミッションを紹介したいと思います。大きく分けて2つあります。

1つ目が、レガシーWebシステムからの脱却です。

先ほど「GYAO!は10年以上続いているサービスである」と言いました。これまで技術リソースの問題から、負債を抱えたまま運用を続ける状況がありました。そのため、これまで「Webの改修が遅い」とステークホルダーの方にご指摘いただくなど、課題を抱えつつも事業を優先するあまり、誰も刷新のような技術チャレンジを行うことが難しかった背景があります。

わたしは2017年にこのWebチームにジョインして、この状況に愕然としまして、変えていくことを決意しました。

もちろん、既存のプロダクトを維持して事業戦略を達成することも大事です。アーキテクチャの刷新とサービスの成長は必ずしも比例しないため、事業戦略を達成しつつ、2つのミッションのバランスを取って実現していく必要があります。これはどうしていけばよいでしょうか? 本日はそのお話をします。

まず、携わってきたメンバーの構成を紹介します。

少人数の開発チームで行っています。バックエンド開発は、わたしも入りつつ、だいたい3人ぐらい。フロントエンド開発はわたし1人でした。デザイナーは適宜アサインされ、案件ごとに1~3人ぐらい。ディレクションも適宜アサインされ、1~3人程度携わる形です。

敵を知る

続いて、具体的な課題点を整理します。ここでは「倒すべき敵」という表現で、整理しています。

1つ目の敵は、スライドでは「モノリシック」とも表現していますが、いわゆるFat Viewです。

GYAO!のWebアプリケーションは、10年以上にわたる事業で、継ぎ足す形で支えられてきたコード群によって動作していました。解読は困難で、業務ロジックと表示のロジックが同一の箇所に記述されている状態でした。

コードは、処理の全貌を見渡すことが困難でした。言語としてはPHPで記述されていましたが、今表示テンプレートを書いているのか、業務ロジックを書いているのか、まったくわからない。

この問題に起因する課題は多々あると思いますが、開発では実際に、テストコードが記述できない、リファクタリングが困難、フロントエンドの開発がサーバー上でしかできない、といった問題が発生しました。この点は、作業効率を著しく悪化させる原因になっていました。

業務ロジックが局所化されていないことも大きな問題になりました。自分たちは通常のWebのほかに、モバイル版のWebなど、複数のアプリケーションにまたがるロジックを持っていますが、新しい仕様が入ってくると、複数の箇所に同じビジネスロジックを加えなければならない状況が発生していました。局所化されていないコードは、開発の手足を止めて工数の増大を招き、リリースそのものを難しくしてしまいます。

敵の2つ目として、テストとリリースの流れが問題になりました。

上述したFat Viewの状況下でテストを行うと、単体テストや結合テストの記述が難しくなります。その結果、テストは手動で担保するしかありませんでした。1つのリリースには、1時間程度の時間を要しました。

敵の3つ目は非セマンティックWebです。

これはいわゆるHTMLのコードの記述の問題です。動作することのみが考えられたHTMLの記述は、セマンティックに書かれていないため、SEO上非常に悪い効果をもたらしており、本来インデックスされるべきページが検索結果に上がってこない状況がありました。同じサービス内なのに、Yahoo! JAPANで検索してもGYAO!が表示されない。

アクセシビリティの考慮もされていませんでした。要素の識別が困難で、マウスやキーボードの操作性は考慮されていませんでした。また品質の問題により、ブラウザ差異に起因する表示崩れも発生していました。継ぎ足し継ぎ足しのコードによって、細部での表示不具合が発生していたのです。

UI、仕様、ワークフローにおける問題

さらに、UIの一貫性も破綻していました。同一UXなのにUIが異なるパーツが散財していたのです。

(スライドを指して)例えば、このウォッチリスト登録のボタンの比較では、担当者ごとに把握する粒度が異なるために、デザインが微妙に異なるボタンが複数生まれていく状況が発生していたのです。マージンの取り方も、統一性がないように見えますね。

観点を変えますと、表示パフォーマンスも非常に悪い状況になっていました。

(スライドを指して)右の表示は、GoogleのPageSpeed Insightsで計測した指標ですが、速度が「Slow」となっています。サーバーの応答速度が非常に遅いという問題もありましたが、フロントエンド部分も最適化がまったくされていませんでした。複数のJSやCSSが直列で呼び出されてしまって、初期のレンダリング自体を阻害しています。

その結果、SpeedIndexというパフォーマンスを測る指標が15,000という数字を叩き出していました。ご存知の方もいるかもしれませんが、この数字は低いほうが良く、5,000を超えた程度でも明らかな遅延を感じるようになります。このときは15,000を超えていましたので、非常に遅いと言えます。

敵の6つ目は、仕様の複雑性です。

長年の開発で、各部門に暗黙の了解で合意された仕様が多く発生していて、どこを変えることで契約の何を満たさなくなってしまうのかが、まったくわからない状態になっていました。

ドキュメントも存在しないため、最終的にはコードが仕様です。読んで把握するしかない。コードを読み解く作業を繰り返して、自分たちはドキュメントを掘り起こす作業をしてきました。

ワークフローも複雑でした。

仕様を策定してから、デザイン、開発と、直列にやりとりが並んでいるので、開発に至るまでに何度も何度も往復の確認を行わなければなりません。最終的に「これ、やっぱり開発できない」と言われると、(フローの)最初に戻ります。プロジェクトの中にいると気が付きにくいですが、この作業の繰り返しは多くの時間を浪費します。

これらの問題が密接に絡み合い、思うように開発が進まず、技術的に挑戦できない状態が、当たり前のように発生していたわけです。

技術的(生存)戦略

多くの敵を目の前にするとあきらめたくなりそうですが、もちろんあきらめはしません。どうやって、これらの課題を解決したかについて説明します。

まず、なぜこれらの問題の解決が重要なのか。GYAO!は「VODサービス」と先ほど紹介しましたが、もちろん競合サービスは多くあります。現在の状況は負債によって機能追加が困難な状況であり、これ以上サービスを成長させるために、時間がかかりすぎてしまうことがわかると思います。現状維持では確実に競合に負けてしまいます。

マイナスの状況からは、高速なリリースサイクルでプロダクトを成長させ、その差分を取り戻すありません。ビジネス指標の達成による短期の成長と、コストの削減による長期の成長を、同時並行で解決していく必要があります。

つまり、「やっていくぞ」ってことですね。

わたしたちはその移行方法として、Webアーキテクチャの段階移行を考えました。どのように移行の算段をつけてきたか、概要を説明します。

Webアーキテクチャの段階移行

移行方法は、大きく2つの方法があります。一括リプレースと、段階移行です。それぞれデメリットとメリットがあると思います。

一括リプレースであれば、既存の実装にしばられず、クリーンな形で最適な技術構成を実現することが可能です。ただし、スライドの図を見ていただくとわかる通り、一括リプレースは古い構成と新しい構成の二重運用が発生します。

段階移行であれば、既存の運用にある程度しばられる制限はつきますが、新規で開発した部分は1つの運用で収まっています。改修した箇所は小さな単位でユーザーに届けることができ、メンテナンス範囲も既存以上に増えることはありません。

上記理由で、わたしたちは段階移行を選択しました。先ほど「少人数の開発体制」と言いましたが、フロントエンドエンジニアがわたし1人であることを考えると、一括リプレースの方法では開発しなければならない箇所が増加し、維持が困難になります。段階移行の方法を取ることで、小さな単位でユーザーに回収を届けながら、順を追って刷新を進めていくことができます。

刷新までの具体的なコード移行手順を説明します。大きく分けて、フェーズ1、フェーズ2、フェーズ3と区切りました。

フェーズ1では、業務ロジックと表示テンプレートの分離を行います。この段階では、表示要素のコンポーネント化などを行うとともに、コードを読み解いて仕様の整理をしていきます。

フェーズ2では、1で細かくした要素をそれぞれリファクタリングしていきます。分解の粒度の大きいものは、ここでも要素を細かく分解する作業を繰り返します。また、この時点でデザインシステムの導入も行っています。

フェーズ3では、全体的な最適化を行っていきます。PaaS環境への移行、SPAの構成への移行、使用言語をTypeScriptに直すといった改善を行っていきます。

これらを抽象的にまとめると、まず分解し、個別に改善して、最後に全体最適化を図るという手順を踏んでいることになります。

アーキテクチャ移行の3つのフェーズ

分解について、詳細に見ていきましょう。

先ほどよりFat Viewの問題点をあげていますが、人間は複雑に固まった問題を把握することができないものです。課題を小さな粒度に分解して、認識できる範囲にしてから改善を行うプロセスを踏みました。

分解すると、改修を考える箇所が小さくなるので、変更が行いやすくなります。その小さくなった部分に対して、リファクタリングをかけていきます。小さい範囲の回収を積み重ねて、最終的にその範囲を広げていき、全体を最適化していく算段です。

分解は、Fat Viewを業務ロジックと表示コンポーネントに分離することから始まります。これはデータを生成する部分と、データを表示する部分を分けるということです。

その際に、書かれているコードの内容を見て、仕様を把握/明記していきます。

1つ目の分解を経て、さらに分解を続けます。業務ロジックを切り離したら、その部分をドメイン駆動設計に見直し、業務に必要な役割ごとにコードを整理します。GYAO!では、クリーンアーキテクチャを元にした分類を行っています。Model、UseCase、Presenterという役割別に分類し、各構成が密になりすぎないよう分離します。また、それぞれに単体テスト、結合テストを確実に記述していきました。外部に依存のテストは、DI(Dependency Injection)を利用します。

表示要素も分解を行っていきます。

表示の部分は、Webページをコンポーネント単位で分けていきます。刷新後の表示要素は、すべてAtomicDesignをベースとしたコンポーネントで構成されています。分解後は、モダンなビルド環境も準備しました。これは後ほど詳説します。

フェーズ2の段階では、1でざっくり分解した業務ロジックと表示コンポーネントをもとに、さらに分解を進め、各要素に対してリファクタリングをかけていきます。

1の段階でテストコードを記述しているため、テストを壊さないように修正を続けていきます。

フェーズ2では、この他にワークフローも変更します。スライドには「デザインシステムで制作を加速する」とありますが、コンポーネントに分解された要素をもとにして、企画職を巻き込みながら、ビジネス仕様を管理するワークフローを整えています。また、コンポーネントの組み合わせでデザインが成立するよう統一性を担保し、デザインと開発が用意な環境を作ります。

フェーズ3では、作成した基盤をもとにして、PaaS環境への移行、テストの自動化、SPAの構成に展開を進めます。

この段階で、高速リリースのサイクルに移行できます。ダークローンチやカナリアリリースといった機能を、PaaSの環境で実現します。また、最適化された表示面のコードをベースに、SPA(Single Page Application)を作成して、複雑な表示要件を高速に実現する環境を作成します。