よくある質問

Topics

Interactivity API はどのように動作しますか ?

3つのメインコンポーネントがあります。

  • Preact と Preact Signals の組み合わせ。ハイドレーション、クライアントロジック、クライアントサイドナビゲーションのため。
  • HTML ディレクティブ。クライアントとサーバーの両方で理解できます。
  • サーバーサイドロジック。HTML_Tag_Processor が処理します。

Top ↑

なぜ Preact でディレクティブシステムを構築したのですか ? なぜ React や他の JavaScript フレームワークではないのですか ?

Preact には、React や他の JavaScript フレームワーク、たとえば Vue、Svelte、Solid よりも、フロントエンドのコンテキストにおいて、すなわち Interactivity API のフォーカスエリアにおいて、多くの利点があります。

  • 小さい: 8kB です。ここにフックシグナルが含まれます。
  • すぐに使える DOM の差分検出 (DOM diffing) があります。
  • オプションフックによって非常に拡張性があります。フック (preact/hooks)、React との互換性 (preact/compat)、シグナル (@preact/signals) は、この拡張性を利用しています。基本的に、DOM 差分検出アルゴリズム以外のすべてで利用されています。
  • コアチームが素晴らしく、とても親切です。彼らはまた、Preact のこの独立した使用法の強化に興味を持っています。

Top ↑

Interactivity API が Preact を使用することにより、Gutenberg も React から Preact に移行する予定ですか ?

いいえ。現時点では、移行の予定はありません。完全にインタラクティブなアプリケーションとしてのエディターの要件と利点とは完全に異なるためです。Preact には、React エコシステムと完全な互換性を実現する @preact/compatパッケージがあり、多くの大規模なウェブアプリケーションがこれを使用しています。しかし、ブロックエディターで Preact を使用しても、フロントエンドで Interactivity API を使用するような利点はありません。

Top ↑

ディレクティブを使う代わりに、どのようなアプローチが検討されましたか ?

多くの代替アプローチが検討されました。そのうちのいくつかを簡単にまとめました。

Top ↑

React やその他の JavaScript フレームワーク

React は Gutenberg の開発者が親しんでいるため最初に検討されました。また、Svelte、Vue.js、Angular などの他の人気のある JS フレームワークも検討されました。しかし React を含めどれも PHP との親和性がなく、WordPress のフックや国際化とも互換性がありませんでした。

Top ↑

Alpine.js

Alpine.js は素晴らしいフレームワークで、Interactivity API は多くの機能をインスパイアされました。しかし、ディレクティブはサーバーサイドレンダリングをサポートしておらず、また WordPress がブロックの便宜のために作成したのと同種のシステムを持っていました。

Alpine.js の代わりに Preact が選ばれたのには多くの理由があります。サイズが小さいこと、パフォーマンスが良いこと (特にシグナルの追加において)、Preact の宣言型構文とツール (フック、シグナル) でカスタムディレクティブを記述できること、Alpine.js よりもテストが行われていて、コミュニティが大きいことなど。また、React と互換性があり (エディターからクライアントサイドでレンダーされたコンポーネントを共有するため)、Interactivity API に、UI のステート保持を含む、最速の DOM 差分検出アルゴリズムを提供しています。

さらに、Preact がバックグラウンドで動作することで、Interactivity API は「最終レイヤー」を管理し、WordPress の要件によりよく適合できます。例えば、ディレクティブの内部での JavaScript 式の使用を禁止し、セキュリティリスクを回避し、厳格なセキュリティポリシーへの準拠を保証できます。さらに WordPress のすべてのディレクティブは仕様に準拠した HTML 属性です。

詳細については「なぜ Alpine でなく Preact なのか ?」の会話を参照してください。

Top ↑

プレーンな JavaScript

以下の回答を参照してください。

Top ↑

テンプレート DSL

インタラクティブなテンプレートを書くための DSL (Domain Specific Language ドメイン固有言語) を作る可能性も研究されました。テンプレート DSL で書かれたコードは JavaScript と PHPの両方にコンパイルされる想定です。しかし、製品レベルの品質のテンプレートコンパイラの作成は複雑で、努力の大規模でリスクの高い投資となります。ディレクティブをコンパイルターゲットとして使用するこのアプローチは、まだ将来のために検討されています。

