最新のWebアプリケーションを作成するためのゲームメーカーのアプローチ

退屈なエントリー



少し前まで、たまたまアメリカの会社のために特定のハードウェアとソフトウェアの複合体の開発に参加していました。 私はバックエンドを開発しました。フロントエンドの少しで、デバイスをクラウドに統合しました( IoT、つまり )。 技術スタックは明確に特定されています。 一言で言えば、右も左もありません。 ある時点で、フロントエンドPOS(Point of Sale)Webアプリケーションを手伝うために投げられました。



問題。 もっと面白くなる



すべては問題ありませんが、Webアプリケーションはアメリカ全土の6000のオフィス(初心者向け)で動作するように開発されました。 結局のところ、インターネットに問題がある可能性があります。 はい、はい、その非常に先進的なアメリカでは! 有線インターネットだけでなく、モバイル通信もカバーする際の問題! つまり 悪いインターネットチャネル(多くの場合モバイル)は、アメリカの小さな都市ではよくある話です。



そして、これはPOSです...ここでは、顧客が立っている、あなたはすぐに請求書を印刷する必要があります...ブレーキがないはずです! そして、livesearch ...最後に議論、推定がありました-彼らはリクエストでトラフィックをロードしませんでした(再び、トラフィック)。 Webアプリケーションはデータを最大限にロードし、同じ検索をローカルで実行することに同意しました。 もちろん、これはデータに関するものであり、そのサイズによってこれを行うことができます。



フロントエンドは、さまざまなサービスから大量のデータを取得しました。 その結果、大量のトラフィックと長時間のページ読み込みが発生します。 一般的に-トラブル。

問題の一部はバックエンド(圧縮、ジオクラスタリングなど)によって解決されますが、これは別の話であり、現在はフロントエンドについてのみです。



キャッシュ



すぐに最初に行われた(これは論理的です)のは、受信したデータをローカルにキャッシュして保存することでした。 可能であれば-セキュリティが許す限り。 一部のデータではlocalStorageを使用することをお勧めします。他のデータではsessionStorageを使用することをお勧めします。適合しないものは単純にメモリに保存できます。 角度を使用したので、 角度キャッシュはこれらの目的非常に適していました。



部分的には、これで問題が解決しました-ページに最初にアクセスしたときに、ページに必要なリソースがロードされました。 さらに、リソースはすでにキャッシュから取得されています。







もちろん、キャッシュの無効化なども行いました。 トラフィックは削減されましたが、最初のページアクセスからの応答は容認できないほど大きいままでした。



バックグラウンドリソースの読み込み



次の論理ステップは、リソースのバックグラウンドロードでした。 メインページにいる間は、メッセージ、アラートなどを確認します。非表示セクションのリソースはバックグラウンドでロードされます。 ユーザーが目的のセクションに切り替えると、データ(または少なくともその一部)が既にキャッシュにあるため、読み込みが不要になり、ページの応答が低下するという考え方です。 最初のオプションは最も簡単です:



$q.all([ Service1.preLoad(), Service2.preLoad(), … ServiceN.preLoad() ]);
      
      





Service.preLoad()は、ページリソースプロミスを返す関数です。



しかし、問題があります-この場合、すべての約束が同時に実行されます。 100500のすべてのリソースが同時にドラッグされます。 そして、チャンネルはゴムではありません! さらに、長時間にわたってゆっくりと大量のデータをダウンロードするサードパーティのサービスに対するメガリクエストがあります。 その結果、すべての並列リクエストは、このメガリクエストとほぼ同じ時間内に実行されました。



OK、順番にロード:



 Service1.preLoad() .then().Service2.preLoad() … .then().ServiceN.preLoad();
      
      





水のように良くなりましたが、それほどではありません-ユーザーがすぐに「間違った」セクションに行った場合、このセクションのリソースに到達するまで、キューがロードされるのを待ちます。 一般的に、無限のヒューリスティックがあります。 パックをロードする方が良いでしょう。何かを並行して個別にロードするなどです。しかし、もっと体系的なアプローチが必要でした。



キュー



また、論理的なステップは、すべてのリソースのロードを動的キューに入れることです。 優先順位 セクションに移動し、そのデータ(またはその一部)がまだキューにある場合、優先度を上げて最初にロードします。 その結果、応答は以前よりも<=になりました。 些細なことですが、素晴らしい。







