するするさせたい:サイボウズ採用情報のアニメーション(その1)

サイボウズの採用情報ページを見ていた。

といっても受けるとかではなく、ただ性格悪いことを思っていただけなんだけど。

Kintoneのセクションでアプリっぽいアイコンたちが右から左へと流れているんだけど、それがガタガタとしている。するするしていない。するするさせたい。

というわけで、何が起こっているのかを調べてみようかと。何回かにわけて書くよ。

  • その1 ― 何が起こっているのか調べる
  • その2 ― 調べながら直しながらするするさせる
  • その3 ― ちょっとしたことや他のブラウザでもするするさせる

アニメーションの実装を調べる

あとのことを考えて、Chrome DevToolsを使う。

まず、該当の流れるアイコンのところで右クリックしてinspectする。Elementsパネルで、<div class="icon"> という要素がハイライトされる。div.icon には style 属性がついていて、そこにセットされた background-position の値が絶えず変化しているのが見える。

f:id:myakura:20160510083150p:plain

というわけで、背景画像の位置をJavaScriptで逐次書き換えるっていう、クラシックなアニメーションの実装方法なのがわかる。

使われているJavaScriptファイルのソースを見てみる。.icon で検索すると見つかった。

var loopIcon = function(){
  $(this).css({backgroundPosition:'0'});
  $('.kintone .icon').animate({backgroundPosition:'-1680px'}, 1680*36, 'linear', loopIcon);
}

jQueryでやっているみたい。で、こういうJavaScriptで逐次CSSを書き換えていくアニメーションにはたいてい描画絡みの問題がある。

描画されている箇所をみてみる

描画について見てみる。DevToolsのレンダリング設定パネルを使う。

DevToolsのメニューで「Other tools」→「Rendering settings」を選ぶと、下からにゅっとConsoleなどがついたパネルがが生えてくる。Renderingタブが選択されていると思うので、その中にある「Enable paint flashing」をチェックすると描画の変化する箇所に緑色の枠がつく。スクロールしたり、リンクにカーソルを重ねたりすると、「描画の変化」がどういうものかわかると思う。

f:id:myakura:20160510083928p:plain

さて件のアニメーション。ずっと枠がついたまま。なので、この箇所が絶えず描画されているのがわかる。

タイムラインをとってみる

こいつがパフォーマンスにどれくらい影響しているのか、もうちょっと見てみる。
Timelineパネルを開いて、左上にある黒丸を押して2〜3秒ほど録る。

以下はMacBook Air 11" (mid-2011モデル、メモリ4GB)上のChrome Canary (M52)、ちょこちょこブラウザやエディタを開いた状態で録ったもの。記録する際に、PaintとScreenshotのみチェックした。

f:id:myakura:20160512120322p:plain

とれたけどいろいろ情報が多いので、まず上のオーバービューと呼ばれる箇所を見る。その下のフレームチャートなどはあとから見よう。

オーバービューは、フレームとFPS、CPUのアクティビティ、スクリーンショットを見せて大まかなところを把握するためのところ。

f:id:myakura:20160512120342p:plain

フレームのところにあるがたがたした緑色の領域はFPSで、てっぺんが60FPSを指す。その上に見られる赤い線は60FPSを切ったフレームで、いわゆる「フレーム落ち」、海外のWebパフォーマンス界隈だと “jank” と呼ばれるやつを指している。
つまり上に赤い線が見えず、緑色の面積が大きいほどいい。

で、かなりのところでジャンクが発生している。環境によっては赤いのを見ないかもしれないけど、今回はこうなった。

さて、フレームの下、CPUのアクティビティを見る。ちょこちょこと濃い緑色の山があって、たまに紫や橙が見られる。
上のフレームのとこと違って、こちらは山が低い方がいい(負荷が少ないから)。ではこの山になってるとこで、なにがおこっているのか。

フレームチャートを見る

調べるといってもどこを見るといいか。見直すと、ちょっとパターンが感じられる箇所があった。

f:id:myakura:20160512124009p:plain

だいたい等間隔で高い山が現れているので、ここを詳しく見ると、パフォーマンスの問題が見えてきそうだ。そこを見てみよう。
オーバービューのところで範囲選択すると、下のフレームチャートが該当する範囲のものに切り替わる。

f:id:myakura:20160512131823p:plain:w600

一番下のペーンに、アクティビティごとにかかった時間が円グラフにまとめられている。“Painting”と“Other”が多い。後者はさておいて、描画関連の処理は全体400ms中38msと、1割弱もの時間がかかっているのがわかる。

本当にそこなのか、隠してみる

さて、タイムラインを録ってアイコン周りの描画の負荷が高くてフレームが落ちているようになんとなく感じていたものの、それが直接の原因なのかを確かめていなかった。どうすればいいか。隠せばいい。

もういちどElementsパネルに戻って、div.icon を選択し、h キーを押す。そうするとアイコンがぱっと消えてしまう。

f:id:myakura:20160512141442p:plain

div.icon__web-inspector-hide-shortcut__ なんて変なclassがついたけど、中身は visibility: hidden を指定しているだけ。
visibility: hidden が当たると描画関連の処理が行われなくなる。ではこの状態でタイムラインを録ってみよう。

f:id:myakura:20160512142003p:plain

全体的にいろいろ薄くなった。ジャンクな赤色も見えない。FPSのグラフがなくなっているのはアイドル状態になった、つまりは活動しなくてもよくなったから。


というわけで、アイコンのアニメーションが描画に負担をかけてるのがわかった。では負担をかけない、するするするアニメーションにどう作り変えていけばいいだろうか。長くなったのでそいつは次回に。

(追記):次回書いたよー