検索
ホームページウェブフロントエンドjsチュートリアルJavaScript バンドルのサイズを最小限に抑えるための実践的なヒント

ractical Tips to Minimize Your JavaScript Bundle Size

アートワーク: https://code-art.pictures/

なぜわざわざ?

最近では驚くべきことかもしれませんが、インターネット トラフィックは依然として多くのシナリオで問題となっています。モバイル ネットワークでは多くの場合、データ プランが制限されており、デバイスのバッテリーは無限ではなく、最も重要なことに、サイトの読み込みを待っている間のユーザーの注意力は限られています。だからこそバンドルのサイズが依然として重要なのです。ここでは、考慮すべき 7 つのヒントを紹介します。

1. ES5 にトランスパイルしない

2020 年、私はローカル ソーシャル ネットワークのプロモーション アプリをメンテナンスしていました。これは、ES5 を対象とした典型的な React TypeScript Webpack アプリケーションでした。 webpack 5 がリリースされたとき、私はアップグレードすることにしました。すべてが順調に進みました。エラー分析とユーザーからのフィードバックを監視しましたが、予想外のものは何もありませんでした。 1 週間後、自分のバンドルにアロー関数が含まれていることを偶然発見しました。それは新しい Webpack 機能でした。

ES5 の状態に関する優れた記事は次のとおりです。重要なポイント:

  • 多くのライブラリにはすでに ES6 コードが含まれており、それらのバンドルは ES5 互換ではありません。
  • 世界中で人気のあるサイトのほとんどは ES5 と互換性がありません。あなたのサイトにも ES5 は必要ないかもしれません。
  • ES5 との互換性が依然として必要であることが確実な場合は、ビルド プロセスにライブラリを含める必要があります。

2. 最新の JavaScript 言語機能を理解し、使用する

より優れた、よりコンパクトなコードを作成できる機能をいくつか紹介します。

2.1.発電機

ジェネレーターは、ネストされた構造をトラバースする効率的な方法です。

type TreeNode<t> = {
    left?: TreeNode<t>
    value: T
    right?: TreeNode<t>
};

function* traverse<t>(root: TreeNode<t>): Generator<t> {
    if (root.left) yield* traverse(root.left)
    yield root.value
    if (root.right) yield* traverse(root.right)
}
</t></t></t></t></t></t>

2.2.プライベートクラスフィールド

ミニファイヤは、エクスポートされたオブジェクトであっても、これらのフィールドが外部で使用できないことを確実に認識しており、名前を自由に短縮できます。

ソース

export class A {
  #myFancyStateObject
}

バンドル

