Slide 1

Slide 1 text

© PLAID, Inc. 2025.02.27  |  #250227_PLSI_Engineering 固有技術の掛け算で事業推進に繋 げるプロダクト開発 ⽇沢翔太 | 株式会社プレイド, KARTE Blocks チーム © PLAID, Inc.

Slide 2

Slide 2 text

© PLAID, Inc. | Confidential ⾃⼰紹介 ⽇沢 翔太 株式会社プレイド KARTE Blocks 2023.11に中途⼊社しました。公私共に、酒を飲みすぎては後悔する⽇々。 お酒🍺 29 © PLAID, Inc. | Confidential 2 地⽅移住検討中 SEO⾒習い🔰

Slide 3

Slide 3 text

© PLAID, Inc. | Confidential KARTEについて © PLAID, Inc. | Confidential 3 CX(顧客体験)プラットフォーム ⼀⼈ひとりに合わせた 顧客体験を提供 WebやAppの訪問者の⾏動を 顧客ごとにリアルタイムに解析

Slide 4

Slide 4 text

© PLAID, Inc. | Confidential Stats of KARTE © PLAID, Inc. | Confidential 4 データ規模も爆発的に増加 199 億UU 累計ユーザー数 ※1 0.x 秒/解析 解析速度 134,000 over 秒間トラッキング数 ※3 2.59 兆円 年間解析流通⾦額 ※2 ※1 ローンチ〜2023年2⽉までのユニークユーザー数の実績 ※2 EC領域における解析流通⾦額。2022年3⽉〜2023年2⽉までの単年の実績 ※3 閲覧、クリック、購⼊などKARTEで計測しているユーザーの全イベントが 対象。ローンチ〜2023年3⽉までにおける最⼤値

Slide 5

Slide 5 text

© PLAID, Inc. | Confidential プレイドの全体戦略 ユーザー軸によるリアルタイムのデータ可視化 / ア クションを強みとするKARTEの提供を通じて、オ ンサイトマーケティング領域より事業を開始 以降、カスタマーサポートやリサーチ等、各領域 に最適化したプロダクト / サービスの提供によって マルチチャネルを形成 ”マルチチャネル × 1st Party Customer Data × リ アルタイム” をワンストップで提供するプラット フォーム実現に向けた基盤が構築されつつある © PLAID, Inc. | Confidential 5 1st Party Customer Data 戦略策定/ 事業‧組織開発 広告 市場調査/ 顧客調査 カスタマーサポート マーケティングオートメーション オフライン/OMO オンサイト マーケティング EmotionTech CX/EX KARTE Signals Databeat KARTE RightSupport STUDIO ZERO KARTE Message KARTE TALK KARTE Web/App KARTE Blocks

Slide 6

Slide 6 text

© PLAID, Inc. | Confidential 本⽇のアジェンダ 1. はじめに 2. KARTE Blocks プロダクトについて 3. KARTE Blocks を取り巻く  事業環境と戦略 4. ダイナミックブロックとは 5. ダイナミックブロックを   構成する技術要素 6. さいごに © PLAID, Inc. | Confidential 6

Slide 7

Slide 7 text

© PLAID, Inc. | Confidential はじめに © PLAID, Inc. | Confidential 7 ● 技術的なコアコンピタンスの掛け合わせによって ● 他社がキャッチアップしづらい価値ある機能を⽣み出し ● 強⼒に事業を推進することができる💡 本⽇お伝えしたいこと💬

Slide 8

Slide 8 text

© PLAID, Inc. | Confidential 本⽇のアジェンダ 1. はじめに 2. KARTE Blocks プロダクトについて 3. KARTE Blocks を取り巻く  事業環境と戦略 4. ダイナミックブロックとは 5. ダイナミックブロックを   構成する技術要素 6. さいごに © PLAID, Inc. | Confidential 8

Slide 9

Slide 9 text

© PLAID, Inc. | Confidential KARTE Blocks プロダクトについて © PLAID, Inc. | Confidential 9 ● サイト改善における悩みは様々 ○ 「継続してできない」「安⼼してできない」「⾃由にできない」 ● KARTE Blocksは、「サイト改修‧更新の効率化」「テストによる仮説検証やパーソナライズ」 「データによる課題発⾒」までをワンストップで実現 ● サイト運営の複雑性を緩和‧解消し、安⼼‧⾃由に⾏えるようにするプロダクトです あなたのサイト改善 あっという間に。継続的に。

