ホームページ ウェブフロントエンド jsチュートリアル チャンクバスターズ: 小川を渡らないでください!

チャンクバスターズ: 小川を渡らないでください!

Dec 02, 2024 am 05:00 AM

⚠️ 光過敏症がある場合は、おそらくこれをスキップした方がよいでしょう。
下の静止画像をご覧ください。ライトが高速で点滅し始めます!

Chunk-Busters: Don’t cross the Streams!

インターネットはどのように機能するのでしょうか?

タイトルを思い出してください…ここではストリームについて話しています。

プロトコル、パケット、順序付け、ACK、NACK について話すこともできます…しかし、ここではストリームについて話しています。おそらくご想像のとおり (私はそう信じています =D)、ストリームについては…バイナリまたは文字列のいずれかです。

はい、文字列は送信前に圧縮されます…しかし、フロントエンドとバックエンドの開発で私たちが通常気にするのは…文字列とバイナリです。

次の例では、JS ストリームを使用します。

Node には独自の従来の実装がありますが、前でも後ろでも同じコードのストリームを処理する方法があります。

他の言語でもストリームを扱う独自の方法がありますが、ご覧のとおり…ストリームを扱う実際のコード部分はそれほど複雑ではありません (複雑なことが起こっていないというわけではありません)。

例の問題

複数のソースからのデータを使用する必要があるフロントエンドがあります。

IP/ポートを介して各ソースに個別にアクセスできますが、使いやすさと制御を容易にするために、ソースを API ゲートウェイの背後に配置します。

レポ

リンクにあるリポジトリを確認してください。自分で実行する方法を学習して、実際に試してみてください。

https://github.com/Noriller/chunk-busters

ビデオ

フォローするビデオ バージョン:

https://youtu.be/QucaOfFI0fM

v0 - 単純な実装

ソースがあれば、フェッチし、待機し、レンダリングします。洗い流して繰り返します。

await fetch1();
handleResult(1);
await fetch2();
handleResult(2);
...
await fetch9();
handleResult(9);
ログイン後にコピー
ログイン後にコピー

実際にそんなことをする人はいないだろうと思っているかもしれません…

この例では、何かが間違っていることは明らかですが、これに陥るのはそれほど難しいことではありません。

明らかなことは、遅いということです。リクエストごとに起動して待機する必要があり、それが遅い場合は待機する必要があります。

v1 - 熱心なバージョン

各リクエストを個別に待ちたくないのはわかっているので、すべてを起動して完了するまで待ちます。

await Promise.all([
  fetch1(),
  fetch2(),
  ...
  fetch9(),
]);
handleAllResults(results);
ログイン後にコピー
ログイン後にコピー

これはおそらくあなたがやることなので、良いですよね?

つまり、1 つのリクエストが遅い場合を除いて…これは、たとえ他のリクエストがすべて完了していたとしても…そのリクエストが完了するまでまだ待たなければならないことを意味します。

v2 - よりスマートで熱心なバージョン

遅いリクエストがいくつかあるかもしれないことはわかっているので、それでもすべてを起動して待機しますが、リクエストが到着すると、可能な場合にはその結果に対してすでに何らかの処理を行っているため、最後のリクエストが到着した時点で、他のリクエストはすでに完了しています。

await fetch1();
handleResult(1);
await fetch2();
handleResult(2);
...
await fetch9();
handleResult(9);
ログイン後にコピー
ログイン後にコピー

これが最善の解決策であるはずですよね?

うーん…何か変ですか?

v3 - 私はあなたに嘘をついていました…これが v1 のあるべき姿です

v1 を覚えていますか?はい…これは次のようになります:

http/1 ではまったく同じエンドポイントに対して接続できる数に制限があることがわかりました。それだけではありません…これはブラウザーに依存しており、ブラウザーごとに制限が異なる可能性があります。

http/2 だけを使用して、もう終わりにしようと思うかもしれません…しかし、これが良い解決策だったとしても、フロントエンドで複数のエンドポイントを処理する必要があります。

これに対する良い解決策はありますか?

v4 - ストリームに参加してください!

v0 をもう一度見てみましょう。ただし、ストリームを使用します…

あなたは賢いので、警告によって少しネタバレされていたので、おそらくこれを期待していたのでしょう...でもそうです...以前に表示されていたのは、バックエンドが生成していたデータのすべてではありませんでした。

とにかく…フェッチしながらレンダリングします。