export class A{#t}

もちろん、これは TypeScript のプライベート フィールドでは機能しません。tsc がその仕事を終えると、プライベート フィールドであるという知識が消えるからです。

2.3.最新の API

Promise.withResolvers() または Map.groupBy() について聞いたことがありますか?これらの API は、この記事の執筆時点では広く利用可能になっていませんが、間もなく利用可能になる予定です。今すぐ時間をかけてそれらを理解し、数年後にそれらを採用できるように準備してください。

ヒント: 新しい JavaScript API を見つける方法

ブログやポッドキャストは無数にありますが、最も優れた「ニュースレター」は TypeScript リポジトリ内の新しい .d.ts ファイルであると思います。たとえば、es2024.collection.d.ts を開いて、お楽しみください ?

3. コードの重複を避ける

繰り返されるパターンに気づきましたか?

type TreeNode<t> = {
    left?: TreeNode<t>
    value: T
    right?: TreeNode<t>
};

function* traverse<t>(root: TreeNode<t>): Generator<t> {
    if (root.left) yield* traverse(root.left)
    yield root.value
    if (root.right) yield* traverse(root.right)
}
</t></t></t></t></t></t>

コードを繰り返すと、バンドルのサイズが大きくなるだけでなく、各部分の動作を理解しにくくなります。これにより、開発者は既存のユーティリティ関数を特定して再利用する代わりに新しいコードを作成することになり、バンドルがさらに肥大化します。

このトピックに関する優れた資料はすでに豊富にあるので、それを再説明するのではなく、Martin Fowler による古典的な リファクタリング をお勧めします。上記のような単純な例だけでなく、階層の結合やデザインの繰り返しなどの複雑なケースもカバーしています。

それでは、小さな例を改良してみましょう。クランプはパラメーターを配列インデックスの範囲に制限するためによく使用されるようです。そのため、ショートカットを作成できます:

export class A {
  #myFancyStateObject
}

この変更により、n はおそらく整数であることが意図されていることが明示されますが、現在はチェックされていません。また、未処理の特殊なケースである空の配列も強調しています。この小さな重複排除を行うことで、2 つの潜在的なバグも発見しました?

4. オーバーエンジニアリングを避ける

このことわざの正確な出典は覚えていませんが、的を射ていると思います:

オーバーエンジニアリングとは、自分が抱えていない問題を解決することです。

Web 開発の世界では、主に 2 つのタイプのオーバーエンジニアリングを観察しました。

4.1.過度の一般化

このコードを考えてみましょう。パディングは 4px の倍数で、背景色は青の色合いです。これはおそらく偶然ではなく、偶然であれば重複の可能性を示している可能性があります。しかし、本当に汎用 Button コンポーネントを抽出するのに十分な情報があるのでしょうか? それともオーバーエンジニアリングなのでしょうか?

CSS

export class A{#t}

JSX

const clamp = (min, val, max) =>
  Math.max(min, Math.min(val, max))
const x = clamp(0, v1, a.length - 1)
const y = clamp(0, v2, b.length - 1)
const z = clamp(0, v3, c.length - 1)

このアドバイスは「重複を避ける」と多少矛盾します。コードの過剰な重複排除はオーバーエンジニアリングにつながる可能性があります。では、どこで線を引くのでしょうか?私は個人的に、魔法の数字「3」を使用しています。同様のパターンを持つ 3 つの場所を見つけたら、汎用コンポーネントを抽出する時期が来るかもしれません。

青いボタンの場合、新しいコンポーネントを作成するのではなく、少なくともパディングには CSS 変数を使用するのが最善の解決策だと思います。

4.2.不適切なフレームワークの使用

はい、私たちが大好きなもの、Next.js、React、Vue などについて話しています。アプリに DOM 要素レベルでの対話性があまり含まれていない場合、または動的ではない場合、または非常に単純な場合は、他のオプションを検討してください。

