1. はじめにJS はシングルスレッドです。つまり、すべてのタスクをキューに入れる必要があり、次のタスクは現在のタスクが完了したときにのみ実行されます。前のタスクに長い時間がかかる場合、次のタスクは待機する必要があります。 Cocos Creator は、基本的に JS である Java Script/Type Script を使用して開発されており、上記の機能も備えています。特に、不適切に使用すると、インターフェースの遅延が発生する可能性が高くなります。 たとえば、 ScrollView のコンテンツに 500 個のノードを作成すると、次のインターフェースがスタックする可能性があります。 PS: 読み込み処理中に読み込みダイアログ ボックスが表示されましたが、スタックしたために表示されなかったようです。 この記事を読むことで、 「フレームロード」技術を使用して上記の問題を解決する方法を学ぶことができます。最終的な効果の比較は次のとおりです。 2. 行き詰まった問題の分析通常の状況では、ScrollViewの子ノードを一定数作成する場合、コードは次のようになります。 パブリックダイレクトロード(長さ: 数値) { (i = 0; i < 長さ; i++) の場合 { this._initItem(i); } } プライベート_initItem(itemIndex: 数値) { itemNode を cc.instantiate(this.itemPrefab); にします。 スクロールビューの幅を 10 に設定します。 アイテムノードの高さ = アイテムノードの幅; 親要素を this.scrollView.content に置き換えます。 アイテムノードの位置を設定します。(0, 0); } 一般的に、長さの値が 10 などの非常に小さい場合、プログラムは実行時に正常に見えるかもしれませんが、より注意深く観察すると、しばらく停止しますが、すぐに終了することがわかります。 特に、長さの値が50以上の特定のレベルに達すると、このコードは上記のスクリーンショットに示すように表示されます。 結局のところ、問題は、このノードに対して この問題をより視覚的に理解したい場合は、次の図のようになります。 直接ロード 明らかに、上の図によると、フレーム 1 から 4 は完全に占有されており、この期間中の他のすべてのロジックの実行が失敗します ([読み込み] ダイアログ ボックスが表示されない、回転アニメーションが停止するなど)。 それで、どうやって解決するのでしょうか? 3. 解決策(理論)学生の中には、Promise を使用して非同期的に問題を解決することを考える人もいるかもしれません。ただし、この場合、Promise は、ノードを継続的に作成する赤いコードを少し後に実行するだけです。しかし、赤いコードが実行されると、その間はコードがスタックしたままになるため、Promise はこの状況に対処できません。 それで、どうやって解決すればいいのでしょうか? その解決策の一つが、今日お話しする「フレームローディング」です。では、 「フレームローディング」とはどのように理解すればよいのでしょうか。 いつものように、これが写真です: フレーム荷重 上の図で「フレームロード」が分かりやすくなりました。具体的な実行プロセスは以下のとおりです。
理論は明確ですが、実際にどのように実行するのでしょうか? 例えば:
現時点では、これを実現するには、ES6 (ES2015) コルーチンである 4. ソリューション(コード)2 番目のセクション (ScrollView の特定の数の子ノードを作成する) で使用したコードを例にとり、コードを複数の小さなセグメントに実装し、各フレームでこれらの小さなセグメントを実行する時間を割り当てます。 4.1 ジェネレータを使用してコードを複数の小さなセクションに分割する分割前: パブリックダイレクトロード(長さ: 数値) { (i = 0; i < 長さ; i++) の場合 { this._initItem(i); } } プライベート_initItem(itemIndex: 数値) { itemNode を cc.instantiate(this.itemPrefab); にします。 スクロールビューの幅を 10 に設定します。 アイテムノードの高さ = アイテムノードの幅; 親要素を this.scrollView.content に置き換えます。 アイテムノードの位置を設定します。(0, 0); } 分割後: /** * (新しいコード) 子ノードを生成するジェネレーターを取得します */ プライベート *_getItemGenerator(長さ: 数値) { (i = 0; i < 長さ; i++) の場合 { this._initItem(i) を生成します。 } } /** * (分割前のコードと同じ) */ プライベート_initItem(itemIndex: 数値) { itemNode を cc.instantiate(this.itemPrefab); にします。 スクロールビューの幅を 10 に設定します。 アイテムノードの高さ = アイテムノードの幅; 親要素を this.scrollView.content に置き換えます。 アイテムノードの位置を設定します。(0, 0); } ここでの原則は、Generator を使用して 1 つの for ループですべてのノードを作成し、 for ループの各ステップを小さなセグメントに分割することです。 もちろん、この「分割」コードは分割ステップのみを実装しているため実行できません。実行するには、以下の2番目のコードが必要です。 4.2 実行するためにフレームごとに時間を割り当てる今撮った写真を見てみましょう。 フレーム荷重 この図から、結果として得られるコードは /** * フレーム読み込みを実装する*/ 非同期フレーミングロード(長さ: 数値) { this.executePreFrame(this._getItemGenerator(length), 1) を待機します。 } /** * フレーム内でジェネレータロジックを実行する* * @param generator ジェネレーター * @paramduration 期間 (ミリ秒) * ジェネレーター操作が実行されるたびに、実行の最大期間。 * 値が 8ms であると仮定すると、1 フレーム (合計 16ms) で、このロジックの実行に 8ms が割り当てられることを意味します */ プライベートexecutePreFrame(ジェネレータ: ジェネレータ、期間: 数値) { 新しい Promise を返します ((resolve, reject) => { gen = ジェネレータとします。 // 実行関数を作成する let execute = () => { // 実行前に開始タイムスタンプを記録します。let startTime = new Date().getTime(); // 次に、ジェネレータから分割されたコードセグメントを取得して実行し続けます for (let iter = gen.next(); ; iter = gen.next()) { // すべてのジェネレータが実行されたかどうかを確認します // そうであれば、タスクは完了です if (iter == null || iter.done) { 解決する(); 戻る; } // 各小さなコードセグメントが実行された後、これらの小さなコードセグメントに対してこのフレームに割り当てた最大実行時間を超えていないかどうかを確認します。if (new Date().getTime() - startTime >duration) { // 制限を超えると、現在のフレームは実行されません。タイマーを開始して次のフレームを実行します。this.scheduleOnce(() => { 実行する(); }); 戻る; } } }; // 実行関数を実行します。execute(); }); } コードには多くのコメントが付けられていますが、言及する価値のある点がいくつかあります。
今のところ、ある程度の「フレームロード」は実現できています~ このプロジェクトのすべての図とコードは Github リポジトリにあります。検証を実行する必要がある場合は、自分でコードを検証しなくても、プロジェクトを直接プルダウンできます。
V. 結論
以上がCocosCreator ScrollView最適化シリーズのフレーム読み込みの詳細です。CocosCreator ScrollView最適化フレーム読み込みの詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
B-Tree インデックスに加えて、MySQL は次のインデックスも提供します。ハッシュインデックス...
この記事では、参考までに、簡単な計算機を実装するためのJavaScriptの具体的なコードを紹介しま...
1. PRIMARY KEY(主キーインデックス)を追加するmysql>ALTER TABLE...
HTML コードを書くとき、最初の行は DOCTYPE にする必要がありますが、DOCTYPE は通...
この記事では、MySQL 8.0.15のインストールと設定方法を参考までに紹介します。具体的な内容は...
数日前に仕事を始めて、Mysql をインストールしたところ、開くことができました。今日、会社に行った...
1 実施原則これは、DOM 要素の dragstart/ondragover/ondrop イベント...
目次意味文法例1. 初期値initが渡されない2. 初期値を渡す場合3. アレイの重複排除4. Re...
nginx サーバーnginx は、静的ファイルの処理に非常に効率的な優れた Web サーバーです。...
まず、MySQL とは何かを簡単に紹介します。簡単に言えば、データベースはデータを格納するための倉庫...
この記事では、MySQL ユーザー権限管理の例について説明します。ご参考までに、詳細は以下の通りです...
この記事では、MySQL の null (IFNULL、COALESCE、NULLIF) に関連する...
質問があります。Dreamweaver で、3 行 1 列のログイン フォーム (ログイン、登録、パ...
HTML は Hypertext Markup Language の略です。現在、ほとんどの Web...
既存のビデオ プレーヤーがニーズを満たせない場合は、ビデオを自分でカプセル化する必要があります。ビデ...