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
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
igarashi
July 07, 2024
Programming
2.2k
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Webエディタライブラリ 「CodeMirror」から学ぶ Webアプリ開発のテクニック
2024/07/05に開催されたDevelopersIO 2024 SAPPOROにて登壇したセッションの資料です。
igarashi
July 07, 2024
More Decks by igarashi
See All by igarashi
生成AIを活用したZennの取り組み事例
ryosukeigarashi
0
840
Zennのパフォーマンスモニタリングでやっていること
ryosukeigarashi
0
1.3k
Other Decks in Programming
See All in Programming
「つくるAI」だけではバグは見つからない ~テストに必要な「見つけるAI」を分離させる戦略~
mfunaki
0
200
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
3
2.2k
FastAPI の並行処理モデルを完全に理解する
hoto17296
8
3.1k
ALB ログから Trace を気合で繋げる技術
fohte
7
760
AWS Transform Customによる Spring Boot 2.xから4.xへのVerUp
satoshi256kbyte
2
110
PyConJP2026_wat_Python × Signal Processing: How to Draw Pictures with Sound Using Spectrogram Art
wat
0
570
関東Kaggler会_NVIDIA_Nemotron_コンペ_振り返り
rick_ds
0
730
AIと壁打ちしながら進めるコスト管理
fufuhu
2
1.8k
高専キャリア LT 発表内容
crysta1221
2
3.5k
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
120
DynamoDBの基礎を振り返りながらベクトル検索機能を理解する
musan
2
240
業務時間外もAIに働いてもらう話
colorful12
2
8.3k
Featured
See All Featured
Un-Boring Meetings
codingconduct
0
400
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
210
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
180
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Scaling GitHub
holman
464
140k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
260
Git: the NoSQL Database
bkeepers
PRO
432
67k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
480
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.1k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
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