Slide 10

Slide 10 text

© PLAID, Inc. | Confidential KARTE Blocks プロダクトについて タグを⼊れるだけでサイトを ブロック化。 直感的なエディタで、アイデアを すぐに反映、⾃由に配信‧検証。 © PLAID, Inc. | Confidential 10

Slide 11

Slide 11 text

© PLAID, Inc. | Confidential KARTE Blocks プロダクトについて KARTE Blocksが⽬指す 新しいサイト運営のアプローチ © PLAID, Inc. | Confidential 11

Slide 12

Slide 12 text

© PLAID, Inc. | Confidential 本⽇のアジェンダ 1. はじめに 2. KARTE Blocks プロダクトについて 3. KARTE Blocks を取り巻く  事業環境と戦略 4. ダイナミックブロックとは 5. ダイナミックブロックを   構成する技術要素 6. さいごに © PLAID, Inc. | Confidential 12

Slide 13

Slide 13 text

© PLAID, Inc. | Confidential KARTE Blocks を取り巻く 事業環境と戦略 © PLAID, Inc. | Confidential 13 KARTE Blocksはサイトの「更新‧管理」および「サイト改善」に対 する課題を持つユーザ層を想定したプロダクト。 この領域においては、既に多くのプレイヤーが存在します👀 ● CMS(Headfull/Headless) ● Web接客ツール ● A/Bテストツール ● LPO‧EFOツール ● ユーザー分析ツール(n1) ● ヒートマップ ● etc...

Slide 14

Slide 14 text

© PLAID, Inc. | Confidential KARTE Blocks を取り巻く 事業環境と戦略 © PLAID, Inc. | Confidential 14 個々のツールとの機能⽐較に終始して機能開発を⾏っても、後発の KARTE Blocksが短期で優位性を獲得することは難しいです。 このような市場環境で戦うためには、明確な負け理由(PoF)を減らし つつも他社と差別化した独⾃の価値(PoD)によって競争優位を⽣み出 し、「Blocksでなければならない理由」を作ることが重要です🗝 出典: https://note.com/secky/n/nccc12ffd4083

Slide 15

Slide 15 text

© PLAID, Inc. | Confidential コンセプト‧設計思想 による差別化 © PLAID, Inc. | Confidential サイト運営・改善の取り組みをワンストップで実現する ツールやプロダクト、あるいはデータの分断が、複雑性を生み 出してしまっている。 ワンストップで施策実行から検証までの機能を提供すること で、その複雑性を取り払い、安心・安全にサイト運営を継続で きる状態を実現する。 15 KARTE Blocks を取り巻く 事業環境と戦略

Slide 16

Slide 16 text

© PLAID, Inc. | Confidential © PLAID, Inc. | Confidential 16 KARTE Blocks を取り巻く 事業環境と戦略 機能による差別化 • 自由で直感的なノーコードエディタ • 高度なパーソナライズ • 定量分析・定性分析それぞれからサイトの課題を 深掘り • etc…

Slide 17

Slide 17 text

© PLAID, Inc. | Confidential 機能による差別化 © PLAID, Inc. | Confidential 17 KARTE Blocks を取り巻く 事業環境と戦略 • 自由で直感的なノーコードエディタ • 高度なパーソナライズ • 定量分析・定性分析それぞれからサイトの課題を 深掘り • etc… コンセプトによる差別化と⽐較すると競合にキャッチアップされやすい 群にすることで「Blocksでなければならない強烈な理由」に昇華する

Slide 18

Slide 18 text

© PLAID, Inc. | Confidential 本⽇の事例: ダイナミックブロック © PLAID, Inc. | Confidential 18 KARTE Blocks を取り巻く 事業環境と戦略

Slide 19

Slide 19 text

© PLAID, Inc. | Confidential 本⽇のアジェンダ 1. はじめに 2. KARTE Blocks プロダクトについて 3. KARTE Blocks を取り巻く  事業環境と戦略 4. ダイナミックブロックとは 5. ダイナミックブロックを   構成する技術要素 6. さいごに © PLAID, Inc. | Confidential 19

Slide 20

Slide 20 text

