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. テレポートの紹介1.1. 複数のテレポートを使用する2. テレポートを使用する理由3. テ...
Jsで作ったスライドボタンの具体的なコードは参考までに。具体的な内容は以下のとおりですまずエフェク...
*** ハイパーリンクのスタイル設定の例a:link クリックされる前のハイパーリンクの状態a:vi...
url-loader をダウンロード 糸を追加 -D URLローダー モジュール: { ルール: {...
MySQL には、「group_concat」という関数があります。通常の使用では問題がないかもしれ...
1. MySQL マスター/スレーブ同期とは何ですか?マスター データベースのデータが変更されると、...
1. Dockerをインストールします。参考URL: Docker 入門インストールチュートリアル ...
MySQL での置換例の詳細な説明replace into は insert と似ていますが、rep...
現在の要件は、ファイルのアップロード ボタンがあることです。ボタンをクリックすると、アップロードする...
目次1. コンテナサービスの更新とDockerコンサルの検出1. サービス登録と検出とは何ですか? ...
注: 親コンテナーに高さと :data='Array' および overfolw:h...
Go は、シンプルで信頼性が高く、効率的なソフトウェアを簡単に構築できるオープンソース プログラミン...
DockerデーモンソケットDocker デーモンは、 unix 、 tcp 、 fdの 3 種類の...
<テンプレート> <div class="demo">...
1. HTMLコードコードをコピーコードは次のとおりです。経験値: <span class=...