await Promise.all([
  fetch1(),
  fetch2(),
  ...
  fetch9(),
]);
handleAllResults(results);
ログイン後にコピー
ログイン後にコピー

代わりに、到来するストリームをタップすると、到来するデータの塊を使って何かを行うことができます。 (はい! Chat GPT などと同様です。)

v0 がこの問題を処理する最悪の方法であるとしても、ストリームを使用することで大幅に改善されます。合計待機時間が同じであっても、何かを表示することでユーザーをだますことができます。

v5 - v1 も同様ですが、ストリームが含まれています。

http/1 問題は依然として問題となっていますが、繰り返しになりますが、事態の推移はすでに確認できています。

そうだ…もうこれを止めることはできない…だから…

v6 - 1 つの API ですべてを制御!

それとも…できるかもしれません?

ご存知のとおり、フロントエンドは管理しなければならないことが多すぎました…それをバックエンドにオフロードできれば、すべてのソースを処理する 1 つのエンドポイントを持つことができます。

これにより、フロントエンドの複雑さと http/1 の問題が解決されます。

await Promise.all([
  fetch1().then(handleResult),
  fetch2().then(handleResult),
  ...
  fetch9().then(handleResult),
]);
ログイン後にコピー


// usually we do this:
await fetch(...).then((res) => {
  // this json call accumulate all the response
  // that later is returned for you to use
  return res.json()
})
ログイン後にコピー

v7 - そして最後に… 1 つの API、複数のソース、ストリーミング。

私たちは 1 つの API を呼び出します。この API は、すべてのソースを呼び出し、データをストリーミングし、それを処理し、フロントに渡します。フロントは、データを受信したときにレンダリングします。

これに使用されるコードは基本的に表と裏で同じです:

await fetchAll();
handleAllResults(results);
ログイン後にコピー

はい…以上です (最も基本的で簡単な例です)。

バッファに来る文字列を追加し、それを解析し、使用可能なチャンクがあるかどうかを確認し、それを使用し、それを忘れます。これは、少ない RAM で、一度に 1 チャンクずつ、TB のデータを受信/消費できることを意味します。

あなたが何を考えているかはわかります...そしてそれは愚かです...それは狂気でもあります...

うーん、Websocket が欲しいです!

いいえ、家には WebSocket があります!

自宅の WebSocket: 次は?

v8 - 機能しないのは愚かなだけです

あなたは賢いですね、ソースがまだデータを生成しているのであれば、いくつかの変数を更新できるかもしれないと考えたのですね…

この方法により、より多くのデータを取得したり、生成されたものから何かを変更したりするために使用されている 1 つの接続を維持できます。

はい…あなたならできると思います…そして私はあなたの主張に従ってその例を実行しました。 =D

それでも…これは愚かなアイデアです。実際の運用環境でどこで使用できるか、使用できるかどうかはわかりません。おそらく、MPA と Ajax の間の厄介な JS 段階にタイムスリップして、十分な対話性はあったものの、同じサーバーへの接続が十分ではなかった (ブラウザーによっては 2 つしか制限されていなかった!) かもしれません。

それ以外は、わかりません。もし持っているなら…知らせてください。

上の例では、中央のボード、特に「進行状況の境界線」に注目してください。更新され続けていることがわかります。 [ネットワーク] タブを開くと、GET 接続が最後まで閉じられていないことがわかります。また、その 1 つのまだ生きている接続の動作を変更する他のリクエストも複数表示されます。これらはすべてバニラの http/1 で行われます。

次は何でしょうか?

文字列とJSONの比較

この例は、私が作成できる最も基本的なものです。解析しやすいため、JSON の代わりに単純な文字列も使用しています。

JSON を使用するには、文字列を蓄積する必要があります (バックエンド応答を JSON.stringify する必要があるのには理由があります)。

次に、どこで分割するかを確認してからその値を解析するか、そのまま解析します。

最初の方法では、NDJSON について考えてみましょう。JSON 配列の代わりに、新しい行でオブジェクトを区切ると、「より簡単に」分割箇所を見つけて、それぞれを JSON.parse してオブジェクトを使用できます。

後者の場合は、次のように解析します。配列に入っていることがわかり、今度はオブジェクトです。OK 最初のキー、今度はキーの値、次のキー、それをスキップ、次のキー…などなど… 手動で行うのは簡単なことではありませんが、待機中にレンダリングにジャンプするようなものです。これはすべて…ただし、さらに小規模な場合を除きます。

エラー処理