© PLAID, Inc. | Confidential ダイナミックブロックとは 元となるデータのアップデートに応じて 配信するコンテンツを⾃動更新。 ex )ランキング、新着商品など。 ユーザーの⾏動履歴や年齢‧性別などを元に、特定の条件で コンテンツを表⽰し、パーソナライズ。 ex)類似商品‧広告バナーなど。 動的なコンテンツ配信をサポートすることによって、 より⼀層⾃由なサイト運営を実現 🎉 ダイナミックブロック © PLAID, Inc. | Confidential 20

Slide 21

Slide 21 text

© PLAID, Inc. | Confidential ダイナミックブロックとは © PLAID, Inc. | Confidential 21 クイックデモ😃

Slide 22

Slide 22 text

© PLAID, Inc. | Confidential ダイナミックブロックとは アーキテクチャ © PLAID, Inc. | Confidential 22 アクションテーブル ⾃社データ データの⾃動取り込み データ連携ジョブを設定 ブロックを編集‧保存 ‧ファイルアップロード ‧データ抽出条件設定 クライアントサイト Blocks 書き換えスクリプト (builder.js) 設定を元に配信 解析基盤(Blitz) KARTE 計測スクリプト

Slide 23

Slide 23 text

© PLAID, Inc. | Confidential ダイナミックブロックとは アーキテクチャ © PLAID, Inc. | Confidential 23 アクションテーブル ⾃社データ データの⾃動取り込み データ連携ジョブを設定 ブロックを編集‧保存 ‧ファイルアップロード ‧データ抽出条件設定 クライアントサイト Blocks 書き換えスクリプト (builder.js) 解析基盤(Blitz) KARTE スクリプト ①サイトにアクセス ③KARTEスクリプトを配信 with ユーザ情報 ②閲覧イベントを トリガー KARTE 計測スクリプト 設定を元に配信

Slide 24

Slide 24 text

© PLAID, Inc. | Confidential ダイナミックブロックとは アーキテクチャ © PLAID, Inc. | Confidential 24 アクションテーブル ⾃社データ データの⾃動取り込み データ連携ジョブを設定 ブロックを編集‧保存 ‧ファイルアップロード ‧データ抽出条件設定 クライアントサイト Blocks 書き換えスクリプト (builder.js) 解析基盤(Blitz) KARTE スクリプト ①サイトにアクセス ③KARTEスクリプトを配信 with ユーザ情報 ④ユーザ情報を利⽤して データをクエリ ⑤データを返却 ②閲覧イベントを トリガー KARTE 計測スクリプト 設定を元に配信

Slide 25

Slide 25 text

© PLAID, Inc. | Confidential ダイナミックブロックとは アーキテクチャ © PLAID, Inc. | Confidential 25 アクションテーブル ⾃社データ データの⾃動取り込み データ連携ジョブを設定 ブロックを編集‧保存 ‧ファイルアップロード ‧データ抽出条件設定 クライアントサイト Blocks 書き換えスクリプト (builder.js) 解析基盤(Blitz) KARTE スクリプト ①サイトにアクセス ③KARTEスクリプトを配信 with ユーザ情報 ④ユーザ情報を利⽤して データをクエリ ⑤データを返却 ⑥ユーザ情報と データをセット ⑦動的コンテンツで 書き換え ②閲覧イベントを トリガー KARTE 計測スクリプト 設定を元に配信

Slide 26

Slide 26 text

© PLAID, Inc. | Confidential ダイナミックブロックとは アーキテクチャ © PLAID, Inc. | Confidential 26 アクションテーブル ⾃社データ データの⾃動取り込み データ連携ジョブを設定 ブロックを編集‧保存 ‧ファイルアップロード ‧データ抽出条件設定 クライアントサイト Blocks 書き換えスクリプト (builder.js) 解析基盤(Blitz) KARTE スクリプト ①サイトにアクセス ③KARTEスクリプトを配信 with ユーザ情報 ④ユーザ情報を利⽤して データをクエリ ⑤データを返却 ⑥ユーザ情報と データをセット ⑦動的コンテンツで 書き換え ②閲覧イベントを トリガー KARTE 計測スクリプト 設定を元に配信

Slide 27

Slide 27 text

