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. Dockerの設定2. レジストリとネットワークを作成する3. コンテナを起動する環境説明...
目次マルチアプリケーションの展開1-Tomcat 構成1.1- プロジェクト構成1.2-サービス構成...
元の構成: http { ...... limit_conn_zone $binary_remote...
ここ数年、私は自動化とコンピューターを行ったり来たりしてきました。最近は、機械学習に関連するプロジェ...
このノートでは、 MySQL の B+Tree インデックスとは何ですか?クラスター化インデックスは...
ユーレカ: 1. JDKイメージを構築するEurekaコンテナを起動するjdkフォルダと必要なファイ...
序文最近、私はある要件に遭遇しました。会社の業務上、2 つのデータベース間の一部のテーブルは、リアル...
最近、要素テーブルを使用すると、並べ替えの問題によく遭遇します。単純な並べ替えであれば、要素の公式が...
Linux がすべてのコマンドをサポートしていない場合はどうすればいいですか?すべてのLinuxコマ...
目次1. DOMとは何か2. 要素を選択する3. getElementById() 4. クエリセレ...
1. 父から息子へ子コンポーネントにpropsフィールドを定義し、その型は配列です (フィールド値の...
1. レスポンシブ デザインとは何ですか?レスポンシブデザインとは、ウェブサイトの開発プロセス中に、...
1. 環境バージョンDocker バージョン 19.03.12セントロス7ソル8.6.2 2. Do...
1. 需要ベースには 300 台の新しいサーバーがあり、CentOS7.6 オペレーティング システ...
1. SELECT句を使用して複数のテーブルをクエリするSELECT フィールド名 FROM tab...