「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > React、Node.js、MongoDB を使用した高性能フルスタック アプリの構築: スケーラビリティ、スピード、ソリューションの旅

React、Node.js、MongoDB を使用した高性能フルスタック アプリの構築: スケーラビリティ、スピード、ソリューションの旅

2024 年 11 月 2 日に公開
ブラウズ:210

Building High-Performance Full-Stack Apps with React, Node.js & MongoDB: A Journey in Scalability, Speed & Solutions

本番アプリを開くと、アプリが停止しかけていることに気づきました。フロントエンドが応答しません。バックエンド API がタイムアウトになります。 MongoDB クエリは無期限に実行されているように見えます。あなたの受信箱にはユーザーからの苦情が溢れています。あなたのチームは集まって状況を優先順位付けしようとします。

そこにありましたか?はい、私もです。

私は上級フルスタック開発者ですが、単一ユーザーとしてのみ使用しているときや、問題の領域が単純なときは問題なく動作するアプリにはうんざりしていますが、実際のトラフィックや環境下では機能しなくなってしまいます。もう少し要求の厳しい作業です。

React、Node.js、MongoDB を使用してこれらの懸念事項にどのように対処したかを説明します。

また単純なチュートリアルを紹介するだけではなく、ストーリーを共有します。現実世界の問題に取り組む方法と、時間の試練や何が投げられても乗り越えられる、高速かつスケーラブルなアプリケーションを構築する方法についての物語。

1: React がボトルネックになったとき

私の職場では、React で開発した Web アプリのアップデートを公開したところです。私たちはユーザーが新機能を高く評価してくれると信じて自信に満ちていました。

しかし、苦情が寄せられるようになるまでに時間はかかりませんでした。アプリの読み込みが非常に遅く、遷移が途切れ、ユーザーはますます不満を募らせていました。新しい機能が有益であることはわかっていたにもかかわらず、誤ってパフォーマンスの問題を引き起こしてしまいました。私たちの調査により、問題が明らかになりました。アプリはすべてのコンポーネントを 1 つのパッケージにバンドルしており、ユーザーはアプリにアクセスするたびにすべてをダウンロードする必要がありました。

修正: 遅延読み込みと呼ばれる非常に便利な概念を実装しました。このアイデアは以前にも思いつきましたが、まさに私たちが必要としていたものでした。アプリの構造を完全に刷新し、必要なときに必要なコンポーネントのみをロードするようにしました。

このソリューションをどのように実装したかを簡単に説明します:

const Dashboard = React.lazy(() => import('./Dashboard'));
const Profile = React.lazy(() => import('./Profile'));

Loading...}>
  

結果: この変更の影響は驚くべきものでした。バンドルでは 30% もの大幅な縮小が見られ、ユーザーは初期読み込みが大幅に高速化されました。最も良かったのは、アプリの特定の部分がまだ読み込まれていることにユーザーが気づいていなかったことです。私たちはサスペンスを賢明に使用し、シンプルで邪魔にならない読み込みメッセージを表示しました。

2: React でステート管理という野獣を飼いならす

数か月が経った今、私たちの開発チームは本領を発揮し、多くの新機能をリリースしていました。しかし、成長に伴い、私たちは意図せずして、より複雑なアプリと呼ぶものを構築し始めました。 Redux はすぐに、単純な対話を促進するのに役立つというよりも、むしろ厄介な存在になりました。

そこで、より良い代替案を求めて時間をかけて概念図を作成しました。私はその結果を文書化し、そのアプローチがどのようなものであるかについて複数の知識共有会議を促進しました。私たちは最終的に、状態を管理するための提案ソリューションとして React Hooks (特に useReducer) を試すことをグループとして決定しました。最終的には、よりシンプルなコードと、多くの小規模な自己完結型の Redux の新しいバージョンで増加するオーバーヘッドによる膨大なランタイム フットプリントを減らしたかったからです。状態。