本当です。ゴム以外の場所がもう1つあります-キャッシュのサイズです。



リソースシステム



この問題を深く理解すればするほど、より多くのdeja vuが生じました-私はすでにそれを経験しました! 限られたメモリリソース、バックグラウンドでのロード、アンロード、優先順位...それは...同じです-典型的なゲームエンジンリソースシステム! あなたは車で行きます-場所はロードされ、それははるかに遅れています-それらはアンロードされます。 もう1つの特別な用語はゲームエンジンを意味します-ストリーミングのサポート...ゲーム開発に5年間費やしました。



だからここに。 実際、Webアプリケーションは、リソースを集中的に使用するゲームの類似物です。 ここにのみ、場所はありませんが、ページ/セクションがあります。 ページはリソースをプルしてキャッシュに入れますが、サイズに制限があるため、何かをアンロードする必要があります。 つまり 類推が適切です。







ゲーム開発の場合のように、Webアプリケーションの問題は、リソースを事前にダウンロードするためにユーザーがどこにいるかを予測することです。 ソリューション#1はもちろん設計です。 予測可能な(場合によっては一意の)ルートに沿ってユーザーを誘導します。 設計では解決できないのは、統計とヒューリスティックです。



アンロードも同じです。 最初にアンロードする対象を理解することのみが必要です。 リソース自体に優先順位を付け、最も優先順位の低いリソースをアンロードします。 またはバンドル全体を叩きます。



実装オプション-たくさん。 最も予測可能なものは、前処理、手動または自動です。 ロケーション/セクションで必要なリソースを指定し、優先順位を何らかの方法で下げる必要があります。



ロッド



そして、Ostapが苦しみました...つまり、Web開発に適用できるgamedevトリックが頭に浮かびました。 その1つが詳細レベルであるLOD (詳細レベル)です。 gamedevでは、テクスチャとモデルに使用されます。 最小限の詳細レベルですぐにワールドをロードし、すでに詳細なテクスチャモデルをストリーミングできます。 そして、プレイヤーは常に何かを見て、プレイすることさえできます。



つまり ダウンロード可能なデータ用のLODシステムが必要です! Webの場合、最も原始的なオプションが適しています-詳細の2つのレベル。 まず、ユーザーに表示される初期データ(たとえば、テーブルの最初のページ)を読み込みます。







すぐにロードされる小さなデータが判明します。 そして、背景...背景はすでにLOD'y「より重い」ロードされています。



圧縮



押せないものを押し出すことは、ゲームメーカーにとってほぼ標準的な作業です。 さて、localStorageの境界を押し広げましょう! LZコンプレッサーを持って行きましょう! はい。ただし、localStorageは文字列のみを保存できます...さて、たとえば、 lz-string.jsでできます 。 圧縮率は同じではありませんが、5MBしか使用できない場合は-20%でさえあります-これはまったく悪くありません! また、ボーナスとして-セキュリティ問題、localStorageにはプレーンテキストではなく、中国語の文字があります。



それから何?



さらに...さらなる思考が未知の深みに突入します。 VFS(仮想ファイルシステム)がメモリ(ゲームのリソースシステムとオペレーティングシステムのファイルシステムの間のレイヤー)に表示されます。 通常、すべてはファイルシステムとしてアクセスできるデータファイルを中心に展開します。 ファイルを読んで、書いてください...しかし、VRC(Virtual REST Call)を作成したらどうでしょう!? その後、インターネットに接続していない場合でも、一般的にWebアプリケーションの操作をサポートできます! もちろんある程度ですが、それでもです。



コントローラはリソースマネージャと通信します。 彼は一度に与えるものを与えることができ、他のすべての要求はVRCに与えられます。 そして、彼は順番に、すでに独立して自分の状態をバックエンドと同期し、ロード時にそれを通知します。







彼らがウェブアプリケーションのオフライン作業について話すとき、 Meteorは必ずすべるでしょう。 もちろんクールですが、私たちは開発スタックのタイトなフレームワークにいました。 提案されたオプションは、ほぼすべてのフレームワークに実装できます。 もちろん予約ありですが、可能です。



しかし、この記事は特にこれについてではありません。 そして、時には予期せずに、過去の過去の事例の経験がどのように現れるかについて...



いいコーディングをしてください、友達!



All Articles