日本語版
最新ニュース
科学&テクノロジー

最新のバニラ JavaScript によるメモリ効率の高い DOM 操作のパターン – Frontend Masters Boost

モダンなバニラ JavaScript シリーズを続けましょう。アプリを快適にするためにDOMの更新を管理する際に、過剰なメモリ使用を避けるためのベストプラクティスについて説明します。 驚くほど速い™️。DOM: ドキュメント オブジェクト モデル – 概要HTML をレンダリングすると、ブラウザでレンダリングされた要素のライブ ビューは DOM と呼ばれます。開発者ツールの「要素」インスペクタに表示されるのは次のようになります。本質的にはツリーであり、ツリー内の各要素はリーフです。この要素ツリーの変更に特化した API セットが存在します。一般的な DOM API の簡単なリストを以下に示します。 querySelector() querySelectorAll() createElement() getAttribute() setAttribute() addEventListener() appendChild() これらは documentのように使います const el = document.querySelector("#el");これらは他のすべての要素でも使用できるため、要素参照がある場合はこれらのメソッドを使用でき、その機能はその要素に限定されます。const nav = document.querySelector("#site-nav"); const navLinks = nav.querySelectorAll("a");Code…

最新のバニラ JavaScript によるメモリ効率の高い DOM 操作のパターン – Frontend Masters Boost

1723329890
2024-08-06 09:04:53

モダンなバニラ JavaScript シリーズを続けましょう。

アプリを快適にするためにDOMの更新を管理する際に、過剰なメモリ使用を避けるためのベストプラクティスについて説明します。 驚くほど速い™️

DOM: ドキュメント オブジェクト モデル – 概要

HTML をレンダリングすると、ブラウザでレンダリングされた要素のライブ ビューは DOM と呼ばれます。開発者ツールの「要素」インスペクタに表示されるのは次のようになります。

Chrome 開発ツールの要素パネル

本質的にはツリーであり、ツリー内の各要素はリーフです。この要素ツリーの変更に特化した API セットが存在します。

一般的な DOM API の簡単なリストを以下に示します。

  • querySelector()
  • querySelectorAll()
  • createElement()
  • getAttribute()
  • setAttribute()
  • addEventListener()
  • appendChild()

これらは documentのように使います const el = document.querySelector("#el");これらは他のすべての要素でも使用できるため、要素参照がある場合はこれらのメソッドを使用でき、その機能はその要素に限定されます。

const nav = document.querySelector("#site-nav");
const navLinks = nav.querySelectorAll("a");Code language: JavaScript (javascript)

これらのメソッドはブラウザでDOMを変更するために使用できますが、サーバーJavaScriptでは使用できません( Node.js)DOMエミュレータを使用しない限り、 js-dom

業界として、私たちはこの直接レンダリングのほとんどをフレームワークにオフロードしてきました。すべての JavaScript フレームワーク (React、Angular、Vue、Svelte など) は、これらの API を内部で使用しています。フレームワークの生産性の利点は、手動の DOM 操作による潜在的なパフォーマンスの向上を上回ることが多いことは認識していますが、この記事では、内部で何が行われているのかをわかりやすく説明したいと思います。

そもそもなぜ自分で DOM を操作するのでしょうか?

主な理由はパフォーマンスです。フレームワークは不要なデータ構造を追加して再レンダリングを行う可能性があり、その結果、多くの最新の Web アプリで見られるような、ひどい途切れやフリーズ動作が発生します。これは、ガベージ コレクターがすべてのコードを処理するためにオーバードライブ状態になるためです。

欠点は、DOM 操作を自分で処理するにはコードが増えることです。複雑になる可能性があるため、DOM を手動で操作するよりも、DOM のフレームワークと抽象化を使用する方が開発者にとってより優れたエクスペリエンスになります。いずれにしても、追加のパフォーマンスが必要になる場合があります。それがこのガイドの目的です。

VS Codeは手動のDOM操作に基づいて構築されています

Visual Studio Codeはそのようなケースの1つです。VS Codeは バニラJavaScriptで記述 「可能な限り DOM に近づける」こと。VS Code のような大規模なプロジェクトでは、パフォーマンスを厳密に制御する必要があります。プラグイン エコシステムには多くのパワーがあるため、コアは可能な限りコアかつ軽量である必要があり、それが幅広い採用につながっています。

マイクロソフト Edgeも最近Reactから移行しました 同じ理由です。

直接的な DOM 操作のパフォーマンス (フレームワークを使用するよりも低レベルのプログラミング) が必要な場合は、この記事が役立つでしょう。

より効率的なDOM操作のためのヒント

新しい要素を作成するよりも非表示/表示を優先する

JavaScript を使用して要素を破棄したり作成したりするのではなく、要素を非表示にしたり表示したりして DOM を変更せずに維持する方が、常にパフォーマンスの高いオプションになります。

サーバーは要素をレンダリングし、次のようなクラス(および適切なCSSルールセット)で非表示/表示します。 el.classList.add('show') または el.style.display = 'block' JavaScript を使用して要素を動的に作成して挿入する代わりに、ほとんど静的な DOM では、ガベージ コレクションの呼び出しや複雑なクライアント ロジックがないため、パフォーマンスが大幅に向上します。

回避できる場合は、クライアント上で DOM ノードを動的に作成しないでください。

しかし、支援技術を忘れないでください。視覚的にも支援技術にも隠したい要素がある場合は、 display: none; そうすればいいのですが、要素を非表示にして補助技術のためにそのままにしておきたい場合は、 コンテンツを非表示にする他の方法

好む textContent 以上 innerText 要素の内容を読み取る

innerText このメソッドは、要素の現在のスタイルを認識しているため優れています。要素が非表示かどうかを認識し、実際に何かが表示されている場合にのみテキストを取得します。問題は、スタイルをチェックするこのプロセスによってリフローが強制され、速度が遅くなることです。

コンテンツを読む element.textContent よりはるかに速い element.innerText、好む textContent 可能な場合は要素の内容を読み取ります。

使用 insertAdjacentHTML 以上 innerHTML

insertAdjacentHTML この方法は、 innerHTML 挿入する前に DOM を破棄する必要がないためです。 方法 新しい HTML を配置する場所は柔軟です。たとえば、次のようになります。

el.insertAdjacentHTML("afterbegin", html);
el.insertAdjacentHTML("beforeend", html);Code language: JavaScript (javascript)

最も早いアプローチは insertAdjacentElement または appendChild

アプローチ1: template HTMLテンプレートを作成するタグと appendChild 新しいHTMLを挿入する

最も速い方法は、完全なDOM要素を追加することです。このための確立されたパターンは、