JSでLottieを配置する方法
- パフォーマンスの最適化方法も紹介!

Xへポスト
はてなブックマークへ投稿
20
共有
URLをコピー

Lottieロッティー」はベクター画像のアニメーションを実現できる技術・ファイルフォーマットです。

Lottieアニメーションの作り方編の記事(Figma編After Effects編)では、Lottieの概要から作り方、ファイルの書き出し方を紹介しました。そして、実装編の前編となる記事では、HTMLメインで実装できるお手軽な実装方法を紹介しました。

実装編の後編となる本記事では、JavaScriptメインに実装する方法の基本事項、およびパフォーマンス考慮についてのポイントを紹介します。

「Lottie=軽い」と思っていませんか? 一般的にウェブサイトの「軽い」「重い」には、読み込みデータ量の大小を指す場合と、動作負荷でのもたつきを指す場合の2つの意味があります。確かにデータ量的にはLottieは軽いといえますが、実はLottieのアニメーションは表示や動作の負荷的に重くなりがちです。本記事では、動作負荷のもたつきとしての「重さ」を深掘りしてみます。ぜひ最後までご覧ください。

dotLottie-webを使用した実装

今回は、LottieをUIに組み込んだデモを作成しました。Lottieの使用箇所に絞って解説します。

▼虫眼鏡をクリックしてアニメーションを確認(キーワードは未入力でも試せます)。

①ライブラリのインポート

ドキュメントにしたがってライブラリをインポートします。

CDNで読み込みたい場合は、JSの冒頭でCDNからDotLottieをimportします。

import { DotLottie } from "https://cdn.jsdelivr.net/npm/@lottiefiles/dotlottie-web/+esm";

パッケージマネージャーの場合は、dotLottieをインストールし、JSの冒頭でDotLottieをimportします。

npm install @lottiefiles/dotlottie-web
import { DotLottie } from "@lottiefiles/dotlottie-web";

② 空のDOM要素を用意してid属性を追加

dotLottie-webはcanvas要素に描画します。JavaScriptから参照するためのid属性をcanvas要素に追加しておきます。作例ではアイコンボタンとして表示するため、button要素内に用意しました。

<button>
  <canvas id="lottie" class="lottie"></canvas>
</button>

new DotLottieで初期化

アニメーションのインスタンスをnew DotLottie()で作成します。

  • canvas: 用意したcanvas要素を渡します。
  • src: lottieデータのファイルパスを記載します。
    • デモではビルドツールであるViteヴィートを使用してファイルをimportしています。
  • autoplay: 再生処理は手動で行うため、falseにしています。
import search from "@/assets/search.lottie";

const lottieContainer = document.querySelector("#lottie");

const anim = new DotLottie({
  canvas: lottieContainer,
  src: search,
  autoplay: false, // 自動再生はしない(デフォルトはfalse。省略可)
});

初期化時に指定できる主要なオプションは次の通りです。全文は公式ドキュメントの『dotLottie Web Player API Reference』をご覧ください。

