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
700
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
910
Other Decks in Programming
See All in Programming
メンテが命: PHPフレームワークのコンテナ化とアップグレード戦略
shunta27
0
190
ML.NETで始める機械学習
ymd65536
0
210
Grafana Cloudとソラカメ
devoc
0
180
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
540
SpringBoot3.4の構造化ログ #kanjava
irof
3
1k
Writing documentation can be fun with plugin system
okuramasafumi
0
120
2024年のWebフロントエンドのふりかえりと2025年
sakito
3
260
DRFを少しずつ オニオンアーキテクチャに寄せていく DjangoCongress JP 2025
nealle
2
190
Pulsar2 を雰囲気で使ってみよう
anoken
0
240
プログラミング言語学習のススメ / why-do-i-learn-programming-language
yashi8484
0
140
新宿駅構内を三人称視点で探索してみる
satoshi7190
2
110
Code smarter, not harder - How AI Coding Tools Boost Your Productivity | Angular Meetup Berlin
danielsogl
0
100
Featured
See All Featured
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
29
1k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Product Roadmaps are Hard
iamctodd
PRO
50
11k
Bash Introduction
62gerente
611
210k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
9
500
Automating Front-end Workflow
addyosmani
1368
200k
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
28
9.3k
Building Adaptive Systems
keathley
40
2.4k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.1k
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