Help us understand the problem. What is going on with this article?

Reflowを制するものはDOMを制す

More than 3 years have passed since last update.

すごい記事が1日目2日目で来ている中で恐縮ではありますが、フロントエンドJavaScriptでパフォーマンス点から気にしたほうがいい部分について書いてみることにします。

DOM律速になるケースもある

よく「JavaScriptが遅い」ということも多いのですが、具体的にはどのあたりが遅くなってくるのでしょうか.

  • 純粋にJavaScriptのスクリプト処理が遅い…最近はブラウザ自体も高速化しては来ましたが、それを追いかけるようにJavaScriptの巨大化も進んでいます。ただし、純粋にプログラム言語的な処理なら、Web Workerに振ることで並列化が可能です。
  • Ajaxや画像読み込みなどの通信が遅い…サーバ側で高速化する手もありますが、状況によってはJavaScriptで先読みを始めておいて、体感時間を短くすることも可能かもしれません。
  • DOM操作・表示が遅い…これについて今回考えてみます。

最大の特徴として、DOM関連の制御はシングルスレッドとなることがあります。Web WorkersやAjaxは、いくつも一気に起動して並行に進めることができますが、DOM操作はそうも行きません。個々の操作について、「不要なものを減らす」「速度に意識して行う」以外に、高速化の手段はないということです。

ReflowとRepaint

ブラウザがHTMLを表示するまでの流れは、大きく2段階にわかれています。

  • 各HTML要素を解釈して、それぞれが占めるスペースを算出する
  • 算出したスペースのなかに、内容を描画していく

Firefoxでは、前者をReflow、後者をRepaintといいます。Chromeでは前者を「Layout」と呼んでいたりもするのですが、この記事ではReflowで通します。

Reflowが起きるということは、つまり表示位置が変わることなので、連動してRepaintも起きるようになります。よく、「<img>にwidthやheightを指定する」という高速化手法が挙げられることがありますが、これも、画像の寸法をあらかじめ固定することで、画像読み込み完了時にReflowが起きるのを予防するという効果があります。

Reflowが起きる時

Reflowは「表示すべきものの配置が変わる」ことをきっかけとして発生しえます。つまり、

  • 要素の追加・削除
  • すでに存在する要素の、寸法や余白が変わり得るスタイル変更
  • ユーザーによるスクロールやブラウザのサイズ変更

などです。ただし、毎回Reflowしなくても処理はできるので、必要な時だけに限定しています。実際にReflowが起きるタイミングとしては、

  • フレーム更新の直前
  • JavaScriptから、寸法に関係するスタイル関係の値にアクセスする(参照を含めて

などです。

Reflowを減らすには

ということで、Reflowを減らす手段として、大きく2つに分ければ「Reflowになりうることを減らす」のと「Reflowが起きるきっかけを減らす」ということがあります。

まず、「Reflowになりうることを減らす」方法としては、

  • 細かい単位でスタイルを変更せず、できればクラス一発で切り替える
  • DOMに要素を追加する場合も、documentFragmentなどを使って、一気に追加する
  • DOMへの追加前にスタイルを整えて、それからDOMに追加する

などがあります。もう一方の、「Reflowが起きるきっかけを減らす」方法ですが、もちろんJavaScriptからフレームレートの調整はできませんので、「できるだけ寸法プロパティへの参照を避ける」ということが中心になります。

requestAnimationFrame

IE 10以降、Android 4.4以降などを含む多くのブラウザで使える関数として、requestAnimationFrame()というものがあります。これはsetTimeoutと似たような感じで処理を遅らせる関数ですが、実行タイミングがフレーム再描画の直前、ということになります。そういうことで、ここでReflowが起きてもほとんどペナルティにならないので、名前の通りのアニメーションなど重いDOM処理をするには最適な場所となっています。

外部リンク

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away