© PLAID, Inc. | Confidential ダイナミックブロックとは ダイナミックブロック の強み💪 © PLAID, Inc. | Confidential 27 • データを流し込むブロックを、ノーコードで直感 的に編集できる • アクセスユーザを解析基盤で瞬時に識別し、個⼈ に合わせた⾼度なパーソナライズを実現できる • データ連携の設定がGUIで完結する • データ抽出ロジックを⾃分たちの仮説に合わせて ⾃由にSQLレスで設定でき、検証できる

Slide 28

Slide 28 text

© PLAID, Inc. | Confidential 本⽇のアジェンダ 1. はじめに 2. KARTE Blocks プロダクトについて 3. KARTE Blocks を取り巻く  事業環境と戦略 4. ダイナミックブロックとは 5. ダイナミックブロックを   構成する技術要素 6. さいごに © PLAID, Inc. | Confidential 28

Slide 29

Slide 29 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 ダイナミックブロックは、⼤きく4つのユニークな要素で成り⽴っ ている機能です。 本⽇は、特にその中からKARTE Blocksが有するサードパーティス クリプト「builder.js」の詳細についてご説明します。 © PLAID, Inc. | Confidential 29 ● 直感的なノーコードエディタ ● 柔軟なサイト書き換えを実現する独⾃ サードパーティスクリプト builder.js👈 ● リアルタイム解析基盤 Blitz ● アクションテーブル

Slide 30

Slide 30 text

© PLAID, Inc. | Confidential ダイナミックブロックとは © PLAID, Inc. | Confidential 30 📄builder.js

Slide 31

Slide 31 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 KARTE Blocksのブロック書き換え⽤サードパーティスクリプトのこ とを、builder.js と呼んでいます。 ここからは、builder.jsによるブロック書き換えの仕組みを⾒ていき ます。 © PLAID, Inc. | Confidential 31

Slide 32

Slide 32 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 builder.jsは「書き換えロジックのソース」 + 「各プロジェクトの設 定値」で構成されています。 KARTE Blocksでユーザが操作を保存すると、それが書き換えに関連 する内容である場合は、直ちに書き換え⽤のスクリプトが新たにビル ドされ、配信されます。 © PLAID, Inc. | Confidential 32 管理画⾯サーバ builder.js ビルドサーバ { … } 設定値をペイロードとして ビルドをトリガー 設定値を埋め込んで builder.jsを ビルド&アップロード 設定を保存 CDNを通じて builder.jsを配信 クライアントサイト 管理画⾯ builder.js クラウドストレージ 👈冗⻑化 👈冗⻑化

Slide 33

Slide 33 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 builder.jsによる書き換えの仕組みは、極限まで単純化すると右記の ようなものです。 バンドルされた設定値に基づいて、セレクタで書き換え対象の要素を 取得して、書き換え後のHTMLで上書きするといったような処理を ⾏っています。 © PLAID, Inc. | Confidential 33 // Blocksの設定の部分的な例 const CONFIG = [{ selector: 'body > img', html: '' }]; // 書き換えロジック const rewrite = () => { CONFIG.forEach(({ selector, html }) => { const element = document.querySelector(selector); if (!element) return; element.outerHTML = html; }); }; const onReady = (callback) => { if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => { callback(); }); } else { callback(); } }; // main onReady(() => { rewrite(); });

Slide 34

Slide 34 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 © PLAID, Inc. | Confidential 34 ダイナミックブロックの書き換え 前⾴にて例⽰したように、通常の書き換えブロックに関する設定につ いては、通常のHTML形式で書き換え後の値が保存されていました。 では、動的にコンテンツを埋め込むダイナミックブロックではどのよ うにしているのでしょうか?

Slide 35

Slide 35 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 ダイナミックブロックの書き換え 上が通常のHTMLデータサンプル、下がダイナミックブロックに対応し た書き換えHTMLデータ(ダイナミックブロックテンプレート)のサン プルです。 なんとなく、馴染みのある構⽂ではないでしょうか? © PLAID, Inc. | Confidential 35

Slide 36

Slide 36 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 © PLAID, Inc. | Confidential 36 ダイナミックブロックの書き換え 実は、ダイナミックブロックテンプレートは Petite-Vueというライ ブラリをベースに作っています。 Petite-VueはEvan Youによって開発された、軽量版 Vue.jsのようなラ イブラリです。

Slide 37

Slide 37 text