人々はサンプルをホストすることを好みますが、これは自分で実行する必要があります…サンプルをどこかにホストしない理由が明確になったことを願っていますが、もう 1 つは、ここでエラーが発生することを期待していないということです。ネットワークエラーを何よりも優先してください…そうですね…

エラーは処理する必要がありますが、さらに複雑さが加わります。

それを使用する必要がありますか?

たぶん…次第と言えるでしょう…

ストリーミングが解決策となる場所もありますが、ほとんどの場合… await json で十分です (簡単であることは言うまでもありません)。

しかし、ストリームについて学ぶことで、フロントエンドであれバックエンドであれ、いくつかの問題を解決する方法が開かれます。

フロントエンドでは、これをいつでもユーザーを「騙す」ために使用できます。スピナーをどこにでも表示する代わりに、何かが現れたらそれを表示し、時間がかかってもさらに表示することができます。ユーザーの操作をブロックしない限り…スピナーを表示するだけよりも「遅い」ものを作成することもできます。実際には、他のものよりもはるかに速いように感じる .

バックエンドでは、フロントから、データベースから、またはその間にあるものから、データの各チャンクを受信したときに解析できるため、RAM を節約できます。必要に応じてデータを処理し、OOM (メモリ不足) エラーをスローするペイロード全体を待つことなくデータを送信します。 GB または TB のデータ…もちろん、そうしないのはなぜですか?

アウトロ

React は遅いですか?このフロントエンドのサンプル全体は React で作成されており、すべての「ライト」の点滅で起こっている「メイン」の処理のほかに、他にも多くの処理が行われています。

はい…十分に速くすると、サンプルが追いつかずフリーズし始めます。しかし、毎分何千ものレンダリングが簡単に行われるので、ほとんどのアプリケーションには十分だと思います。

そして、いつでもパフォーマンスを向上させることができます。「進行状況の境界線」については、レンダリングで一部を保存する必要がある場合に、遅延値を使用してスムーズにしています…「ライト」については、これと他のパフォーマンスの強化を行うことができます。とタイトルですが、これでは「ライト」の点滅が頻繁に停止するだけになり (良いデモにはなりません)、タイトルの「電気」の下線もそれほど楽しくありません。

この例では、これらすべての「改善」は理想的ではありませんが、通常のアプリケーションの場合は、多くのことを処理できるようにすることができます。さらに何か必要な場合は、別のソリューションを使用してください。

結論

自分の武器庫にストリームを追加しましょう…万能の解決策ではないかもしれませんが、いつかきっと役に立つでしょう。

それを使って何かをしようとしていて、助けが必要な場合は、そうですね…私に電話してください。 =P

以上がチャンクバスターズ: 小川を渡らないでください!の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

JavaScriptエンジン:実装の比較 JavaScriptエンジン:実装の比較 Apr 13, 2025 am 12:05 AM

さまざまなJavaScriptエンジンは、各エンジンの実装原則と最適化戦略が異なるため、JavaScriptコードを解析および実行するときに異なる効果をもたらします。 1。語彙分析:ソースコードを語彙ユニットに変換します。 2。文法分析:抽象的な構文ツリーを生成します。 3。最適化とコンパイル:JITコンパイラを介してマシンコードを生成します。 4。実行:マシンコードを実行します。 V8エンジンはインスタントコンピレーションと非表示クラスを通じて最適化され、Spidermonkeyはタイプ推論システムを使用して、同じコードで異なるパフォーマンスパフォーマンスをもたらします。

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

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

C/CからJavaScriptへ:すべてがどのように機能するか C/CからJavaScriptへ:すべてがどのように機能するか Apr 14, 2025 am 12:05 AM

C/CからJavaScriptへのシフトには、動的なタイピング、ゴミ収集、非同期プログラミングへの適応が必要です。 1)C/Cは、手動メモリ管理を必要とする静的に型付けられた言語であり、JavaScriptは動的に型付けされ、ごみ収集が自動的に処理されます。 2)C/Cはマシンコードにコンパイルする必要がありますが、JavaScriptは解釈言語です。 3)JavaScriptは、閉鎖、プロトタイプチェーン、約束などの概念を導入します。これにより、柔軟性と非同期プログラミング機能が向上します。

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

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

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

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

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

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

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により優れています。選択は、プロジェクトのニーズと個人的な関心に基づいている必要があります。

Python vs. JavaScript:開発環境とツール Python vs. JavaScript:開発環境とツール Apr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

See all articles