Top ↑

ブロック開発者として、なぜ React ではなく Interactivity API を使うべきなのでしょうか ?

フロントエンドでの React の使用は、PHP 内でのサーバーレンダリングではスムーズに動作しません。React を使用してブロックをレンダーするすべてのアプローチでは、クライアントサイドの JavaScript を使用してコンテンツをロードしなければなりません。クライアントサイドでのみブロックをレンダーすると、一般にユーザー体験は悪くなります。なぜならコンテンツがロードされるのを待つ間、ユーザーは空のプレースホルダーやスピナーを見つめることになるためです。

PHP の拡張機能内で JS を使うことも可能ですが (v8js など)、残念ながら PHP の拡張機能には後方互換性がなく、PHP のフォールバックがある場合にしか使えません。

現在も、PHP 内でブロックをサーバーサイドレンダーし、かつ、React を使用して同じブロックをフロントエンドでレンダーすることは可能です。しかし、これは貧しい開発者体験になります。なぜなら、PHP 部分と React 部分の両方で、同じロジックを複製しなければならないためです。それだけでなく、WordPress のフックに起因する微妙なバグにさらされることになります !

ここでサードパーティプラグインのインストールを考えます。プラグインは、サーバーがレンダーした HTML を変更するフック (フィルター) を持ち、フィルターはブロックの HTML に1つの CSS クラスを追加するとします。この CSS クラスはサーバーでレンダーされたマークアップ内に存在します。フロントエンドでは、ブロックは React で再びレンダーされますが、今度はコンテンツにその CSS クラスは含まれません。React でレンダーされたコンテンツに WordPress フックを適用する方法がないからです !

一方、Interactivity API は WordPress のフックと完璧に連動するように設計されています。これはまた、i18n のような WordPress のバックエンド API とすぐに連携できることを意味します。

まとめると、React を使うよりも Interactivity API を使用した方が、以下のようなメリットがあります。

  • React を使用する場合、インタラクティブブロックは、サーバー上で PHP で作成したマークアップと同じマークアップをクライアント上で生成しなければなりません。Interactivity API を使用すると、サーバーでレンダーされた HTML にはディレクティブが追加されるため、そのような要件はありません。
  • Interactivity API は PHP と親和性があります。WordPress のフックや、国際化のようなサーバーの機能ともそのまま、すぐに動作します。例えば、React であれば、サーバー上でどのフックが適用されるかわかりませんし、その修正はハイドレーションの後に上書きされます。
  • 標準 (standard) を使用することのすべてのメリットがあります。

Top ↑

jQuery や バニラ JavaScript を使うよりも、Interactivity API を使う利点は何ですか ?

主な違いは、Interactivity APIが宣言的でリアクティブであることです。このため、複雑なインタラクティブ体験の作成や維持が簡単になります。さらに、ブロックと動作するように特別に設計され、上で述べた機能、たとえばブロック間通信、互換性、クライアントサイドナビゲーションのようなサイト全体の機能を実現する標準 (standard) が提供されます。

最後に、jQuery と比較すると、Interactivity APIのランタイムは、およそ10kb で、格段に軽量です。実際、WordPress のエコシステム全体で jQuery のような重いフレームワークを削除する取り組みが進行中で、この点でも流れに沿います。

Top ↑

React、PHP、そしてこの Interactivity API の知識が必要ですか ?

この API を使用してブロックにフロントエンドのインタラクティブ性を追加したければ、単純に「はい」です。もしブロックがインタラクティブでなければ、ブロックを作成するワークフローはこれまでとまったく同じままです。

Interactivity API は WordPress のフロントエンド部分に、容易にインタラクティブな動作を統合する、新しい標準の方法を導入します。このことは、ブロックのエディター部分の処理には、引き続き React を使用する必要があることを意味します。

一方、インタラクティブなブロックの作成に Interactivity API を使用すれば、複雑なトピック、たとえばツールの作成、WordPress との統合、ブロック間のコミュニケーション、インタラクティブ部分のサーバーサイドレンダリングなどに対処する必要はありません。

