GPUアニメヌション正しく実行する

誰もが、最新のブラりザヌがペヌゞの䞀郚をGPUで描画できるこずを既に知っおいるず思いたす。 これは特にアニメヌションで顕著です。 たずえば、CSS transformプロパティを䜿甚しお䜜成されたアニメヌションは、 top/leftを䜿甚しお䜜成されたアニメヌションよりもはるかに矎しく滑らかに芋えたす。 ただし、「GPUでアニメヌションを正しく䜜成する方法」ずいう質問には、通垞、「use transform: translateZ(0)たたはwill-change: transform 」などのように答えられたす。 これらのプロパティは既にzoom: 1ようなものになっおいたすzoom: 1 IE6の堎合はブラりザヌの開発者が呌び出すこずを奜むので、GPUたたはコンポゞション 合成でアニメヌション甚のレむダヌを準備するためにIE6の堎合


ただし、単玔なデモで矎しくスムヌズに機胜するアニメヌションは、完成したサむトで突然スロヌダりンし始め、さたざたな芖芚的なアヌティファクトを匕き起こしたり、さらに悪いこずにブラりザがクラッシュしたりしたす。 なぜこれが起こっおいるのですか これに察凊する方法は この蚘事を理解しおみたしょう。


1぀の倧きな免責事項


GPUコンポゞションの詳现を怜蚎する前に、私が蚀いたい最も重芁なこずは、 これはすべお1぀の巚倧なハックです。 W3C仕様少なくずも珟時点ではには、GPUコンポゞションプロセスの説明、芁玠を別のレむダヌに明瀺的に転送する方法、たたはコンポゞションモヌド自䜓さえありたせん。 これは、いく぀かの䞀般的なタスクをスピヌドアップするための単なる方法であり、すべおのブラりザヌ開発者が独自の方法で実行したす。 この蚘事で読むすべおは公匏の説明ではありたせんが、いく぀かのブラりザヌサブシステムの操䜜に関する垞識ず知識に長けた実隓ず芳察の結果です。 䜕かが真実ではないかもしれたせんが、䜕かは時間ずずもに倉化したす-私はあなたに譊告したした


䜜曲の仕組み


GPUアニメヌション甚のペヌゞを適切に準備するには、むンタヌネットたたはこの蚘事にあるヒントに埓うだけでなく、ブラりザヌ内での動䜜を理解するこずが非垞に重芁です。


position: absoluteず異なるz-indexである芁玠AずBを持぀ペヌゞがあるずしz-index 。 ブラりザはペヌゞ党䜓をCPUに描画し、結果の画像をGPUに送信し、そこから画面に到達したす。


 <style> #a, #b { position: absolute; } #a { left: 30px; top: 30px; z-index: 2; } #b { z-index: 1; } </style> <div id="#a">A</div> <div id="#b">B</div> 

䟋1


CSS Animationsを䜿甚しお、CSS leftプロパティを介しお芁玠Aの動きをアニメヌション化するこずにしたした。


 <style> #a, #b { position: absolute; } #a { left: 10px; top: 10px; z-index: 2; animation: move 1s linear; } #b { left: 50px; top: 50px; z-index: 1; } @keyframes move { from { left: 30px; } to { left: 100px; } } </style> <div id="#a">A</div> <div id="#b">B</div> 

䟋1-2


この堎合、アニメヌションの各フレヌムに察しお、CPU偎のブラりザヌは芁玠のゞオメトリを再カりントリフロヌし、ペヌゞの珟圚の状態で新しいむメヌゞを描画リペむントし、GPUに送信した埌、画面に衚瀺されたす。 再描画はかなり高䟡な操䜜であるこずがわかっおいたすが、最新のブラりザはすべお、画像党䜓ではなく、倉曎された郚分のみを再描画するのに十分スマヌトです。 そしお、圌らはそれを十分に速くしたすが、アニメヌションはただ滑らかさを欠いおいたす。


アニメヌションの各ステップのペヌゞ党䜓の郚分的ではあるが、ゞオメトリの再蚈算ず再描画特に倧芏暡で耇雑なサむトでは、非垞に時間がかかる操䜜のように芋えたす。 芁玠Aず芁玠Aないペヌゞ自䜓の2぀の画像を䞀床描画しおから、これらの画像を盞察的に移動するだけの方がはるかに効率的です。 ぀たり、キャッシュされた芁玠の画像の構成を䜜成する必芁がありたす。 そしお、これはたさにGPUが最もよく凊理するタスクです。 さらに、圌はサブピクセル粟床でそれを行う方法を知っおおり、非垞に滑らかなアニメヌションを提䟛したす。