その後の変革はまさに革命的でした。私たちは、数十行の定型コードを簡潔で理解しやすいフック ロジックに置き換えていることに気づきました。この新しいアプローチをどのように実装したかを示す例を次に示します:

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count   1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

const CounterContext = React.createContext();

function CounterProvider({ children }) {
  const [state, dispatch] = useReducer(reducer, initialState);
  return (
    
      {children}
    
  );
}

結果: この移行の影響は深刻かつ広範囲に及びました。私たちのアプリケーションは大幅に予測可能になり、推論が容易になりました。コードベースはより無駄がなく、より直観的になったので、チームはより速いペースで反復できるようになりました。おそらく最も重要なことは、当社の若手開発者がコードベースをナビゲートして理解する能力が著しく向上したと報告したことです。その結果、双方にとって有利な状況が生まれました。保守するコードが減り、潰すべきバグも減り、開発チームは著しく幸せになり、生産性が向上しました。

3: バックエンドの戦場を征服する — Node.js API を最適化して最高のパフォーマンスを実現する

フロントエンドに多くの改善を導入することができましたが、直後にバックエンドで複数の問題が発生しました。 API のパフォーマンスがひどくなり、特にいくつかのエンドポイントのパフォーマンスが最悪になり始めました。これらのエンドポイントは、さまざまなサードパーティ サービスに対して一連の呼び出しを行いますが、ユーザーベースが拡大するにつれて、システムはこの負荷を処理できなくなりました。

何が間違っていたのかは非常に常識的でした。私たちはパラレルではありませんでした!つまり、各エンドポイントへのリクエストは順次処理されます。つまり、次の呼び出しはすべて、前の呼び出しが完了するまで待機します。この大規模 (数十万リクエスト) システムでは、悲惨な結果になることが判明しました。

解決策: これを修正するために、多くのコードを書き直し、Promise.all() の機能を利用して API リクエストを同時実行することにしました。つまり、複数のリクエストを開始しても、すべての呼び出しが終了するまで次のリクエストを開始するまで待つ必要はありません。

そのために、API 呼び出しを開始したり、完了するまで待機したり、別の呼び出しを作成したりすることはありません…

単純に Promise.all() を使用する代わりに、すべてが一度に起動され、はるかに高速になりました。

このソリューションをどのように実装したかを簡単に説明します:

const getUserData = async () => {
  const [profile, posts, comments] = await Promise.all([
    fetch('/api/profile'),
    fetch('/api/posts'),
    fetch('/api/comments')
  ]);
  return { profile, posts, comments };
};

結果: この最適化の影響は即時かつ多大なものでした。応答時間の 50% の顕著な短縮が観察され、バックエンドは高負荷時の回復力が大幅に向上していることが実証されました。ユーザーはイライラする遅延を経験することがなくなり、サーバーのタイムアウト数が劇的に減少しました。この機能強化により、ユーザー エクスペリエンスが向上しただけでなく、システムがパフォーマンスを損なうことなく、より大量のリクエストを処理できるようになりました。

4: MongoDB クエスト — データ野獣を飼いならす

私たちのアプリケーションが注目を集め、ユーザーベースが桁違いに増加するにつれ、私たちは新たな障害に直面する必要がありました。それは、そのデータをどのように拡張するかということです。かつては応答性が高かった MongoDB インスタンスが、数百万のドキュメントを処理する必要があるときに動作を停止し始めました。以前はミリ秒単位で実行されていたクエリが完了するまでに数秒かかった、またはタイムアウトになりました。

私たちは数日かけて MongoDB のパフォーマンス分析ツールを調査し、インデックスのないクエリという大きな悪者を特定しました。最も一般的なクエリの一部 (ユーザー プロファイルのリクエストなど) は、強固なインデックスを使用できるコレクション全体をスキャンしていました。

解決策: 入手した情報をもとに、最もリクエストの多かったフィールドに複合インデックスを作成するだけで済み、これによりデータベース本体の検索時間を完全に修正できることがわかりました。ここでは、「ユーザー名」フィールドと「電子メール」フィールドに関してどのように行ったかを示します。