© PLAID, Inc. | Confidential Why Petite-Vue ? © PLAID, Inc. | Confidential • データをUIに反映する際、HTMLを動的に書き換える仕組みが必要 • しかし、ノーコードでJavaScriptコードを生成・管理するのは難易度 が高いため、宣言的な記法でコンテンツ書き換えを実現したい • ランタイムサイズが軽量であること • HTML互換であること • JSX/TSXやSvelteの構文はこれに当てはまらない • ASTとして扱えること • 多くの人にとって馴染みがある記法 であること 37 ダイナミックブロックを 構成する技術要素

Slide 38

Slide 38 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 ダイナミックブロックの書き換え 次に、ダイナミックテンプレートを利⽤したブロックの書き換え処理 をみていきます。 KARTE Blocksの書き換え処理は、チラつき(フリッカー現象)を防 ⽌するために基本的に元ページの描画前に差し込んで同期的に実⾏さ れます。 ダイナミックブロックにおいても、まずは同期的な書き換えを⾏いま す。 つまり、書き換え対象の要素をセレクタで取得し、保存されたダイナ ミックブロックテンプレートで書き換えを⾏います。 © PLAID, Inc. | Confidential 38 const CONFIG = [{ selector: '#target', html: '', variablesQueriy: [...] }];

Slide 39

Slide 39 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 © PLAID, Inc. | Confidential 39 export function createPetiteVueDynamicRenderer({ selectors, PetiteVuePkg, }: { selectors: string[]; PetiteVuePkg: PetiteVue; }): DynamicRenderer { const rootElementsMap: Record = {}; const reactiveScopeValuesMap: Record = {}; let app: PetiteVueApp | undefined; const render: DynamicRenderer['render'] = () => { const { createApp } = PetiteVuePkg; selectors.forEach(selector => { const element = document.querySelector(selector); if (element) { rootElementsMap[selector] = element; } }); Object.entries(rootElementsMap).forEach(([selector, element]) => { setAttributesForRender(element, selector); }); app = createApp({ Scope, $delimiters: ['#{', '}'], }); app.directive(EXPORT_DIRECTIVE_NAME, exportDirective).mount(); }; const setData: DynamicRenderer['setData'] = (selector, data) => { reactiveScopeValuesMap[selector]?._setData(data); }; const getData: DynamicRenderer['getData'] = selector => { return reactiveScopeValuesMap[selector]?._getData(); }; return { render, setData, getData }; } ダイナミックブロックの書き換え 次に、ダイナミックブロックのターゲットとなる要素全てに対してレンダリ ング⽤の前処理を⾏い、petite-vueのAppをbody要素にマウントします。 petite-vueは krt-scope というディレクティブが有効な要素をリアクティブ に管理します。

Slide 40

Slide 40 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 © PLAID, Inc. | Confidential 40 export function createPetiteVueDynamicRenderer({ selectors, PetiteVuePkg, }: { selectors: string[]; PetiteVuePkg: PetiteVue; }): DynamicRenderer { const rootElementsMap: Record = {}; const reactiveScopeValuesMap: Record = {}; let app: PetiteVueApp | undefined; const render: DynamicRenderer['render'] = () => { const { createApp } = PetiteVuePkg; selectors.forEach(selector => { const element = document.querySelector(selector); if (element) { rootElementsMap[selector] = element; } }); Object.entries(rootElementsMap).forEach(([selector, element]) => { setAttributesForRender(element, selector); }); app = createApp({ Scope, $delimiters: ['#{', '}'], }); app.directive(EXPORT_DIRECTIVE_NAME, exportDirective).mount(); }; const setData: DynamicRenderer['setData'] = (selector, data) => { reactiveScopeValuesMap[selector]?._setData(data); }; const getData: DynamicRenderer['getData'] = selector => { return reactiveScopeValuesMap[selector]?._getData(); }; return { render, setData, getData }; } ターゲットとなる要素に対してレンダリング⽤の属性を設定 各要素に対して、 krt-scope 属性と krt-_export 属性を設定。 petite-vueは、 krt-scope 属性が有効な要素に対してリアクティブな管理を ⾏います。 function setAttributesForRender(element: Element, selector: string) { element.setAttribute('krt-scope', `Scope('${selector}')`); element.setAttribute('krt-_export', '{ _getData, _setData, _selector }'); }

Slide 41

Slide 41 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 © PLAID, Inc. | Confidential 41 export function createPetiteVueDynamicRenderer({ selectors, PetiteVuePkg, }: { selectors: string[]; PetiteVuePkg: PetiteVue; }): DynamicRenderer { const rootElementsMap: Record = {}; const reactiveScopeValuesMap: Record = {}; let app: PetiteVueApp | undefined; const render: DynamicRenderer['render'] = () => { const { createApp } = PetiteVuePkg; selectors.forEach(selector => { const element = document.querySelector(selector); if (element) { rootElementsMap[selector] = element; } }); Object.entries(rootElementsMap).forEach(([selector, element]) => { setAttributesForRender(element, selector); }); app = createApp({ Scope, $delimiters: ['#{', '}'], }); app.directive(EXPORT_DIRECTIVE_NAME, exportDirective).mount(); }; const setData: DynamicRenderer['setData'] = (selector, data) => { reactiveScopeValuesMap[selector]?._setData(data); }; const getData: DynamicRenderer['getData'] = selector => { return reactiveScopeValuesMap[selector]?._getData(); }; return { render, setData, getData }; } Black65 function Scope(selector) { return { data: {}, _setData(newData) { this.data = newData; }, _getData() { return this.data; }, _selector: selector, }; } 要素ごとにデータを管理するオブジェクトを作成する関数の定義 Scope関数によって各要素のデータストアを定義しています。 要素のセレクタ、データ更新処理、データ取得処理が定義されています。

Slide 42

Slide 42 text

© PLAID, Inc. | Confidential © PLAID, Inc. | Confidential 42 export function createPetiteVueDynamicRenderer({ selectors, PetiteVuePkg, }: { selectors: string[]; PetiteVuePkg: PetiteVue; }): DynamicRenderer { const rootElementsMap: Record = {}; const reactiveScopeValuesMap: Record = {}; let app: PetiteVueApp | undefined; const render: DynamicRenderer['render'] = () => { const { createApp } = PetiteVuePkg; selectors.forEach(selector => { const element = document.querySelector(selector); if (element) { rootElementsMap[selector] = element; } }); Object.entries(rootElementsMap).forEach(([selector, element]) => { setAttributesForRender(element, selector); }); app = createApp({ Scope, $delimiters: ['#{', '}'], }); app.directive(EXPORT_DIRECTIVE_NAME, exportDirective).mount(); }; const setData: DynamicRenderer['setData'] = (selector, data) => { reactiveScopeValuesMap[selector]?._setData(data); }; const getData: DynamicRenderer['getData'] = selector => { return reactiveScopeValuesMap[selector]?._getData(); }; return { render, setData, getData }; } カスタムディレクティブによるgetter/setterのブリッジ get(exp) はカスタムディレクティブの実装において、バインドされた値を評 価して返します。 _selector はターゲット要素のセレクタ、 _getData はデータプロパティの getter、 _setData はデータプロパティのsetterとそれぞれバインドされてい ます。 この処理で、 reactiveScopeValuesMap にgetter/setterをセレクタごとに保 存し、petite-vueの外部からデータ操作関数にアクセス可能にしています。 const exportDirective: PetiteVueDirective = ({ get, effect, exp }) => { effect(() => { const value = get(exp); const selector = value?._selector; if (selector) { reactiveScopeValuesMap[selector] = { _getData: value._getData, _setData: value._setData, }; } }); }; ダイナミックブロックを 構成する技術要素

Slide 43

Slide 43 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 © PLAID, Inc. | Confidential 43 const CONFIG = [{ selector: '#target', html: '', variablesQueriy: [...] }]; ☝ダイナミックブロックでは、 variablesQueryというプロパティが追加され、 そこにデータ取得⽤のクエリ定義が含まれている ダイナミックブロックの書き換え 次に、書き換え設定に保存されたクエリ定義にしたがって、それぞれ のダイナミックブロック描画に必要なデータの取得を⾮同期に⾏いま す。 データ取得に成功したら、リアクティブデータを更新し、再レンダリ ングを発⽕します。

Slide 44

Slide 44 text

© PLAID, Inc. | Confidential ダイナミックブロックを 構成する技術要素 © PLAID, Inc. | Confidential 44 render(targets) { const selectors = targets.map(({ selector }) => selector); // 1⃣ Petite-Vue による Renderer のセットアップ const dynamicRenderer = createPetiteVueDynamicRenderer({ selectors, PetiteVuePkg: PetiteVue, }); renderState = { dynamicRenderer, targets }; dynamicRenderer.render(); // **同期レンダリング( Petite-Vue の適用)** // 2⃣ 各要素ごとにデータ取得 targets.forEach(async ({ variation, selector }) => { // **createSetDataByUpdater() を展開** const setDataByUpdater = (updater) => { dynamicRenderer.setData(selector, updater(dynamicRenderer.getData(selector))); }; dispatchEvent(variation.variationId, 'beforeDataLoad'); // `variablesQuery` の取得 const variablesQuery = variation.variablesQuery; if (!variablesQuery) return; try { // 3⃣ データ取得前に `loading` ステータスを適用 setDataByUpdater(prev => ({ ...prev, _loadingStatus: 'loading' })); // 4⃣ `variablesQuery` を解決 const resolvedVariables = await resolveVariablesQuery(variablesQuery); // 5⃣ データ適用後に `success` ステータスを更新 setDataByUpdater(prev => ({ ...prev, ...resolvedVariables, _loadingStatus: 'success' })); await dynamicRenderer.nextTick(); dispatchEvent(variation.variationId, 'dataLoaded'); } catch (e) { setDataByUpdater(prev => ({ ...prev, _loadingStatus: 'error' })); dispatchEvent(variation.variationId, 'error', { raw: e }); } }); } ダイナミックブロックの書き換え 次に、書き換え設定に保存されたクエリ定義にしたがって、それぞれ のダイナミックブロック描画に必要なデータの取得を⾮同期に⾏いま す。 データ取得に成功したら、リアクティブデータを更新し、再レンダリ ングを発⽕します。

Slide 45

Slide 45 text

© PLAID, Inc. | Confidential おさらい © PLAID, Inc. | Confidential • ダイナミックブロックの書き換え設定はPetite-Vueベースの構文でテンプレートを作成 し、保存している • 書き換え処理は、⬇のような流れで行われる • セレクタで要素を取得し、同期的にダイナミックブロックテンプレートで書き換 え • 対象の要素にリアクティブ管理をするためのディレクティブを付与し、 Petite-Vueのアプリケーションをマウント • 書き換え設定に含まれるクエリ定義でデータの取得を非同期に行い、取得に 完了したらリアクティブデータを更新し再レンダリング 45 ダイナミックブロックを 構成する技術要素

Slide 46

Slide 46 text

© PLAID, Inc. | Confidential 本⽇のアジェンダ 1. はじめに 2. KARTE Blocks プロダクトについて 3. ダイナミックブロックとは 4. ダイナミックブロックを   構成する技術要素 5. KARTE Blocks を取り巻く  事業環境と戦略 6. さいごに © PLAID, Inc. | Confidential 46

Slide 47

Slide 47 text

© PLAID, Inc. | Confidential 本⽇のまとめ © PLAID, Inc. | Confidential KARTE Blocks は、競合プレイヤーが多い領域で後発として奮闘している。 そこで、“Blocksでなければならない理由 ”を生み出し、戦いの軸をずらす戦略をとって いる。 差別化の軸は、大きく コンセプト・設計レベル と 機能レベル に分けられる。 ● コンセプト・設計レベルの差別化 は、競合がキャッチアップしづらく、長期的な 強みになりやすい。 ● 機能レベルの差別化 は、模倣されやすいため、単体ではなく機能の群として 独自価値に昇華することが重要。 さらに、技術的固有価値を掛け合わせることで、キャッチアップしづらく、かつコンセプト にマッチした機能を生み出せば、強力な武器になる ⚔🔥 47 さいごに

Slide 48

Slide 48 text

© PLAID, Inc. | Confidential © PLAID, Inc. | Confidential 48 KARTE Blocksを⽀える技術 さいごに

Slide 49

Slide 49 text

© PLAID, Inc. | Confidential © PLAID, Inc. | Confidential 49 セカンドパーティコンテンツをもつ サードパーティスクリプトの作り⽅ さいごに

Slide 50

Slide 50 text

© PLAID, Inc. | Confidential © PLAID, Inc. | Confidential 50 Blitz(前編): ⾃由度と即時更新性を 担保したAggregation さいごに

Slide 51

Slide 51 text

© PLAID, Inc. | Confidential さいごに © PLAID, Inc. | Confidential 51 Thank You! KARTE Blocks 採⽤