12/28

日記

2025/12/28

Three.js

GPGPU

computation.init()のいちが重要

一通り終わって前とは印象違った。

流体シミュレーションでレンダーテクスチャを使ったときはテクスチャに前の時間の位置の情報を渡して現在の位置の速度を求めていたけど、journeyの例では各パーティクルの位置を出して、ノイズを足していき、gl_FragColorの第4引数に寿命を設定して元の位置に戻したりした。

  • gpgpu用につくるglslでは、addVariableで渡した変数名が使える。
  • gpgpu用につくるglslでなにかのジオメトリのpositionを扱う場合、テクスチャで渡ってくるから、texture2D(position , uv)←uvが必要
  • ジオメトリやモデルは頂点位置を取得するためだけに使われ、実際の描画ではGPGPUで計算されたテクスチャから取得される。

manual

tips-要求されたレンダリングより。

基本的に毎フレームレンダリングしていたが、常時動いておらず何らかのアクションによって動くような3Dシーンの場合、アクションが起きているときにだけrenderされるような構造で動かしたほうがパフォーマンスがよい。

たしかに。今まで疑問を持たず毎フレームレンダリングしてたけど、次からこの手法取れないかやってみる。

パフォーマンス レイアウトツリー構築最適化

レイアウトツリー構築

Scriptの後のRenderingフェーズの話。
CalculateStylesとLayoutが行われる。
JSでDOMを更新したりするとだいたいLayoutが引き起こされる。

CalculateStyle

CSSルールセットがどのDOMに当たるかを算出する。

CSSセレクタのマッチング処理は右から左へ処理される。
そのためセレクタの記述を増やせば増やすほどマッチング処理の時間は遅くなる。

再レンダリング

DOM操作などによりCalculateStyleやLayoutが再計算される。

ただ、なるべく再利用されるよう設計されており、必要のない内部の処理はスキップされたりする。

例えば、JSでstyleプロパティを直接変えたりしたらCSSのマッチング処理はおこらない、
backgroundColorをかえてもLayoutはおこらない

計測方法

パフォーマンスタブで紫色で「レイアウト」「スタイルの再計算」と書かれている。

パフォーマンスの良いCSSの記述

セレクタが右から左へ評価されることを知っていると、子孫セレクタなどを避けて記述をシンプルにすることはわかると思う。

特に、全称セレクタ(*)がまずい。
header > *とかだと、すべての要素に対して親要素がheaderかどうか確認することになる。

実はカードとかの中身に対して .card > * + *として間隔を開けていたが、中身をgridかflexにしてgapで間隔を開けたほうがパフォーマンスに良い。

Recalculate Styleを高速に

CSSセレクタのマッチング処理をレンダリングエンジンに行わせないことが有効。
JSの実行でDOMツリー構造が変化したり、DOM要素の属性が変化するとマッチング処理が行われる。

  • DOMのclass属性変更
    classList.add()
    マッチング処理の対象となる。記述されているルールによってはオーバーヘッドが大きくなる。
  • styleプロパティを変更
    el.style.color="white"
    CSSセレクタのマッチング処理を避ける。

クラス付け外しの方が早いと思っていたが、jsでやったほうがパフォーマンスに良いらしい。

Layout(リフロー)について

CalculateStyleの後は視覚的な要素のみを抜き出して大きさや位置が計算される。
レイアウトは以下で引き起こされる。

  • DOM要素の座標、大きさ変化
    cssでwidth、height、topなどの位置、margin関連、padding関連、border、border-widthを変えるとだめ。
    ホバーとかでwidthを変えてると、ホバーのたびにLayoutを引き起こしているということ。
  • DOMツリー構造の変化
    appendChildとかでDOM要素を変えると、CalculateStyleとLayoutが実行される
  • DOM要素のコンテンツの変化
    要素の幅や高さによって親要素の幅高さが決まるような場合、その要素内のテキストが変更されるとLayout

Layout最適化

再度Layoutが引き起こされる場合、Layout計算の対象となるのはドキュメント全体になる。

以下の最適方法がある

  • レイアウトの範囲を限定する
    ドキュメント全体が対象にならない条件を満たすと範囲をそのDOM要素以下に限定できる。
  • レイアウトを減らす
    再計算される要素を減らす。JSではremove()を使って処理してから必要になってからappendしたり、
    display:noneで非表示にされた要素は計算の対象にならない。(visibility:hiddenでは対象となる)
    全く非表示でもdisplay:noneにされてないと対象となるので、透明の要素とか注意。
  • img要素にwidthheightを指定する
    指定されていないと、大きさがわからない関係でLayoutが一度行われてから大きさがわかってから再度行われる。
    レイアウトシフト以外にもパフォーマンスにも良かったとは。

PWA

ブログをPWA化してみた。

manifest.tsを追加するだけでインストールできるように。
スマホホーム画面にインストールすると、スタンドアロン表示(アドレスバーなし)に。
また、Wappalyzerで見ると「PWA」が追加されている。

例えば記事投稿されたらプッシュ通知を受け取るようにするには、dbが必要。
supabaseで将来やるか?

感想

マック安い。コメダよりこっちになりそう。

さてさて、「WebデザインプロセスBook」が届いた。楽しみ。

Well, Today the book has arrived. I'm looking forward to it.