db.users.createIndex({ "username": 1, "email": 1 });

結果: この最適化の効果は驚くべきものでした。以前は実行に最大 2 秒かかっていたクエリが 200 ミリ秒未満で完了するようになり、パフォーマンスが 10 倍向上しました。私たちのデータベースは機敏な応答性を取り戻し、目立った速度低下を引き起こすことなく、大幅に大量のトラフィックを処理できるようになりました。

しかし、そこで終わりではありませんでした。当社の急速な成長軌道は今後も続く可能性が高いと認識し、長期的な拡張性を確保するために積極的な措置を講じました。データを複数のサーバーに分散するためにシャーディングを実装しました。この戦略的決定により、水平方向の拡張が可能になり、ユーザー ベースの拡大と並行してデータ処理能力も確実に向上しました。

5.マイクロサービスの採用 — スケーラビリティのパズルを解決する

ユーザー ベースが増加し続けるにつれて、インフラストラクチャを拡張する必要があるだけでなく、自信を持って拡張できるようにアプリケーションを進化させる必要があることがますます明らかになりました。モノリシック アーキテクチャは、小規模なチームだったときは適していましたが、時間が経つにつれて非常に煩雑になってきました。私たちは、思い切ってマイクロサービス アーキテクチャに向けた構築を開始する必要があることを認識していました。これは、どのエンジニアリング チームにとっても恐ろしい作業ですが、スケーラビリティと信頼性には大きな利点があります。

最大の問題の 1 つは、サービス間の通信でした。私たちのケースでは HTTP リクエストは実際には機能せず、膨大な量の操作が休むことなく応答を待っており、やることが多すぎると必要に応じてプログラムが強制終了されてしまうため、システムにもう 1 つのボトルネックが残りました。この時点で、RabbitMQ を使用するのが明白な答えであることがわかったので、あまり考えずにそれを適用しました。

このソリューションをどのように実装したかを簡単に説明します:

const amqp = require('amqplib/callback_api');

amqp.connect('amqp://localhost', (err, conn) => {
  conn.createChannel((err, ch) => {
    const queue = 'task_queue';
    const msg = 'Hello World';

    ch.assertQueue(queue, { durable: true });
    ch.sendToQueue(queue, Buffer.from(msg), { persistent: true });
    console.log(`Sent ${msg}`);
  });
});

結果: RabbitMQ を介して行われた通信と移行自体は、私たちの観点からは魔法のように見えました…そして数字がそれを裏付けました!!!私たちは、各サービスが独自に拡張できる疎結合マイクロサービスの幸運な所有者になりました。突然、具体的な DNS ゾーンで実際のトラフィックが急増しましたが、システムがダウンするという恐怖はありませんでした (サービス操作は常にカスケードされるため、どのサービス操作を要求しても同じであるため) が、残りの部分/操作が静かに手を挙げて「」と言うだけだったので、うまく機能しました。眠れますよ、愛しい人よ。メンテナンスも容易になり、問題が少なくなり、新しい機能やアップデートの追加がより速く、より確実に操作できるようになりました。

結論: 将来のイノベーションへの道筋を描く

このスリリングな旅の各ステップは教訓であり、フルスタック開発はコードを書くだけではないことを思い出させてくれました。フロントエンドの高速化や障害に耐えられるバックエンドの構築から、ユーザー ベースが爆発的に増加する間に拡張するデータベースの処理に至るまで、相互に関連する複雑な問題を理解し、解決することです。

2024 年後半以降に目を向けても、Web アプリケーションに対する需要の増加は止まらないでしょう。スケーラブルでパフォーマンスが最適化され、適切に設計されたアプリケーションの構築に集中し続ければ、今日のあらゆる問題を解決でき、将来的には他の課題を活用できる立場にあります。これらの実体験は、私のフルスタック開発への取り組み方に大きな影響を与えました。そして、これらの影響が今後も私たちの業界をどのように推進していくのかを見るのが待ちきれません!