オプション名 説明
canvas(必須) lottieを差し込むcanvas要素
src または data path: ファイルのパス
data: jsonオブジェクト
loop(デフォルトはfalse true: 無限ループ再生
false: 1回だけ再生
autoplay(デフォルトはfalse true: ロードされたら自動再生
false: 自動再生はしない
segment 再生するフレームの範囲指定。最初の値に開始フレーム、2番目の値に最終フレームを指定する。

④アニメーションの操作

アニメーションインスタンスの操作メソッド一覧を参考にアニメーションを調整します。

作例では、元のLottieがゆったりとしたスピード感のアニメーションデータだったため、setSpeed()メソッドで再生速度を調整しました。

anim.setSpeed(1.7); // 速めの再生速度に調整

また、ボタン押下時に呼び出す関数に、アニメーションの再生を管理する処理を追加しています。

play()メソッドでアニメーション再生を開始し、ランダムな秒数の待機後、loopプロパティをfalseに変更します。これで再生中だったアニメーションが完了したら自動で停止します。

const onSearch = async (anim) => {
  // アニメーション再生
  anim.setLoop(true); // ループ再生
  anim.play();

  // ローディング風にランダムな時間待機
  await wait(Math.random() * 5000);

  // アニメーションがループしないよう設定を変更(再生中のアニメーションが完了したら自動で停止)
  anim.setLoop(false);
};

⑤Lottieのイベントに応じて処理を追加

イベントリスナーもいくつか用意されているので追加してみましょう。アニメーションインスタンスに対して、completeイベントリスナーを追加すれば、アニメーション完了後に何かの処理を行うことができます。作例では、ローディング画面を非表示にする処理を記述しました。

anim.addEventListener("complete", () => {
  statusText.innerText = "検索完了";
});

Lottieのパフォーマンス最適化について

前述の作例のようにUIの一部として小さなパーツに組み込む分には、さほど問題はないように見えますが、演出としてウェブサイトに組み込む場合には、パフォーマンスの問題は切り離せません。

記事の冒頭でも触れたとおり、Lottieはファイル容量自体が数KBと軽量のため、ページ読み込み時のデータ容量的な軽さとしては優れているといえます。ですが、アニメーションの再生・レンダリングは負荷がかかるため、ウェブサイトの動作的には重くなりがちです。

CPUやGPUに負荷がかかった状態だと、チラつきやフレームレートの遅延を招きます。ブラウザーによって見え方は異なりますが、Chromeの場合はフレームレートは保つものの一部が表示されず画面がバグっているように見える、Safariの場合はフレームレートが大幅に下がってカクついて見えるなどさまざまです。モバイル端末だとブラウザーが落ちることもあります。

ユーザー体験を損ねないためにも、最適化を行っておくことを推奨します。

具体的にいうと、描画が重くなる場合は以下の項目を検討するとよいでしょう。

  • 画面内に表示されないLottieはアニメーションを破棄する
  • ウェブワーカーを使用しバックグラウンドのスレッドで実行する
  • WebGPUを使用し描画の負荷を下げる

それでは詳しくポイントを見ていきます。

記事『クリエイティブ表現のレベルアップに使える最新ブラウザーの開発者機能(パフォーマンス編)』を参考に検証ツールの「Rendering」から、「Frame Rendering Stats(フレーム レンダリング統計情報)」と「Paint flashing(ペイント点滅)」のチェックを有効にしておきます。また、「Performance monitor」から「CPU usage(CPU使用状況)」等のチェックを有効にしておくと、さまざまな情報が確認できるのでオススメです。

検証1: Lottieアニメーション管理の最適化について

ひとつ目の検証に、メインビジュアルエリアをposition: sticky;で固定させ、スクロールすると次のセクションが迫り上がってメインビジュアルが隠れるという構造のデモを用意しました。結果は次の通りでした。

何もしない場合 アニメーションを破棄した場合
GPUメモリ 約16.2MB 約16.2MB
CPU使用率 約60%~99% 約27.5%~90%

検証環境:Chrome 148.0.7778.216 / macOS 26.5.1 / MacBook Air M1, 2020 / ブラウザーサイズ1920*1080px(外付けモニター)

※アニメーションの再生フレームに応じてメモリ使用量が変動するため、目安程度にご覧ください。

前提: 再生に関して何も最適化していない場合

スクロールするとメインビジュアルエリアのLottieアニメーションは本文セクションの背景に隠れて表示されていないにもかかわらず、アニメーションの再生が止められていないため、CPUをムダに使用していることがわかりました。「Paint flashing」で有効にした緑の矩形では、背景側のアニメーションがペイントされているのがわかります。

何もケアしないと描画負荷がかかっている

アニメーションを破棄した場合

スクロールしメインビジュアルのLottieが隠れたあたりで、destroy()メソッドでアニメーションを破棄しました。CPU使用率が減少し、負荷が下がったことが確認できます。

公式ドキュメントのdestroyの説明では、destroy()メソッドはレンダラーのインスタンスを破棄し、登録されているすべてのイベントリスナーを解除するとあります。

また、公式ドキュメントのMemory Managementの章でも、複数アニメーションを破棄する方法が紹介されています。

検証2: Lottieデータが複雑な場合

Lottieのデータ自体が複雑な場合はどうでしょう。検証用に、After Effects内で適当にオブジェクトを複製し、総シェイプレイヤー数800枚程度のLottieデータを用意しました。ファイルは.lottie形式のためわずか18KBと軽量です。

import { DotLottie } from "@lottiefiles/dotlottie-web";
import animation from "@/assets/complex-anim.lottie";

// 省略

const canvas = document.createElement("canvas");
const anim = new DotLottie({
  canvas: canvas,
  src: animation,
  autoplay: true,
  loop: true,
  renderConfig: {
    devicePixelRatio: window.devicePixelRatio * 0.75,
  },
});

大きめのモニターで見るとアニメーションがカクついて表示されました。フレームレートは10fps前後、CPU使用率は常時ほぼ100%まで上がっています。このように複雑なLottieは再生するだけ高い負荷がかかることもあります。

複雑なデータ

ウェブワーカーを使用する

LottieFilesのパフォーマンス最適化のドキュメントでは、ウェブワーカーを使用したDotLottieWorkerが紹介されています。

負荷の重いアニメーションの描画をメインスレッドから分けることで、パフォーマンスの向上が期待できます。DotLottieDotLottieWorkerで置き換えるだけで簡単に実装できます。

import { DotLottieWorker } from "@lottiefiles/dotlottie-web";

// 省略

const anim = new DotLottieWorker({
  // 省略
  renderConfig: {
    freezeOnOffscreen: false, // offscreenで描画がstopするのを防ぐために設定。これがないと描画されない
  },
});

フレームレートは20fps前後に向上。CPU使用率が0.1%に減少しました。アニメーションのカクつきが多少改善されたことがわかります。

複雑なデータ(ウェブワーカー)

WebGLを使用する

DotLottieはデフォルトではcanvas 2Dを使用して描画していますが、WebGLに対応したものもあります。canvas 2DはCPUを使用して描画するのに対し、WebGLはGPUを活用し、ブラウザのレンダリングを高速に実行できます。

import { DotLottie } from "@lottiefiles/dotlottie-web/webgl";

// 省略

const anim = new DotLottie({
  // 省略
});

フレームレートは60fpsに向上し、アニメーションが滑らかに表示できました。

複雑なデータ(WebGL)

WebGPUを使用する

WebGLよりさらにGPUを効率的に使うのがWebGPUです。WebGLよりもさらにパフォーマンスをあげたい時に検討しましょう。WebGPUについて詳しく知りたい方は記事『次世代のWebGPUの可能性 WebGLと比較して理解する描画機能の違い』をご確認ください。

import { DotLottie } from "@lottiefiles/dotlottie-web/webgpu";

// 省略

const anim = new DotLottie({
  // 省略
});

フレームレートは60fpsで安定しています。アニメーションも滑らかです。

複雑なデータ(WebGPU)

まとめ

JavaScriptメインで実装する方法からパフォーマンスを考慮した最適化の方法までを紹介しました。

アニメーションの作り方編では、FigmaやAfter Effectsを使用した作成方法を紹介し、実装編では、HTMLで配置できるWeb PlayerとJSで配置するdotLottie-webを使用したウェブ向けの実装方法を紹介しました。

今回Lottieのデータの作成から実装まで調査を行ってみて、デザインツールから手軽に組み込む方法が充実し、実装においても敷居が低く、リッチな体験を作ることができる素晴らしい技術だと感じました。それと同時に、パフォーマンスが悪くなってしまうとユーザー体験を損ないかねないので、Lottieを最大限活かすために、実装時のケアを行う重要性がわかりました。

デザインと実装を分担できるようになったとはいえ、相互に知っておくことは重要といえるのではないでしょうか。よりよいコンテンツを作る足掛かりになれば幸いです。

参考サイト

連載一覧

※この記事が公開されたのは1年前ですが、今月6月に内容をメンテナンスしています。

SNSでシェアしよう
シェアいただくと、サイト運営の励みになります!
Xへポスト
はてなブックマークへ投稿
共有
URLをコピー
新着記事のお知らせCSSだけでメイソンリーレイアウト - display: grid-lanesの使い方