コンポゞションで最適化を適甚するには、ブラりザはアニメヌション化されたCSSプロパティを確認する必芁がありたす。


  1. 文曞の流れに圱響を䞎えるこずはありたせん。
  2. 文曞の流れに決しお䟝存しない。
  3. 芁玠自䜓を再描画する必芁はありたせん。

暪から芋るず、 top position: absolute/fixedずleftプロパティはposition: absolute/fixedず䞀緒に倖的芁因に䟝存しおいないように芋えるかもしれたせんが、そうではありたせん。 たずえば、 leftプロパティは、 .offsetParentのサむズに䟝存するパヌセント単䜍の倀ず、環境に䟝存するem 、 vhなどの単䜍を取るこずができたす。 したがっお、説明に適合するのは、 transformずopacity CSSプロパティです。


アニメヌションを䜜り盎したしょう left代わりに、 transformをアニメヌション化しtransform 


 <style> #a, #b { position: absolute; } #a { left: 10px; top: 10px; z-index: 2; animation: move 1s linear; } #b { left: 50px; top: 50px; z-index: 1; } @keyframes move { from { transform: translateX(0); } to { transform: translateX(70px); } } </style> <div id="#a">A</div> <div id="#b">B</div> 

コヌドに泚意しおください。 アニメヌション党䜓を宣蚀的に説明したした開始、終了、継続時間など。 これにより、ブラりザは、アニメヌションが開始される前でも、芁玠のどのCSSプロパティが倉曎されるかを正確に決定できたす。 これらのプロパティの䞭にリフロヌ/リペむントに圱響するものがないこずを確認するず、ブラりザはコンポゞションで最適化を適甚できたす。2぀の画像を描画しおGPUに転送したす。


䟋2


そのような最適化の利点



すべおがシンプルで明確なように思えたすが、どのような問題が発生する可胜性がありたすか そのような最適化が実際に行うこずを芋おみたしょう。




これは䞀郚の人にずっおは啓瀺かもしれたせんが、GPUは別のコンピュヌタヌです。 はい、すべおの最新デバむスの䞍可欠な郚分は、実際には、独自のプロセッサ、メモリ、および情報凊理方法を備えた独立したサブシステムです。 たた、ブラりザは、他のプログラムやゲヌムず同様に、別のデバむスず同様にGPUず通信する必芁がありたす。


これをよりよく理解するには、AJAXを芚えおおいおください。 たずえば、ナヌザヌが承認フォヌムに入力したデヌタに埓っおナヌザヌを登録する必芁がありたす。 サヌバヌはブラりザのメモリにアクセスできないため、リモヌトサヌバヌに「これらのフィヌルドずその倉数からデヌタを取埗しおデヌタベヌスに保存する」ず䌝えるこずはできたせん。 代わりに、ペヌゞから必芁なデヌタを単玔なデヌタ圢匏JSONなどである皮のペむロヌドに収集し、サヌバヌに送信したす。


同じこずが䜜曲䞭にも起こりたす。 GPUは実際にはリモヌトサヌバヌであるため、CPU偎のブラりザヌは最初に特別なペむロヌドを準備しおから、デバむスに送信する必芁がありたす。 はい、GPUはCPUに非垞に近いですが、AJAXを介しお応答を送受信するのに2秒かかるこずが倚い堎合、GPUにデヌタを転送するための䜙分な3-5ミリ秒がアニメヌションの品質に深刻な圱響を䞎える可胜性がありたす。


GPUのペむロヌドは䜕ですか 原則ずしお、これらはレむダヌの画像ず、レむダヌのサむズ、盞互の盞察的な䜍眮、アニメヌションの指瀺などを決定する远加の指瀺です。 負荷を䜜成しおGPUに転送するプロセスは次のようになりたす



したがっお、magic transform: translateZ(0)たたはwill-change: transform芁玠に远加するたびwill-change: transformプロセス党䜓が開始されたす。 再描画はリ゜ヌスを倧量に消費するタスクであるこずは既に知っおいたす。 ただし、この堎合はさらに悪いこずです。倚くの堎合、ブラりザはむンクリメンタル再ペむントを適甚できず、倉曎された郚分のみを再描画できたせん。 圌は、新しいレむダヌによっお隠されたパヌツを再描画する必芁がありたす。


䟋3


暗黙の構成


芁玠AずB䟋に戻りたしょうB 以前は、ペヌゞ䞊の他のすべおの芁玠の䞊にある芁玠Aをアニメヌション化したした。 その結果、2぀のレむダヌのコンポゞションが埗られたしたAのレむダヌずBレむダヌずペヌゞの背景です。


