5周年!ついにグラブル5周年ですよ!十賢者の追加や新エンドコンテンツの実装(予定)など、盛りだくさんな内容になっていますね。界隈ではニーアちゃんが人気のようですが、私はハーゼちゃんを狙いに行きます。
話は変わって、グラブル七不思議のひとつとして「戻るボタンはリロードボタンより速い」というのがありますよね。共闘の爆なんかでよく使うテクニックです。
あれって、なんででしょうね。正直よく知らなかったので、自分の勉強がてら調べてみました。
リロードより速い「戻る」
グラブルの有名なテクニックとして、「一部の戦闘では戦闘終了が確定したらリロードするより”戻る”ボタンを押したほうが高速にリザルト画面にたどりつける」というものがあります。特に共闘などにおいては戦闘の回転率がわりと上がるため、多くの騎空士に重宝されています。
これは、リザルトを消化していないときに共闘ルームに入ると強制的にリザルト画面に飛ばされるため……と理解することができますが、ちょっと不思議ではないでしょうか。
リロードでも、戻るでも、結局のところ画面を読み込み直しているのには変わりないはずで、むしろ戻るボタンのほうが共闘ルームを経由するため遅くなるのではないかという気がします。しかし現実にリロードより戻るのほうが圧倒的に高速なのです。
この裏には一体どんな仕組みが存在するのでしょうか。これから紐解いていきましょう。しょぼい題材の割に結構複雑ですが、頑張っていきましょう。
注意事項
この記事は部外者が勝手にグラブルのことを調べて想像で補いながら書きなぐっているだけで、正確さが保証されているわけではありません。そこだけは注意してください。
グラブルはウェブアプリ
まず大前提として、グラブルはネイティブアプリではなくウェブアプリ、という事実があります。このあたりは私も過去に記事にしています。
グランブルーファンタジー(グラブル)はどんな技術で動いているのか
ウェブアプリである以上、グラブルはブラウザの制約を強く受けてしまいます。特に、URLの書き換えや戻る/進むボタン、リロードなどの「ページの移り変わり」がユーザ側から自由にできるというのがブラウザ特有の自由度になります。これらはグラブルの開発者たちを大きく悩ませていることでしょう。
また、アプリ版もブラウザを内蔵しているだけで、結局のところはブラウザ版とほぼ同じでブラウザの影響を受けます。
シングルページアプリケーション
実はグラブルは「画面の数」と「ページの数」が一致していません。何をわけのわからない日本語を……と思うかもしれませんが、簡単な理屈です。ひとつのページに複数の画面が詰め込まれていて、プログラムで切り替えながら表示しています。
普通のウェブページやウェブアプリなんかだと、画面ごとにURLがわかれていて、移動するときはそのページへのリンクをたどる、という作りが多いですが、グラブルはひとつのページ内にほぼ全ての画面を内蔵しています。
土台だけ共有して表面だけを張り替えているイメージです。
例えば「マイページ/クエスト選択画面/サポ石選択画面/共闘画面/リザルト画面」などは共通のひとつのページのようで、このあたりの切り替えは全くページを移動していません。同じページ内の表示だけ差し替えています。
こういうのを「シングルページアプリケーション(SPA)」とか言ったりします。単一ページでごにょごにょするからシングルページ、ですね。最近めっちゃ流行ってます。
SPAのメリット
いや、SPA(シングルなんとか)ってなんだよ、普通にページ切り替えろよ、と思うかもしれません。
でも実は毎回毎回ページ切り替えていると結構遅いです。ページを移動してしまうと、サーバと通信してページを最初から読み込んで解析して表示して……という作業が発生します。これが意外にかなり重い処理で、特にグラブルのような画像やプログラムが複雑に絡み合うゲームでは、読み込みが致命的に長くなります。
最近のPCやブラウザは十分高速ですが、それでもページ読み込みの遅さからは逃れられません。
一方で、作り方にもよりますが、一般的なSPAではすでに読み込んだ部分はそのままに、変更する部分だけを読み込み/書き換えに行く形式が取られることが多いです。必要な部分だけを読み込んで書き換えるので、(うまく作れば)毎回ページ全体を読みに行くより比較的高速になります。
グラブルのテンポのいいUIを実現するためには、SPAは必須だったのでしょう。
SPAとURL
素直にSPAを作るとわりと困ったことが起きます。それは「ページがひとつなんだから、URLがひとつしかない」という問題です。ひとつしかないので各々の画面に対してURLを振れません。普通は1ページあたりURLひとつですからね。結構めんどくさいです。
例えばページを分けていれば、以下のようにそれぞれにURLを割り振ることができます:
- game.granbluefantasy.jp/mypage
- game.granbluefantasy.jp/quest
- game.granbluefantasy.jp/list
ですが、SPAだとページが1つしかないのでどの画面のURLも「game.granbluefantasy.jp」ただひとつです。複数の画面で、たったひとつのURLの奪い合いです。例えばこのURLにマイページを割り当てると、たとえ戦闘画面に移っていてもリロードするたびにマイページに戻ってきます。困った。
いくつか解決法はあるのですが、グラブルでは「ハッシュ」を使ってます。ハッシュはURLの末尾に自由に好き勝手につけられるもので、「#mypage」とか「#quest」とかつけられます。
- game.granbluefantasy.jp/#mypage
- game.granbluefantasy.jp/#quest
- game.granbluefantasy.jp/#list
ハッシュはURLに対する付属情報のようなもので、これがついたからといって何か起こるわけではありません。むしろハッシュに何が書いていても無視されます(※一部例外有り)。つまり、これらURLは全部以下と同じ扱いです:
- game.granbluefantasy.jp/
確認したかったら適当なウェブサイトのURLの後ろにハッシュつけて遊んでみるといいですよ。基本的には何も起こりません。
ですが、ハッシュはプログラム側から読み取れるので、「URLは変わらないけど、ハッシュは#questだからクエスト画面を表示する!」とか「URLは変わらないけど、ハッシュは#listだからリストを表示する!」みたいなことができるわけです。
グラブルがハッシュを使用しているのはブラウザ版でプレイしていると明らかです。URLの後ろにハッシュがついていて、画面によってこのハッシュが切り替わっています。
ハッシュの値で今のページを表しているのですね。これをプログラム側で読み取って表示する画面を振り分けているのです。
グラブルではハッシュを活用してSPAの弱点(URLがひとつしかない)を克服しているということですね。
試しにちょっとブラウザ版URLのハッシュ書き換えても面白いかもしれませんよ?
ハッシュと履歴
ハッシュ部分は基本的に無視されるので、以下のURLは全て同じページと扱われます:
- game.granbluefantasy.jp/#mypage
- game.granbluefantasy.jp/#quest
- game.granbluefantasy.jp/#list
ここで重要なのが、ハッシュが変更されたとき、例えば#mypageから#questにうつったとき、ページは移動もしないし、再読み込みもされません。「同じページ」扱いなので、改めて読み込む必要がないからです。
ハッシュが変わっただけでは例外を除き基本的に何も起こらず、「ハッシュが変わったときになにかする」プログラムを自分で書いて初めて意味が出てきます。グラブルはこれをやっているわけですね。
一方でブラウザの「履歴」にはハッシュの変化がしっかりと残ります。
例えばマイページ(#mypage)からクエスト選択画面(#quest/index)に行くと、裏側で履歴にはきっちりと「#mypage」が残っています。そしてクエスト選択画面で戻るボタンを押すとハッシュが#mypageに戻ります。そこから進むボタンを押すと#quest/indexに復帰します。このあたりは普通のURL移動と同じ扱いになります。
戻るボタンを押すと履歴に残っている前のハッシュに戻りますが、このときも当然ページの再読み込みは行われません。ハッシュが戻るだけです。
「ハッシュが変わってもページは移動/再読み込みしない」「でもハッシュ変更はブラウザの履歴に残る」がポイントです。移動していないのに履歴に残るってちょっと変な感覚ですけどね。
ここまでの情報まとめ
いままでの情報をまとめると、こうなります。
- グラブルはほぼ1枚のページで構成されている
- その1ページをガラッと書き換えることで画面を変更している
- 画面切り替えしてもページ自体が変わっているわけではない
- 「今どの画面か」はURLのハッシュ(#mypageなど)で判別している
- ハッシュだけが切り替わってもページは再読み込みされない
- 画面の変更はハッシュ切り替え時にプログラムで処理している
- ハッシュの変化はブラウザの履歴には残る
グラブルは単一のページで表示を切り替えて画面変更を実現し、そのためにハッシュを使って画面にURLを与えている、という具合になります。
ハッシュが変わってもページの再読み込みは行われませんが、ブラウザの履歴には残るというのも重要です。
「リロード」と「戻る」
ようやく本題です。リロードと戻る、どうして差が出るのでしょうか。
例えばスライムをグラゼロで吹っ飛ばしたとしましょう。このときリロードでリザルト画面まで飛ばすと、一例として以下のようなことが起こります(プログラムを全て見たわけではないので想像も入ってます):
- サーバにもう一回接続に行く
- サーバからページを受信する
- 受信したページを解析する
- ページに紐づくプログラムを解析する
- 解析したプログラムを実行する
- プログラムがハッシュを見て戦闘画面を表示しようとする
- 戦闘が終わっているのでリザルト画面に飛ばす
- リザルト画面表示
リロードは強制的に最初から読み込むので手間が多いですね。ただ、グラブルの場合は配信サーバがちゃんとしているみたいなので、言うほど時間かからないことも多いです。またブラウザ側がいろいろやってくれてさらに短縮されることもあります。
一方、戻るボタンを押したときはだいたい以下のようになるはずです:
- ページはそのままで、戦闘の一個前(共闘ルーム)のハッシュに戻る
- プログラムがハッシュの変更を見て共闘ルームを表示しようとする
- 戦闘が終わっているのでリザルト画面に飛ばす
- リザルト画面表示
リロードの半分ぐらいの手間ですね。やってることが違うので単純比較はできませんが、なんとなく戻るボタンのほうが速そうな雰囲気です。
ここで重要なのは「戻るボタンを押してもハッシュがひとつ前のに戻るだけ」「ページ移動/再読み込みが行われていない」ということです。ページ再読み込みがないため不要な処理もなく、リザルトページにすぐに誘導してもらえるのが速度の秘訣です。
「なぜリロードより戻るの方が速いのか」に対しては「戻るボタン押した時の方が手順が短いから」が答えになりますね。
ただ、これだけ見ると大きな差が出そうなものですが、実際にやってるとそこまでの差は出ません。回線状況やキャッシュの効き具合にも左右されるので、一概にどうこうは言えませんが。遅めのケータイ回線だとわりと顕著に差が出てきます。
まとめ
グラブルは1枚のページに多数の画面を詰め込むSPA(シングルページアプリケーション)という作りをしています。SPAではページがひとつしかないので当然URLもひとつになるのですが、ハッシュを使って擬似的にURLを割り当てています。
戻るボタンではハッシュの切り替えのみが行われ、リロードではページの読み込みを最初からするため、比較するとリロードの方が若干不利です。そのため読み込みの速度差が出ています。
こういった細かい挙動ひとつとっても、調べてみると意外に面白いことが判明しますね。
それでは、よい終末を。
余談
基本的にSPAなグラブルですが、「サポ石選択/共闘ルーム → 戦闘画面」と「マイページボタンを押したとき」だけはページ移動が起きます。「戦闘画面 → 他の画面」ではページ移動は起きません。理由はさっぱりわかりません。
グラブル、まだまだ謎が多いです。