しかし、あなたはどうですか?あなたも同様の障害に直面したことがありますか? あるいは、これらの問題を克服するための他の創造的な方法で幸運に恵まれたことはありますか?あなたのストーリーや洞察をぜひお聞きしたいです。コメント欄で知らせていただくか、私と連絡を取ってください!

リリースステートメント この記事は次の場所に転載されています: https://dev.to/mukhilpadmanabhan/building-high-performance-full-stack-apps-with-react-nodejs-mongodb-a-journey-in-scalability-speed-solutions-3fk0? 1 権利侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>
  • PHP で文字列を操作する
    PHP で文字列を操作する
    文字列は、プログラミングで文字のシーケンスを表すために使用されるデータ型です。これらの文字には、文字、数字、スペース、記号などを使用できます。多くのプログラミング言語では、文字列は一重引用符 (') または二重引用符 (") で囲まれます。 文字列の連結 連結は、2 つ以上の文字列...
    プログラミング 2024 年 11 月 8 日に公開
  • rimmel.js でのイベント マッパーの使用: 簡単な概要
    rimmel.js でのイベント マッパーの使用: 簡単な概要
    コードの全体的な品質を向上させたい場合は、データ モデルを基礎となるビューからきちんと分離しておくとよいでしょう。 Observable を完全にサポートする Functional-Reactive フレームワークや、Rimmel.js のような UI ライブラリを使用すると、あまり知られていない設...
    プログラミング 2024 年 11 月 8 日に公開
  • C++ ではオペランドの評価順序が指定されていないのはなぜですか?
    C++ ではオペランドの評価順序が指定されていないのはなぜですか?
    C におけるオペランドの評価順序 数式では、オペランドの評価順序は固定されていると想定されることがよくあります。ただし、 C などのプログラミング言語では、評価の順序が指定されていないため、予期しない結果が生じる可能性があります。式 a b について考えてみましょう。この式では、オペランド a と ...
    プログラミング 2024 年 11 月 8 日に公開
  • phpMyAdmin の既存のテーブルに CSV ファイルをインポートするにはどうすればよいですか?
    phpMyAdmin の既存のテーブルに CSV ファイルをインポートするにはどうすればよいですか?
    既存のテーブル列を使用した phpMyAdmin への CSV のインポート既存のデータベース テーブルへの CSV ファイルのインポートは、phpMyAdmin を通じて実行できます。新しいテーブルの作成を回避するには、次の手順に従ってください:phpMyAdmin を開いてデータベースを選択しま...
    プログラミング 2024 年 11 月 8 日に公開
  • PDO_ODBC を使用して Access から UTF-8 アクセント付き文字を正しく取得する方法
    PDO_ODBC を使用して Access から UTF-8 アクセント付き文字を正しく取得する方法
    PDO_ODBC 経由で Access から UTF-8 アクセント記号付き文字を取得できませんPHP ODBC、特に PDO_ODBC 経由で Access データベースからデータを取得しようとすると、非標準です文字が正しくインポートされず、特殊文字の代わりに疑問符が表示されるなどの問題が発生する...
    プログラミング 2024 年 11 月 8 日に公開
  • Java の登場 新機能 ?
    Java の登場 新機能 ?
    Java 23 が正式にリリースされました。これは非 LTS (長期サポート) リリースです。短期間のバージョンではありますが、Java 23 にはエキサイティングな改善、バグ修正が満載されており、また、注意を払う必要がある削除された機能やオプションも含まれています。 新機能と、それが JDK 21...
    プログラミング 2024 年 11 月 8 日に公開
  • jQuery を使用してキーボードの Enter キーを検出する方法: 包括的なガイド
    jQuery を使用してキーボードの Enter キーを検出する方法: 包括的なガイド
    jQuery を使用したキーボード Enter キーの検出: 総合ガイドインタラクティブな Web アプリケーションを構築する場合、ユーザー入力の検出は非常に重要です。一般的なタスクの 1 つは、Enter キーの押下をキャプチャすることです。この記事では、jQuery を使用してこれをシームレスに...
    プログラミング 2024 年 11 月 8 日に公開
  • 文字列と文字列
    文字列と文字列
    弦 小文字の文字列は、JavaScript の プリミティブ データ型です。 この型で作成された文字列はオブジェクトではありませんが、JavaScript は自動的に文字列を String オブジェクトでラップします (これを「ボックス化」と呼びます)。 let imAString...
    プログラミング 2024 年 11 月 8 日に公開
  • C++ と Python で出力文字列を右揃えにする方法
    C++ と Python で出力文字列を右揃えにする方法
    右揃えで出力文字列をフォーマットするテキスト ファイルを操作する場合、データを一貫して揃えることで読みやすさと分析を向上させることができます。 C では、出力文字列を右揃えでフォーマットするにはどうすればよいのかという疑問が生じます。Python のフォーマット構文を使用すると、解決策は簡単です。l...
    プログラミング 2024 年 11 月 8 日に公開
  • ハクトーバーフェスト第 2 週
    ハクトーバーフェスト第 2 週
    2 週目では、問題の検索に費やす時間が減りました。今回は、Mattermost のドキュメント Web サイトのダーク モードで発生したバグで、特定のボタンの色が正しくなくなりました。 Docusaurus のことは知っています。他のドキュメントや、それをベースに構築されたコース教材サイトの一部を見...
    プログラミング 2024 年 11 月 8 日に公開
  • Python の Try/Except と If/Else: どちらのアプローチがより効果的ですか?
    Python の Try/Except と If/Else: どちらのアプローチがより効果的ですか?
    Try/Except と If/Else: どちらのアプローチが好ましいですか?Python で例外を扱う場合、開発者は多くの場合ジレンマに直面します。有効性をテストするか、アクションを試行して結果として生じる例外を処理するかどうか。この記事では、各アプローチのニュアンスを詳しく掘り下げ、意思決定に...
    プログラミング 2024 年 11 月 8 日に公開
  • Git リモート ブランチ
    Git リモート ブランチ
    今週、他の人のリポジトリに機能を追加する必要がありました。具体的には、CLI ツールのデフォルト パラメータを含むデフォルト設定 TOML ファイルをユーザーの $HOME フォルダ内に追加する必要がありました。 readMeMaker リポジトリに貢献しました: https://github.co...
    プログラミング 2024 年 11 月 8 日に公開
  • 単純な操作の場合、ストリームは常に従来のコレクションよりも遅いですか?
    単純な操作の場合、ストリームは常に従来のコレクションよりも遅いですか?
    Java 8 ストリームのパフォーマンスと従来のコレクションあなたは最近 Java 8 に挑戦し、そのストリーム API のパフォーマンスを従来のコレクションと比較する非公式のベンチマークを実施しました。テストには、整数のリストのフィルター処理、偶数の平方根の抽出、結果の Double リストへの保...
    プログラミング 2024 年 11 月 8 日に公開
  • 母国語を追加できる言語 API。
    母国語を追加できる言語 API。
    2016 年 4 月に、私は大好きな部族「イゲデ語」のための辞書プロジェクトを作成するというアイデアを思いつきました。ネイティブスピーカーではありません。 これが私にイゲデ言語から 5,000 語以上の単語を書いて英語に翻訳するきっかけになりました。これは間違いなく、私がこれまでに取り組んだ、ある...
    プログラミング 2024 年 11 月 8 日に公開
  • Playwright、TypeScript、JavaScript を使用した自動化
    Playwright、TypeScript、JavaScript を使用した自動化
    TypeScript を使用した劇作家 | JavaScriptのインストール Playwright は、Puppeteer チームとの協力による Microsoft の最新の Web ベースの API 自動化ツールです。Puppeteer は、DevTools プロトコルまたは WebDriver...
    プログラミング 2024 年 11 月 8 日に公開

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3