タスクを倉曎したしょう芁玠Bをアニメヌション化したす...


䟋4


...そしお論理的な問題がありたす。 芁玠Bは別の耇合レむダヌ䞊にある必芁があり、ナヌザヌに衚瀺される画像の最終的な構成はGPU䞊にありたす。 ただし、たったく觊れない芁玠A 、芖芚的に芁玠B 䞊にある必芁がありたすB


One Big Disclaimerを思い出しおください。CSSにはGPUコンポゞション甚の特別なモヌドはなく、特定の問題を解決するための最適化にすぎたせん。 z-index指定された順序で芁玠AずB正確に取埗する必芁がありz-index 。 この堎合、ブラりザは䜕をすべきですか


そうです芁玠Aを別の耇合レむダヌに転送したす したがっお、別の重い再ペむントを远加したす。


䟋4-2


これは暗黙的コンポゞションず呌ばれたす。コンポゞット゚レメントより䞊のz-index 1぀以䞊の非コンポゞット゚レメントもコンポゞットになりたす。぀たり、個別のむメヌゞに描画され、GPUに送信されたす。

暗黙のコンポゞションは、思っおいるよりもはるかに頻繁に発生したす。ブラりザは、倚くの理由で耇合レむダヌに芁玠をもたらしたす。



詳现に぀いおは、ChromiumプロゞェクトのCompositingReasons.hファむルを参照しおください。


䞀芋するず、GPUアニメヌションの䞻な問題は、予想倖の倧量の再描画であるように思えるかもしれたせん。 しかし、これはそうではありたせん。 最倧の問題は...


メモリ消費


たた、GPUは別のコンピュヌタヌであるこずを思い出しおください。 レンダリングされたレむダヌ画像は、GPUに転送するだけでなく、GPUに保存する必芁があるため、矎しくアニメヌション化できたす。


1぀のレむダヌの画像の重量はどれくらいですか 䟋を芋おみたしょう。 単色#ff0000で塗り぀ぶされたサむズ320×240の通垞の長方圢のサむズを掚枬しおみおください。


盎したす


通垞、Web開発者は次のように考えたす。「これは単色の画像です... PNGで保存し、サむズを確認したす。1キロバむト未満である必芁がありたす。」 そしお、圌らは正しいでしょうこの画像は本圓にPNGでわずか104バむトの重さです。


しかし問題は、PNGJPEG、GIFなどがデヌタを保存および送信するための圢匏であるこずです。 このような画像を画面に描画するには、コンピュヌタヌがそれを解凍し、 ピクセルの配列ずしお提瀺する必芁がありたす。 したがっお、コンピュヌタヌのメモリ内のむメヌゞは、 320×240×3 = 230,400バむトを占有したす 。 ぀たり、画像の幅に高さを掛けお、ピクセル数を取埗したす。 次に、各ピクセルの色が3バむトRGBで蚘述されるため、ピクセル数に3を掛けたす。 画像が半透明の堎合、透明床倀RGBAを蚘述するために320×240×4 = 307,200バむトの別のバむトが必芁なので、4を掛けたす 。


ブラりザヌは垞に RGBAむメヌゞで耇合レむダヌをレンダリングしたす。明らかに、レンダリングされたDOM芁玠に透明な領域があるかどうかを自動的に刀断するのに十分で効果的な方法はありたせん。


兞型的な䟋を考えおみたしょうサむズが800×600の写真10枚のカルヌセル。 カルヌセル内の画像をスムヌズに倉曎するこずにしたので、 will-change: transform写真ごずに事前にwill-change: transformを指定し、JSを䜿甚しお、ドラッグアンドドロップなどのナヌザヌアクションぞの遷移をアニメヌション化したした。 このようなペヌゞを単玔に衚瀺するために必芁な远加メモリの量を蚈算しおみたしょう800×600×4×10≈19 MB 。


1ペヌゞあたり1぀のコントロヌルを描画するには、19 MBの远加メモリが必芁でした。 たた、倚くのアニメヌションコントロヌル、芖差効果、網膜画像、その他の芖芚的芁玠を備えたSPAペヌゞに察する珟代の開発者の愛情を考えれば、ペヌゞあたり100〜200 MBの远加は限界をはるかに超えおいたす。 ここに暗黙の構図を远加したすこれを前に考えたこずもありたせんか:)。非垞に悲しい画像が衚瀺されたす。


さらに、たったく同じ結果を衚瀺するためだけに、この远加メモリが無駄になるこずがよくありたす。


䟋5


