slickスライダーが突然表示されなくなった

Shopifyストア(Dawnテーマ)へslickスライダーを導入していたのですが、2024年8月1日頃、突然表示されなくなりました。特にGoogle Chromeで発生しており、他のブラウザでは正常に動作するケースが見られました。原因と対処方法をメモとして残します。

原因

調査の結果、この問題はChromeブラウザにおける「DOMNodeInserted」などのMutation Eventsが原因で発生したことがわかりました。GoogleはChromeでのミューテーションイベントを正式に非推奨とし、2024年7月にサポート終了と削除が行われました。バージョン127(2024年7月23日リリース)以降のサポートが終了されました。これにより、スライダー表示に使っていたコードが意図通り動作しなくなりました。

今回トラブルになったスライダーは setTimeout() と組み合わせて読み込みを遅延させる方法を取っていましたが、この方法ではタイミングによってスライダーが正しく初期化されないようです。特に、非推奨になったMutation Eventsがトリガーされない場合、setTimeout() の依存関係も問題を引き起こすことがあります。

Mutation Eventsの非推奨とその理由については、Googleが公式に発表している以下の記事を参考にしてください。
▼Chrome からミューテーション イベントが削除されます
https://developer.chrome.com/blog/mutation-events-deprecation?hl=ja

対処方法

この問題を解決するためには、古いMutation Eventsを使用していたコードを、新しい「MutationObserver」に置き換え、setTimeout() を使う代わりにDOMの変更を正確に監視する方法を取り入れます。
下記は追加したスクリプトです。(参考まで)

$(document).ready(function() {
  // 監視対象のノードを指定
  var targetNode = $('.slick-slider')[0];

  // MutationObserverオプションの設定
  var config = { childList: true, subtree: true };

  // コールバック関数
  var callback = function(mutationsList, observer) {
    mutationsList.forEach(function(mutation) {
      if (mutation.type === 'childList') {
        // スライダーが初期化されたか確認
        if ($('.slick-initialized').length > 0) {
          // setTimeoutで遅延処理を実行(例: 500ミリ秒遅延)
          setTimeout(function() {
            $('.slick-initialized').addClass('finally-loaded');
          }, 500); // 遅延時間は調整可能
        }
      }
    });

  // MutationObserverを初期化して監視を開始
  var observer = new MutationObserver(callback);
  observer.observe(targetNode, config);
  
  // 必要に応じて setTimeout() を削除し、正確なDOM変化に基づいて処理
});

このコードでは、「MutationObserver」を使用し、指定したDOM要素に変化があった場合にクラス「slick-initialized」に「finally-loaded」クラスを追加します。スライダーの読み込みが完了した際に特定の処理を行うことができます。

最後に

今回の問題は、ブラウザの仕様変更により発生したものでした。特にパフォーマンスへの影響が懸念されるため、非推奨技術が使用されている場合は、新しい標準に対応することが重要ですね。

免責事項

提供するサンプルコードは、一般的なシナリオを想定していますが、各ストアのカスタマイズ内容や環境によっては予期せぬ動作を引き起こす可能性があります。本コードを導入する際は、十分なテストを行い、その使用によって発生した不具合については責任を負いかねます。