みなさんこんにちは!
タイトルから推測したかもしれませんが、HTML(以降html)の解析について説明します。
前文どういうわけか「X」のアイデアがありましたが、その実装には、すべてのスタイルと利点を備えた計算されたDOMが必要です。 GoogleとYandexは良いことを何も示さなかった。 WebKitにはあらゆる種類のラッパーがありますが、すべてのプラットフォームで機能するわけではなく、大幅にトリミングされています。 JavaScriptを使用して作業するフロントエンドでWebKitがラップされているプロジェクトがあります。 何か試してみましたが、結果は悲惨なものでした。 リソースの消費はそれだけの価値がありました。
ウィッシュリストそして、当時はそうではなかったように、私は望んでいました。
- 野生の依存関係なしでhtmlをレンダリングします。 引き出しだけで、ネットワークはユーザーに落ちます。 言い換えれば、ウィンドウに描画する瞬間までのhtmlの完全な計算。
- JavaScriptエンジンのラッパーをカスタマイズする機能
- 他のプログラミング言語を簡単にラップする機能
そして、私は不平等な戦いに入りました!私は既存のHTMLおよびCSS(以下、cessと呼びます)パーサーを研究しました。
バックエンド開発者である私は、既存のHTMLパーサーが常に好きではありませんでした。 それらはすべて、条件付きで3つのカテゴリに分けられました。
- 独自のHTMLトークン化のアイデアしか持たない、パーシス
- なんらかの仕様に従った構文解析
- 明確に仕様に従っているパーシー
3番目のポイントがあるように思えますが、おそらくトピックを閉じることができますか?! しかし、そうではありません。理由は次のとおりです。既存のパーサーはすべて、「Parsim and Dying」の原則に基づいて構築されています。 これは、html全体をプログラムに渡すと、プログラムが結果を返し、それ以降の操作は不可能で、読み取りのみです。 この事実は、パーサーの範囲を大きく制限します。 発言する価値があります。DOMを使用した作業をより高いレベルにシフトする人がいます。 意味は:パーサーで解析し、ラッパーを介して、たとえばPythonでDOMを操作しようとしますが、これは少しばかげています。
さらに、解析時にストリーム(HTMLを意味する)に侵入することは誰にも許可されていませんでした。 これは、JavaScriptエンジンをスムーズにするために重要です。 長い間説明しませんが、次の理由をお見せします。
HTMLドキュメントの断片:
<script>document.write("<div cl");</script>ass="future"></div>
JSを使用したブラウザーの結果:
... <div class="future"></div>
つまり、結果として、本格的なDIV要素が作成されます。 ところで、SCRIPTタグのトークン化は別の問題です。 描きました
結局、Cですべてをゼロから書くことにしました。 すぐにコードの要件がありました:
- C99サポート
- HTMLパーサーをレンダラーから分離して個別に使用する機能
- 外部依存関係なし
なぜそれがすぐに難しいのか-Cで!? ソリューションは、サードパーティのプログラミング言語のバインディングを簡単に作成できるように、埋め込み可能である必要があります。
さまざまな成功を収めながら、ドラフト形式で実装することができました。
- HTMLパーサー
- パーサーアクセス
- セレクター
- インライン、インラインブロック、ブロック、テーブル...
レンダラーについては長い間書くことができます。「インライン要素レンダラー」という短いフレーズの裏には多くの隠されたものがあります。仕様に従ってフォントを操作し、テキストのサイズを計算し、垂直方向の位置を計算し、テキストをレンダリングするための補助ツリーを構築します。
その結果、2、3年のゆったりした開発の後、ドラフトバージョンを機能するバージョンにリメイクし始めました。 最初は論理的で、HTMLパーサーでした。
現在、HTMLパーサーには次の機能があります。
- HTMLの非同期解析、トークンの処理、ツリーの構築
- html.spec.whatwg.org/multipage仕様に準拠した完全なHTML 5サポート
- 高と低の2つのAPIがあります。 1つ目はパブリックAPIです。これには説明があり、一般的にはすべてが人のものに似ていますが、構造を表示することはできません。 2つ目は、ソースを直接使用することです。
- 要素を操作する機能:追加、削除、変更。
- 要素の属性を操作する機能:追加、削除、変更
- 34の入力エンコーディングをサポートします。 UTF-8のみが出力され、内部での作業はすべてUTF-8のみです
- テキストのエンコードを決定できます。 Unicodeが利用可能になりました:UTF-8、UTF-16LE、UTF-16BE(+ BOM検出)およびロシア語:windows-1251、koi8-r、iso-8859-5、x-mac-cyrillic、ibm866
- シングルモードで動作可能-スレッドなし
- HTMLフラグメントの解析
- 断片(チャンク)に解析します。 HTMLのカットされた部分(任意の場所で引き裂かれた)を与えると、最初にバッファーを蓄積することなく、それらを解析します。
- 外部依存関係はありません
- C99をサポート
- メモリを操作します。 メモリはキャッシュされ、分割してオブジェクトに割り当てられます。 たとえば、10個の要素を削除してから10個の要素を追加しても、新しい要素のメモリは消費されません。
+あらゆる種類の小さいが、長い間書くことができる必要な部分の束。
次の行は、CSSパーサーとレンダリングです。 私はすべてを一人でやっています。「ガソリン」で十分です。
どんな助けも大歓迎です!
ご清聴ありがとうございました! これがお役に立てば幸いです!
パーサー自体PS:コミュニティがこのトピックに興味を持っている場合、レンダリング計算のしくみと、遭遇/遭遇した困難について、焦点を絞った記事を書くことができます。