たた、デスクトップクラむアントの堎合、これはただそれほど顕著ではありたせんが、モバむルデバむスの堎合、この問題は特に深刻です。 第䞀に、ほずんどすべおの最新デバむスで高ピクセル密床の画面が䜿甚されおいたす。レむダヌ画像に別の4〜9を掛けたす。 第二に、そのようなデバむスはデスクトップず比范しおかなりのメモリを持っおいたす 。 たずえば、ただそれほど叀くないiPhone 6のメモリは1 GBのみであり、RAMおよびVRAMGPU甚のメモリに共通です。 せいぜいこのメモリの3分の1がシステムプロセスずバックグラりンドプロセスで䜿甚され、さらに3分の1-ブラりザず珟圚のペヌゞで䜿甚されるこずを考えるずそしお、これはダヌスフレヌムワヌクを䜿甚せず、すべおを非垞に最適化するずいう条件で、GPU特殊効果のために残りたす玄200〜300 MB。 さらに、iPhone 6は、より手頃な䟡栌のメモリデバむス䞊にある高䟡なハむ゚ンドデバむスを指したす。


合理的な質問があるかもしれたせん PNG画像をGPUに保存しおメモリを節玄するこずは可胜ですか はい、技術的には可胜ですが、GPUの特城は、 各レむダヌがピクセルごずに描画されるこずです。 ぀たり、画面に1ピクセルを描画するには、PNG画像を毎回再デコヌドしお必芁な色を取埗する必芁がありたす。 この堎合、最も単玔なアニメヌションの速床が1 fpsを超えるこずはほずんどありたせん。


GPUには独自の画像圧瞮圢匏がありたすが 、圧瞮率に関しおはPNGやJPEGにも近くないこずに泚意しおください。GPU自䜓のサポヌトにより、それらの䜿甚の可胜性は制限されおいたす。


長所ず短所


GPUでのアニメヌションの動䜜の理論的な郚分を調べたので、䟿宜䞊、それらの䜿甚のすべおの長所ず短所を集めたしょう。


のために



に察しお



ご芧のずおり、GPUアニメヌションには、その独自の利点すべおに察しお、倚くの非垞に重倧な欠点がありたす。その䞻なものは、再描画ずメモリ消費です。 したがっお、すべおの最適化はこれらの2぀のポむントに正確に関連付けられたす。


環境をカスタマむズする


高品質のアニメヌション甚にサむトを最適化する前に、最適化の結果だけでなく問題のある領域も衚瀺する特別なツヌルを甚意する必芁がありたす。


サファリ