  • 静的サイト ジェネレーター — いくつかの厳選されたリストから始めることができます。
    • 注意: 中には React やその他のフレームワークを内部で使用しているものもあります。バンドルの最小化が目標の場合は、別のことを試してください。
  • WordPress などのコンテンツ管理システム。
  • バニラ — 特に次の 2 つの場合に役立ちます。
    • アプリはとてもシンプルです。
    • アプリは DOM をあまり操作しませんが、代わりに、たとえばキャンバス上に何かを描画します。まさにこれと同じようなプロジェクトがあります。

5. 時代遅れの TypeScript 機能を避ける

TypeScript の現在の目標は主に JavaScript の型チェックですが、常にそうであったわけではありません。 ES6 以前の時代には、「より優れた JavaScript」を作成しようとする試みが数多くあり、TypeScript も例外ではありませんでした。一部の機能はその初期に遡ります。

5.1.列挙型

適切に使用するのが難しいだけでなく、非常に冗長な構造に変換されます。

TypeScript

type TreeNode<t> = {
    left?: TreeNode<t>
    value: T
    right?: TreeNode<t>
};

function* traverse<t>(root: TreeNode<t>): Generator<t> {
    if (root.left) yield* traverse(root.left)
    yield root.value
    if (root.right) yield* traverse(root.right)
}
</t></t></t></t></t></t>

JavaScript

export class A {
  #myFancyStateObject
}

公式の TypeScript ハンドブックでは、列挙型の代わりに単純なオブジェクトを使用することを推奨しています。共用体型を考慮することもできます。

5.2.名前空間

ネームスペースは、ESM モジュール以前のソリューションでした。バンドルのサイズが大きくなるだけでなく、名前空間はグローバルであることが意図されているため、大規模なプロジェクトで名前の競合を避けるのは非常に困難になります。

TypeScript

export class A{#t}

JavaScript

const clamp = (min, val, max) =>
  Math.max(min, Math.min(val, max))
const x = clamp(0, v1, a.length - 1)
const y = clamp(0, v2, b.length - 1)
const z = clamp(0, v3, c.length - 1)

名前空間の代わりに ES モジュールを使用します。

注: 名前空間は、グローバル ライブラリの型定義を記述する場合には依然として役立ちます。

6. 小さな最適化を無視しない

これらの小さなトリックのそれぞれにより、バンドル内の数バイトから数十バイトを節約できます。一貫して適用すれば、目に見える結果をもたらすことができます。

6.1.真/偽のプロパティを使用する

たとえば、空の文字列は false です。それが定義されており、空でないことを確認するには、次のように書くだけです:

const clampToRange = (n, {length}) =>
  clamp(0, n, length - 1)
const x = clampToRange(v1, a)
// ...

6.2.場合によっては非厳密な比較を許可する

== を使用して null を未定義に強制したり、その逆を行うことは完全に正当化されると信じています。

.btn-a {
    background-color: skyblue;
    padding: 4px;
}
.btn-b {
    background-color: deepskyblue;
    padding: 8px;
}

6.3.ヌル合体、論理和、およびデフォルトパラメータを使用してデフォルト値を置き換える

<button classname="btn-a" onclick="{handleClick}">
    Show
</button>
// ...
<button classname="btn-b" onclick="{handleSubmit}">
    Submit
</button>

6.4.ワンライナーにアロー関数を使用する

これの代わりに:

enum A {
  x, y
}

これを書きます:

var A;
(function (A) {
    A[A["x"] = 0] = "x";
    A[A["y"] = 1] = "y";
})(A || (A = {}));

6.5.非常に単純なオブジェクトにはクラスを使用しないでください

これの代わりに:

namespace A {
  export let x = 1
}

これを書きます:

var A;
(function (A) {
    A.x = 1;
})(A || (A = {}));

オブジェクトをフリーズして、そのプロパティを変更から保護することもできます。

7. バンドルを定期的に検査する

各バンドラーには、webpack の webpack-bundle-analyzer や Vite の vite-bundle-analyzer など、そのコンテンツを視覚化するツールがあります。次のようなツールは、バンドルに関する一般的な問題を特定するのに役立ちます:

  • ライブラリが不釣り合いな量のスペースを占有します。移行またはアップグレードする時期が来たのでしょうか?
  • プロジェクトのさまざまな部分で 2 つの類似したライブラリが使用されています。統合して 1 つだけを使用できますか?
  • 大きなファイルがバンドル内に存在しますが、ユーザーの 0.5% がアクセスするページ (ライセンス テキストなど) からのみアクセスされます。動的 import() を使用してバンドルを分割できる可能性があります?

これらのツールに加えて、時々手動でバンドルを読んで不規則性を見つけることをお勧めします。たとえば、TypeScript の構成ミスにより、ES6 バンドルに ES5 ヘルパーが含まれたり、ESM プロジェクトに CJS ヘルパーが含まれたりする可能性があります。これらの問題は自動化ツールでは検出できない可能性がありますが、それでも読み込み時間が長くなり、最も貴重な資産であるユーザーの注意が損なわれる可能性があります。


読んでいただきありがとうございます。コーディングを楽しんでください!

以上がJavaScript バンドルのサイズを最小限に抑えるための実践的なヒントの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

Python vs. JavaScript:ユースケースとアプリケーションと比較されますPython vs. JavaScript:ユースケースとアプリケーションと比較されますApr 21, 2025 am 12:01 AM

Pythonはデータサイエンスと自動化により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、データ処理とモデリングのためにNumpyやPandasなどのライブラリを使用して、データサイエンスと機械学習でうまく機能します。 2。Pythonは、自動化とスクリプトにおいて簡潔で効率的です。 3. JavaScriptはフロントエンド開発に不可欠であり、動的なWebページと単一ページアプリケーションの構築に使用されます。 4. JavaScriptは、node.jsを通じてバックエンド開発において役割を果たし、フルスタック開発をサポートします。

JavaScript通訳者とコンパイラにおけるC/Cの役割JavaScript通訳者とコンパイラにおけるC/Cの役割Apr 20, 2025 am 12:01 AM

CとCは、主に通訳者とJITコンパイラを実装するために使用されるJavaScriptエンジンで重要な役割を果たします。 1)cは、JavaScriptソースコードを解析し、抽象的な構文ツリーを生成するために使用されます。 2)Cは、Bytecodeの生成と実行を担当します。 3)Cは、JITコンパイラを実装し、実行時にホットスポットコードを最適化およびコンパイルし、JavaScriptの実行効率を大幅に改善します。

