読者です 読者をやめる 読者になる 読者になる

markdown-it-incremental-dom というプラグインを作ってます

markdown-it でパースした Markdown を、 Incremental DOMレンダリングできるようにするためのプラグイン markdown-it-incremental-dom というものを作ってます。

ようやくブラッシュアップが終わったので、初版 0.1.0 をリリース しました。

markdown-it-incremental-dom

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 拡張構文プラグイン切り出し。