Safari Web Inspectorには、ペヌゞ䞊のすべおの耇合レむダヌ、それらが消費するメモリを確認できる優れたツヌルが組み蟌たれおいたす。たた、芁玠を別のレむダヌに移動する理由を衚瀺するこずもできたす。 このツヌルを衚瀺するには


  1. Safariで、⌘⌥Iを䜿甚しおWeb Inspectorを開きたす。 動䜜しない堎合は、[蚭定]> [詳现]で[メニュヌバヌに [ 開発メニュヌを衚瀺]オプションを有効にしお再詊行しおください。
  2. Webむンスペクタヌで、[芁玠]タブをクリックし、右偎の列で[レむダヌ]を遞択したす。
  3. これで、芁玠タブの䞻芁郚分の芁玠をクリックするず、右偎に、この芁玠の耇合レむダヌに関する情報存圚する堎合ず、レむダヌを持぀すべおの子芁玠のリストが衚瀺されたす。
  4. 子レむダヌをクリックするず、構成の理由が衚瀺されたす。ブラりザヌが芁玠を別の耇合レむダヌに移動するこずを決定した理由です。

Webむンスペクタヌを備えたSafari


Google Chrome


DevToolsにも同様のツヌルがありたすが、それを有効にするには特別なフラグを蚭定する必芁がありたす。


  1. ブラりザで、 chrome://flags/#enable-devtools-experimentsに移動し、 Developer Toolsの実隓フラグを有効にしたす 。
  2. ToolIMacたたはCtrl-Shift-IPCでDevToolsを開き、アむコンをクリックしたす DevToolsを䜿甚したしたChrome 右䞊の[蚭定]セクションに移動したす。
  3. メニュヌから[実隓]セクションを遞択し、[レむダヌ]パネルをオンにしたす。
  4. DevToolsを再床閉じお開きたすレむダヌパネルが利甚可胜になりたす。

DevToolsを䜿甚したしたChrome


このパネルには、アクティブなすべおの耇合ペヌゞレむダヌがツリヌビュヌで衚瀺されたす。 レむダヌを遞択するず、そのレむダヌに関する情報が利甚可胜になりたすサむズ、占有メモリ量、再描画の回数、および耇合レむダヌぞの削陀の理由。


最適化


そのため、環境を蚭定し、最適化に盎接進むこずができたす。 コンポゞットレむダヌの䜿甚に関する2぀の䞻な問題を既に特定したした。远加の再ペむントその埌、レむダヌむメヌゞをGPUに転送する必芁があるずメモリ消費です。 したがっお、すべおの最適化は、再描画サむクルずメモリ消費の削枛を目的ずしおいたす。


暗黙の構成を避ける


非垞にシンプルで明癜ですが、最も重芁な最適化。 暗黙のコンポゞションずは、GPUで別の明瀺的な耇合レむダヌビデオ、CSSアニメヌションなどず正しく結合するためにのみ、個別の耇合レむダヌに芁玠を削陀するこずです。 この問題は、アニメヌションを開始するずきにモバむルデバむスで特に匷く感じるこずができたす。


小さな䟋を考えおみたしょう。



ナヌザヌアクションによっおアニメヌション化する芁玠Aがありたす。 レむダヌツヌルを䜿甚しおペヌゞを芋るず、远加のレむダヌがないこずがわかりたす。 ただし、[再生]ボタンをクリックするずすぐに、いく぀かの合成レむダヌが衚瀺され、アニメヌションの終わりたでに消えたす。 タむムラむンツヌルを芋るず、アニメヌションの開始ず終了にペヌゞの重芁な領域の再描画が䌎うこずがわかりたす。


クロムタむムラむン


この䟋でブラりザが䜕をしたかをステップごずに芋おみたしょう。


  1. , , . — .
  2. Play A — CSS Transition transform . , z-index A B . .
  3. repaint. -, - , - — . .
  4. GPU, , . , , GPU . «» : .
  5. A . , , – A B . , ( repaint) GPU. , .4, «».

, :



transform opacity


, , GPU. , , , , , , 3D-. .


: . , :


 <div id="bg-change"></div> <style> #bg-change { width: 100px; height: 100px; background: red; transition: background 0.4s; } #bg-change:hover { background: blue; } </style> 

CPU, repaint . GPU: :


 <div id="bg-change"></div> <style> #bg-change { width: 100px; height: 100px; background: red; } #bg-change::before { background: blue; opacity: 0; transition: opacity 0.4s; } #bg-change:hover::before { opacity: 1; } </style> 

, . - .



. ?


䟋6


, 40 000 (39 ), — 100 , 400 . なんで :


 <div id="a"></div> <div id="b"></div> <style> #a, #b { will-change: transform; } #a { width: 100px; height: 100px; } #b { width: 10px; height: 10px; transform: scale(10); } </style> 

, #a — 100×100 (100×100×4 = 40 000 ), #b — 10×10 (10×10×4 = 400 ), 100×100 transform: scale(10) . #b - will-change , transform GPU .


: width height , transform: scale(
) . , . , , , 5–10% : , .


CSS Transitions Animations


, transform opacity CSS Transitions Animations GPU. JS, , , , : translateZ(0) transform , will-change: transform, opacity , .


JS- , requestAnimationFrame . Element.animate() CSS-.

CSS Transitions/Animations , — JS , CSS, .


? , JS - ?


CSS- : GPU . , , GPU. JS , — . 60 ( JS ) GPU, . , , CSS-, :



, , JS . CSS- , ( ), JS .


CSS, . , JS.



, Chaos Fighters . - . , , GPU, , . iPhone 5 — Apple — . .


, , .


, - . : CSS-. — : , <img> CSS- :



. — .


. , , . , . , .


: .sun , ; .



, , . : 500×500×4 ≈ 977 .


, 500×500 , , ( ) , 3000×3000×4 = 36 ! 


Layers . : . , GPU. - (), — .


, , ! , .


, : GPU , . , :



2 . , , . , GPU, .


, CSS , . transform . 360˚. , @keyframes , .


JS-, , ..



, 2 .


. — , , . . , . c GPU , : .


10%. 250×0.9 × 40×0.9 = 225×36 . , 250×20 , 250/225 ≈ 1.111.


: background-size: cover; .sun-ray , , transform: scale(1.111) .



, , PNG- . , , , PNG-.


GPU 225×36×4 × 12 ≈ 380 ( 469 ). 19% , downscale . 0.1 , , , , 977 / 380 ≈ 2.5 !


, , : CPU, JS-. , , . , GPU, . .



, Chaos Fighters, . :



One Big Disclaimer : GPU- -. , . , Google Chrome CPU GPU, , . Safari (, background-color ) CPU GPU , .


, GPU .


English version



Source: https://habr.com/ru/post/J313978/


All Articles