JavaScript in Action:実際の例とプロジェクトJavaScript in Action:実際の例とプロジェクトApr 19, 2025 am 12:13 AM

現実世界でのJavaScriptのアプリケーションには、フロントエンドとバックエンドの開発が含まれます。 1)DOM操作とイベント処理を含むTODOリストアプリケーションを構築して、フロントエンドアプリケーションを表示します。 2)node.jsを介してRestfulapiを構築し、バックエンドアプリケーションをデモンストレーションします。

JavaScriptとWeb:コア機能とユースケースJavaScriptとWeb:コア機能とユースケースApr 18, 2025 am 12:19 AM

Web開発におけるJavaScriptの主な用途には、クライアントの相互作用、フォーム検証、非同期通信が含まれます。 1)DOM操作による動的なコンテンツの更新とユーザーインタラクション。 2)ユーザーエクスペリエンスを改善するためにデータを提出する前に、クライアントの検証が実行されます。 3)サーバーとのリフレッシュレス通信は、AJAXテクノロジーを通じて達成されます。

JavaScriptエンジンの理解:実装の詳細JavaScriptエンジンの理解:実装の詳細Apr 17, 2025 am 12:05 AM

JavaScriptエンジンが内部的にどのように機能するかを理解することは、開発者にとってより効率的なコードの作成とパフォーマンスのボトルネックと最適化戦略の理解に役立つためです。 1)エンジンのワークフローには、3つの段階が含まれます。解析、コンパイル、実行。 2)実行プロセス中、エンジンはインラインキャッシュや非表示クラスなどの動的最適化を実行します。 3)ベストプラクティスには、グローバル変数の避け、ループの最適化、constとletsの使用、閉鎖の過度の使用の回避が含まれます。

Python vs. JavaScript:学習曲線と使いやすさPython vs. JavaScript:学習曲線と使いやすさApr 16, 2025 am 12:12 AM

Pythonは、スムーズな学習曲線と簡潔な構文を備えた初心者により適しています。 JavaScriptは、急な学習曲線と柔軟な構文を備えたフロントエンド開発に適しています。 1。Python構文は直感的で、データサイエンスやバックエンド開発に適しています。 2。JavaScriptは柔軟で、フロントエンドおよびサーバー側のプログラミングで広く使用されています。

Python vs. JavaScript:コミュニティ、ライブラリ、リソースPython vs. JavaScript:コミュニティ、ライブラリ、リソースApr 15, 2025 am 12:16 AM

PythonとJavaScriptには、コミュニティ、ライブラリ、リソースの観点から、独自の利点と短所があります。 1)Pythonコミュニティはフレンドリーで初心者に適していますが、フロントエンドの開発リソースはJavaScriptほど豊富ではありません。 2)Pythonはデータサイエンスおよび機械学習ライブラリで強力ですが、JavaScriptはフロントエンド開発ライブラリとフレームワークで優れています。 3)どちらも豊富な学習リソースを持っていますが、Pythonは公式文書から始めるのに適していますが、JavaScriptはMDNWebDocsにより優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

mPDF

mPDF

mPDF は、UTF-8 でエンコードされた HTML から PDF ファイルを生成できる PHP ライブラリです。オリジナルの作者である Ian Back は、Web サイトから「オンザフライ」で PDF ファイルを出力し、さまざまな言語を処理するために mPDF を作成しました。 HTML2FPDF などのオリジナルのスクリプトよりも遅く、Unicode フォントを使用すると生成されるファイルが大きくなりますが、CSS スタイルなどをサポートし、多くの機能強化が施されています。 RTL (アラビア語とヘブライ語) や CJK (中国語、日本語、韓国語) を含むほぼすべての言語をサポートします。ネストされたブロックレベル要素 (P、DIV など) をサポートします。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。