uhyohyo.net

JavaScript初級者から中級者になろう

十五章第一回 Page Visibility

このページの最終更新日:

第十五章はWeb Performanceの話です。最近(2014年7月現在)、Webアプリケーションへの注目が集まっています。これは、HTMLやCSS・JavaScriptで書かれたブラウザ上で動くアプリケーションであり、この講座もWebアプリケーションに直接つながる技術を数多く紹介しています。そんな中、いかにアプリケーションがサクサク動くかということは重大な関心事となりつつあります。Webアプリケーションの動作が重いとユーザーの悪印象に直結するからです。ですから、サクサク動いてユーザーを不快にさせないような工夫が必要です。Web Performanceはそのような目的で作られた一連の仕様のことを指します。

その中で、今回紹介するのはPage Visibility APIです。これは簡単に述べると、ユーザーが今このタブを見ているか他のタブを見ているか知ることができるものです。これを利用することで、例えば重い処理をするページで、ページが見られていないときは処理を削減したりするなどして軽くする工夫ができます。

現在の状態を知る

まず、現在ページが見られているか見られていないかは、Documentのもつhiddenプロパティを使います。これは真偽値で、trueならユーザーが見ていない、falseなら見ているということです。


if(document.hidden){
  //ページは今は見られていない
}else{
  //見られている
}

ちなみに、タブブラウザの場合は見られているか見られていないかは明らかで話は簡単ですが、ブラウザのウィンドウが複数あったりする場合はどうなるでしょうか。

実は、そのページのウィンドウが他のウィンドウに完全に隠されていたり最小化されていたりしたらtrueで、一部分でも見えていたらfalseということになっています。

また、そのページから他のページに移動する瞬間にももう見られないということでfalseになります。

ただ、他のウィンドウで完全に隠されている場合の動作などを厳密に正しく実装しているブラウザはない気がします。

また、より詳しい状態を知るために、もう一つvisibilityStateプロパティがあります。これは真偽値の代わりに状態を表す文字列が入っています。状態は以下の4つのうちのどれかです。

"hidden"
ページが、他のタブが見られていたりウィンドウで覆われていたりで見えない場合です。この場合はhiddenプロパティはtrueになっていますね。
"visible"
逆に、ページが見えている状態です。hiddenプロパティがfalseの場合に当てはまります。
"prerender"
これもページが見えない場合ですが、ページが最初から見えない状態で開かれて、そのまま見えていない場合です。これもhiddenプロパティはtrueですね。
"unloaded"
これは同じくhiddenプロパティがtrueの場合のうち、他のページに移動しようとしている場合です。しかしこの値も確実なものではないためあまり期待しないほうがいいです。

以上をまとめると、visibilityStateでは、hiddenプロパティがtrueの場合をさらに3つに分けているということです。しかし"hidden"以外の2つはブラウザによるサポートが必須ではなく、"preorder""unloaded"に当てはまる場合も"hidden"としてもよいと定められています。そのため、これらの情報を利用してもいいが、なくても問題なく動くようなプログラムを書かなければいけません。

状態の変更を検出する

さて、現在の状況を知るだけではなく、状態が変わったら分かったほうが嬉しいですね。それには、Documentで発生するvisibilitychangeイベントを利用します。このイベントは単純で、イベントオブジェクトには特に情報はありません。イベントが発生したら、hiddenプロパティなどを見て現在(変更後)の状況を判断します。

サンプルソースとしてサンプルを用意しました。動作を確かめたりソースを見たりしてみてください。現在のブラウザの動作を見るに、他のタブを見たりブラウザを最小化すると見えなくなったと判定され、他のウィンドウを上からかぶせただけでは見えなくなったとは認識しないようです。

以上がPage Visibility APIの全てです。簡単ですね。繰り返しになりますが、用途は例えば、重い描画をするゲームを作ったりしたときに、見ていないときは描画を省略して負荷を小さくするなどの使い道があります。他には、例えば動画を再生するページで見られていないときは再生を止めたい場合などもあるでしょう。