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の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
目次1. AST抽象構文木を生成する2. ASTのルートノードを作成する3. 子ノードの解析4. テ...
1. 絶対パスまず、ローカル コンピューターでは、ファイルの絶対パスは、当然、ハード ディスク上でフ...
ここでは、v3 のインストールと使用にのみ焦点を当てます。v2 について学びたい場合は、公式 Web...
多くの場合、 Web デザインが完成した後でデザイナーの無知が露呈し、批判されることがあります。彼ら...
この記事では、例を使用して、データベースを削除せずに MySQL 内のすべてのテーブルをすばやく削除...
1. 同時実行性同時実行性は OLTP データベースの最も重要な機能ですが、同時実行性にはリソース...
1. 削除delete は、オブジェクトのプロパティを残さずに削除する唯一の方法ですが、その「代替」...
1. 引き続き PHP スクリプトを使用して実行します。コマンドラインに入力: php /home/...
目次序文分析する初期レンダリング方法初期最適化さらなる最適化方法2序文ほとんどのミニプログラムには、...
ネットワークポートの公開実際、Docker にはネットワーク ポートの公開に関わる 2 つのパラメー...
接続クエリ:これは、2 つのクエリ (またはテーブル) の各行をペアで接続した結果です。つまり、1 ...
現在、プロジェクトを作成しました。インターフェースは次のとおりです。これはフレームセットを使用して行...
1. 疑似クラスを使用して境界線の半分を表示する <!DOCTYPE html> <...
目次配列分割代入オブジェクトの分解代入分割割り当ての適用変数の値の交換関数から複数の値を返すマップ構...
目次1. イベントとは何ですか? 2. イベントの使い方3. バインドタップとキャッチタップの違い4...