markdown-it-incremental-dom というプラグインを作ってます
markdown-it でパースした Markdown を、 Incremental DOM でレンダリングできるようにするためのプラグイン markdown-it-incremental-dom というものを作ってます。
ようやくブラッシュアップが終わったので、初版 0.1.0 をリリース しました。
markdown-it renderer plugin by using Incremental DOM.
上記のように 差分更新 が可能になり、Markdown の 描画パフォーマンスの向上 が期待できます。
なぜ作ったのか
作るキッカケは拙作の Marp 絡みなんですが、今現在『要所要所のモジュール化を図りながらをボトムアップで作り直していく』という方針をとっています。
当時はフロントエンドの世界に「片足突っ込んでみた」という感じだったので、結果的にアンメンテナブルなコードを産んでしまった上に、そのまま広まってしまった、という反省がありまして…
markdown-it-incremental-dom は、『ライブプレビューのパフォーマンス改善』と『モダンな JS によるモジュールの作り方を学ぶ』の 2 つを兼ねての成果物であり、立てていた計画の最下段にありました。
React じゃダメなの?
- markdown-it → React は既存実装がすでに結構あるので、車輪の再発明になりそうだった
- メモリ効率の点で Markdown AST と Virtual DOM を一緒に持ちたくなかった
- Marp のユーザー規模が大きくなった以上、特定の VDOM 技術へのロックインを避けたかった
一番の理由は最後で、Incremental DOM は Real DOM ベースで差分更新できるので、それほど場所を選ばず活躍できるだろう、と踏んでいます。
メモリ効率に関しては、よっぽど大規模な Markdown で無い限りは、差は雀の涙程度だろうなぁ...
技術的な話
markdown-it は Markdown パーサー (AST を作る) と レンダラ (AST を HTML に変換) に分かれていて、今回作ったプラグインでは、レンダラ部分を Incremental DOM に差し替える、という事をしてます。
完全に Incremental DOM で乗っ取っているわけではなく、既存のレンダリングメソッド(md.render()
)と共存させている(=md.renderToIncrementalDOM()
を生やしている)ため、従来通り HTML 文字列としての出力も可能です。
他プラグインとの互換性
この手のプラグインは、ユーザーによる HTML を許可していたり、他のプラグインで Markdown 構文が拡張されたりした時に対応できないケースが多いですが、markdown-it-incremental-dom は未知の HTML がある場合、部分的にパースし Incremental DOM に変換するようにしています。なので、理論的には互換性アリのはずです(まだユースケースを集め切っていない)。
このパース処理が課題で、現時点では htmlparser2 を使用していますが、必要ない処理 (ノード AST 生成など) が多くて結構ヘビーなので、シンプルな実装に変えたいというのが現状です。Markdown でリアルタイムで incompleted な HTML が打たれると invalid になりがちなので、そのへんを上手いこと処理したいところ。
一方、HTML を出力する markdown-it 標準のルールを Incremental DOM を使うようにする ことで、パース処理自体を減らす処理も実施中です。
ということで
しばらくは、こういったモジュールを小出しにしていくつもりです。
次にやること
Marp Markdown 拡張構文 のプラグイン切り出し。