Top ↑

Interactivity API はブロックの外でも使えますか ?

もちろん、「はい」です。ブロックに限りません。Interactivity API はインタラクティブブロックを作成するための標準を提供する、という記述をよく見かけますが、それはそれが最も一般的な使用例だからです。もっと汎化して言うと、Interactivity API 標準はWordPress のあらゆる部分のフロントエンドに「インタラクティブな動作」を追加するために使用できます。

ブロックの外側の任意の HTML での Interactivity API の使用に関する詳細については、wp_interactivity_process_directives 関数を参照してください。

Top ↑

これは、すべてのインタラクティブブロックをこの API に移行しなければならないということですか ?

いいえ。Interactivity API を使用しないブロックは、Interactivity API を使用するブロックと共存できます。ただし、上で説明したように、API を使用するブロックにはいくつかの利点があります。

  • ブロック同士が簡単に通信できる。標準では、このコミュニケーションはデフォルトで処理されます。フロントエンドのインタラクティビティに個々のブロックが異なるアプローチを使用すれば、ブロック間のコミュニケーションはより複雑になり、異なる開発者がブロックを作成する場合はほとんど不可能になります。
  • 組み合わせ可能性と互換性: インタラクティブブロックを組み合わせ、定義された振る舞いを持つ構造内に入れ子にできます。同じ標準に従うことで、完全に相互互換性があります。インタラクティブ性に対して個々のブロックが異なるアプローチを取れば、おそらく互換性は壊れるでしょう。
  • ブラウザに送信されるサイズは少なくなります。個々のプラグインの作者が異なる JS フレームワークを使用すると、より多くのコードがフロントエンドに読み込まれます。すべてのブロックが同じものを使えば、コードは再利用されます。
  • ページ上のすべてのブロックがこの標準を使用する場合、クライアントサイドナビゲーションのようなサイト全体の機能を有効にできます。

Top ↑

この API の使用によるパフォーマンスへの影響は ? 非常にシンプルなユースケースで Interactivity API をロードする価値はありますか ?

この API はパフォーマンスを考慮して設計されているため、問題はないはずです。

  • ディレクティブに必要なランタイムコードはわずか10KB で、すべてのブロックに対して一度だけロードされます。
  • Interactivity APIに属するすべてのスクリプトモジュール (view.js ファイルを含む) は、ページのレンダリングをブロックすることなくロードされます
  • ブロックがビューポート内にある場合、スクリプトのロードを遅延させる可能性について、現在、調査が進行中です。実現すると、ユーザー体験に影響を与えることなく、最初の読み込みを最適化できます。

Top ↑

コアの翻訳 API と動作しますか ?

Interactivity API はサーバーサイドレンダリングと完璧にに動作するため、__() や _e() を含むすべてのWordPress API を使用できます。通常のように HTML 内のテキストを翻訳したり、サーバーサイドで wp_interactivity_state() を使用するときにストア内で使用できます。以下のようになります。

// render.php
wp_interactivity_state( 'favoriteMovies', array(
      "1" => array(
        "id" => "123-abc",
        "movieName" => __("someMovieName", "textdomain")
      ),
) );

スクリプトモジュールと互換性のある 翻訳 API (Interactivity APIに必要) は現在、作業中です。この作業の進捗については、#60234をチェックしてください。

Top ↑

XSS が心配です。JavaScript をディレクティブに注入できますか ?

いいえ。Interactivity API では、ディレクティブの値として参照を渡すことしかできません。この方法では、JavaScript の完全な式を eval() する必要がないので、XSS 攻撃は実行できません。

Top ↑

カスタムセキュリティポリシーで動作しますか?

はい。Interactivity API はeval() や Function() コンストラクタを使用しないため、unsafe-eval コンテンツセキュリティポリシーに違反しません。また、どのようなカスタムコンテンツセキュリティポリシーでも動作するように設計されています。

Top ↑

ディレクティブを使用して AJAX / REST-API リクエストを作成できますか ?

もちろんです。ディレクティブによって呼び出されるアクションやコールバックは、API リクエストの作成を含め、JavaScript の関数ができることは何でもできます。

原文

最終更新日: