Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Webエディタライブラリ 「CodeMirror」から学ぶ Webアプリ開発のテクニック
Search
igarashi
July 07, 2024
Programming
0
420
Webエディタライブラリ 「CodeMirror」から学ぶ Webアプリ開発のテクニック
2024/07/05に開催されたDevelopersIO 2024 SAPPOROにて登壇したセッションの資料です。
igarashi
July 07, 2024
Tweet
Share
More Decks by igarashi
See All by igarashi
Zennのパフォーマンスモニタリングでやっていること
ryosukeigarashi
0
110
Other Decks in Programming
See All in Programming
Pinia Colada が実現するスマートな非同期処理
naokihaba
4
230
ヤプリ新卒SREの オンボーディング
masaki12
0
130
Macとオーディオ再生 2024/11/02
yusukeito
0
370
Click-free releases & the making of a CLI app
oheyadam
2
120
LLM生成文章の精度評価自動化とプロンプトチューニングの効率化について
layerx
PRO
2
190
Amazon Qを使ってIaCを触ろう!
maruto
0
410
Webの技術スタックで マルチプラットフォームアプリ開発を可能にするElixirDesktopの紹介
thehaigo
2
1k
初めてDefinitelyTypedにPRを出した話
syumai
0
420
シェーダーで魅せるMapLibreの動的ラスタータイル
satoshi7190
1
480
CSC509 Lecture 13
javiergs
PRO
0
110
3 Effective Rules for Using Signals in Angular
manfredsteyer
PRO
0
100
エンジニアとして関わる要件と仕様(公開用)
murabayashi
0
290
Featured
See All Featured
Building Applications with DynamoDB
mza
90
6.1k
Writing Fast Ruby
sferik
627
61k
jQuery: Nuts, Bolts and Bling
dougneiner
61
7.5k
How to Ace a Technical Interview
jacobian
276
23k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Producing Creativity
orderedlist
PRO
341
39k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
890
A better future with KSS
kneath
238
17k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
2.9k
Agile that works and the tools we love
rasmusluckow
327
21k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Transcript
Webエディタライブラリ 「CodeMirror」から学ぶ Webアプリ開発のテクニック 2024.7.5 新規事業部 Zennチーム Igarashi
Xへの投稿の際は、 ハッシュタグ #devio2024 でお願いいたします。 2 お願い
Igarashi Ryosuke • 2015/7⼊社 • CX事業本部(旧モバイルアプリサービス 部)でバックエンド‧インフラを担当 • 2021/6より新規事業部 Zennチーム
• フロントエンドもやってますが何もわから ない ⾃⼰紹介 3
はじめに 4
とは Zennは「知見を共有するエンジニアに対価を」 というコンセプトでつくられた 技術情報共有コミュニティです。 5
3種類の投稿形式で、その時々に合った粒度で知見を残すことができます ひとまず 雑にメモ したい あのテーマ で誰かと 議論したい 最近学んだ あの話を記事 にしよう
労力が かかった分 有料で販売 しよう あの話を まとめて 本にしよう 6
著者が金銭的な対価を受け取れる仕組み 知見をまとめて 有料の本として 販売してみよう 応援したい 著者には 有料のバッジ を贈ろう バッジを受け取った著者に 分配金が支払われます
7
8 8
catnose さんが個人プロジェクトとしてリリース 運営会社がクラスメソッド株式会社に 2020年9月 2021年6月 5人の小さなチームで運営中 現在 のこれまで 9 企業運営になってからも自分たちがワクワクすることに積極的に取り組むスタンスは変わって
いません。ほぼすべての意思決定はチームメンバーだけで行われており、メンバー一人ひとり のアウトプットがサービスの質に直結します。
本編 10
最近のエディタ周りのアップデート 11
ZennのMarkdownエディタの作り⽅ アップデートで⾏ったことはほとんどすべて「Zenn Tech Blog」で公開しています。 12
お話すること CodeMirrorの実装からわたしが学んだこと‧興味深 かったこと伝えします。 🚀 パフォーマンス最適化 🚀 状態管理のアーキテクチャ 🚀 拡張性 13
CodeMirrorの実装からわたしが学んだこと‧興味深 かったこと伝えします。 🚀 パフォーマンス最適化 🚀 状態管理のアーキテクチャ 🚀 拡張性 収まりきらなかったので記事として書きます
お話すること 14
注意‧免責事項 • 本スライドの内容はCodeMirrorのドキュメント やソースコードを参考に作成していますが、正確 ではない可能性があります。 • 本スライドの内容はCodeMirror v6に関する内容 です。v6はv5以前とは実装が全く異なりますので ご注意ください。
15
ZennのエディタとCodeMirror 16
ZennのMarkdownエディタ ZennのMarkdownエディタはCodeMirrorというライ ブラリをベースに、多数のカスタマイズを加えてい ます。 17
ZennのMarkdownエディタ 18
ZennのMarkdownエディタ 19 Markdown記法の デコレーション URLをペーストで自動 的にリンク生成 画像をD&Dでアップ ロード・リンク生成 ショートカットキーによる Markdown記法の挿入
(太字・斜体など) SlackライクなEmojiの 入力補完
CodeMirrorとは “CodeMirrorは、Web⽤のコードエディターコン ポーネントです。多くの編集機能をサポートするテ キスト⼊⼒フィールドを実装でき、さらなる拡張を 可能にする豊富なプログラミング インターフェイス を備えています。”(翻訳) 20 引用: https://codemirror.net/
Features 21 - Modularity - Speed - Bracket Closing -
Linting - Flexible Styling - Theming - Collaborative Editing - Undo History - Multiple Selections - Internationalization ...and more - Accessibility - Mobile Support - Bidirectional Text - Syntax Highlighting - Line Numbers - Autocompletion - Code Folding - Search/Replace - Full Parsing - Extension Interface
Language Support 公式がサポートする⾔語。 この他に、コミュニティが作成した⾔語サポートも あります。 22
ちなみに ProseMirrorという、Notionライクなブロック ベースのエディタライブラリもあります。 ラッパーライブラリとして や などが有名です。 作者はCodeMirrorとおなじ⽅です。 23
ブロックエディタのトレードオフ 良いところ • プレビュー不要 • リッチな表現をUIで実現できる ⼤変なところ • 編集‧表⽰の2つのモードの実装が必要 •
細かい挙動の調整 24
質問✋ 技術記事を書く時に使いたいエディタはどっち? (A)Markdownベースの「テキストエディター」 (B)Notionライクな「ブロックエディター」 25
🚀パフォーマンス最適化 26
基礎知識 27 このテキストエディタのHTMLはどのようになって いるでしょうか?
基礎知識 28 contenteditable=”true”により、 divやspanのテキストが編集可能に 1⾏⽬ 2⾏⽬ 3⾏⽬ class指定による ハイライトの装飾
仮想スクロール ⼤量のデータをブラウザにレンダリングする際に、可視範囲 のDOMだけを動的に⽣成することで、レンダリングにかかる 時間を⼩さくしてパフォーマンスを向上させるテクニック。 動的な変数をもとにレイアウト(描画範囲)を決定する。 • エディタの⾼さ • 1⾏あたりの⾼さ •
スクロール位置 • その他 29
仮想スクロール 30 例えばこんなCSS div.outer { height: 500px; overflow: auto; }
div.inner { height: 10000px; }
仮想スクロール トレードオフ • DOMが⽣成されていない部分はブラウザ検索が 効かない(別途実装が必要) • など 31
レイアウト計測はコストが⼤きい テキストの⽂法解析 ↓ テキストを構造化 ↓ テキストのデコレーションや様々な状態を適⽤ ↓ ようやくレイアウトが計測できる 32
レイアウト計測はコストが⼤きい 変数が変わるたびに1フレーム内で何度もレイアウ ト計測を実⾏してしまうとフレーム落ちが発⽣する 👉 requestAnimationFrameを使う 33
requestAnimationFrameとは CSSなどでは表現が難しいアニメーションを、 JavaScriptからブラウザのリフレッシュレートにあ わせてスムーズに描画するためのAPIです。 34
ブラウザのレンダリングサイクル • ブラウザはMainスレッドでレ ンダリングを⾏う • 初回は全部通りますが、2回 ⽬以降は差分更新 • 余った時間でクライアント JavaScriptの実⾏も⾏う
35 https://web.dev/learn/performance/understanding-the-critical-path?hl=ja
フレーム落ちとは • 処理時間が⻑いJavaScriptがあると、レンダリン グタイミングが数フレームに1回になる。 • 50ms以上かかるタスクは分割したほうが良いと されています。 36 https://web.dev/articles/long-tasks-devtools?hl=ja
フレーム落ちとは • requestAnimationFrameを使うことで、処理を フレームの先頭に先送りする。 37
requestAnimationFrameの例 アニメーションの場合、 コールバック関数の中で 再帰呼び出しをして、差 分時間から移動距離を算 出する 38 引用: https://developer.mozilla.org/ja/docs/Web/API/windo w/requestAnimationFrame
再帰的に呼び出し 呼び出された時間 開始からの経過時間 時間から移動距離を測る
requestAnimationFrameの例 39 フレームごとにrequestAnimationFrameの コールバックが実行される
CodeMirrorの場合 エディタの状態が更新された時 • テキストのDOM更新は即座に⾏う。 • レイアウト計測はrequestAnimationFrameで次 のフレームの先頭で⾏い、仮想スクロールを更新 40 引用: https://github.com/codemirror/view/blob/6.28.4/src/editorview.ts#L67-L72
ハイライトもコストが⼤きい テキストの⽂法解析 ↓ テキストを構造化 ↓ テキストの選択範囲や様々な状態を反映 41
ハイライトもコストが⼤きい これらをDOM更新と同じタイミングで実⾏するとコ ストが⼤きいのでフレーム落ちが発⽣する可能性が ある。 👉 setTimeout/requestIdleCallbackを使う 42
setTimeoutとは 指定した時間が経過した後にコールバックを実⾏す るAPIです。 ブラウザ環境においては、setTimeoutの待ち時間の 間、ブラウザの処理を実⾏することができる。 43
requestIdleCallbackとは ブラウザのスレッドがアイドル状態のときに実⾏さ れる関数をキューイングできます。優先度が低くコ ストが⼤きい処理をさせるのに有効です。 44
requestIdleCallbackとは 45 ただし、Safariはまだ⾮対応です。
CodeMirrorの場合 requestIdleCallbackが⾮対応環境 • setTimeoutで500ms遅延 requestIdleCallbackが対応環境 • setTimeoutで100ms遅延 • requestIdleCallbackで0~400ms遅延 46
CodeMirrorの場合 47 IdleCallbackで解析 レイアウト 計測して レンダリン グ 大量のコード をペースト 100ms
まとめ 48 • 仮想スクロールは⼤量のデータをパフォーマンス を落とすことなくレンダリングするテクニック。 • レンダリングコストが⼤きい処理はブラウザに⽤ 意されたAPIを⽤いて遅延実⾏させることでフ レーム落ちを抑える。 ◦
requestAnimationFrame ◦ setTimeout ◦ requestIdleCallback
おわりに 49
おわりに • CodeMirrorの実装から学んだ、広く活⽤できそ うな知識‧テクニックをお話しました。 • なにかのお役に⽴てれば幸いです。 • 素晴らしいライブラリと作者に感謝します。 50
None
52