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
490
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
820
Other Decks in Programming
See All in Programming
[JAWS-UG横浜 #76] イケてるアップデートを宇宙いち早く紹介するよ!
maroon1st
0
460
Jakarta EE meets AI
ivargrimstad
0
240
return文におけるstd::moveについて
onihusube
1
1.1k
useSyncExternalStoreを使いまくる
ssssota
6
1k
Cloudflare MCP ServerでClaude Desktop からWeb APIを構築
kutakutat
1
540
なまけものオバケたち -PHP 8.4 に入った新機能の紹介-
tanakahisateru
1
120
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
110
tidymodelsによるtidyな生存時間解析 / Japan.R2024
dropout009
1
770
開発者とQAの越境で自動テストが増える開発プロセスを実現する
92thunder
1
180
talk-with-local-llm-with-web-streams-api
kbaba1001
0
180
創造的活動から切り拓く新たなキャリア 好きから始めてみる夜勤オペレーターからSREへの転身
yjszk
1
130
rails stats で紐解く ANDPAD のイマを支える技術たち
andpad
1
290
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
229
52k
Thoughts on Productivity
jonyablonski
67
4.4k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
BBQ
matthewcrist
85
9.4k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
111
49k
What's in a price? How to price your products and services
michaelherold
243
12k
KATA
mclloyd
29
14k
Fashionably flexible responsive web design (full day workshop)
malarkey
405
66k
Typedesign – Prime Four
hannesfritz
40
2.4k
Automating Front-end Workflow
addyosmani
1366
200k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
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