【Ionic3】実機では描画が崩れるが開発者ツールの検証では正常
Ionic3で実機では表示が崩れるのに、開発者ツールでは正常な状態として扱われる現象がありました。
その発生原因モーダル内でnavCtrl.push()でPageを表示していたことでした。
まずはどういう風に画面が崩れたかを説明します。
実機で表示が崩れたスクリーンショット
実機は、Android7.0のASUSの端末で、タブレットでもスマホでも再現しました。
条件を満たすと、上記のスクリーンショットのように、表示が崩れます。
ただし、毎回同じというわけではありません。画面が真っ白になるような場合もありました。
表示の崩れ方はランダムです。
表示崩れの原因
開発者ツールでメモリの計測などを行いましたが、負荷を上げても再現しませんでした。
検証を繰り返すうちに、どうやら、Ionic の ModalControllerが関係しているらしいということがわかってきました。
検証用にHomeというPageを作成し、navCtrlのPushとModalのCreateが行えるように作成しました。
<!-- home.html --> <ion-header> <ion-navbar> <ion-title>Home</ion-title> </ion-navbar> </ion-header> <ion-content padding> <div padding> <ion-list> <ion-item> <ion-label>toggle1</ion-label> <ion-toggle></ion-toggle> </ion-item> <ion-item> <ion-label>toggle2</ion-label> <ion-toggle></ion-toggle> </ion-item> <ion-item> <ion-label>toggle3</ion-label> <ion-toggle></ion-toggle> </ion-item> <ion-item> <button ion-button (click)="push()" tappable>Push HomePage</button> </ion-item> <ion-item> <button ion-button (click)="ModalCreate()" tappable>Show Modal</button> </ion-item> </ion-list> </div> </ion-content>
// home.ts import { Component } from '@angular/core'; import { NavController, ModalController } from 'ionic-angular'; @Component({ selector: 'page-home', templateUrl: 'home.html' }) export class HomePage { constructor ( public navCtrl: NavController, public modalCtrl: ModalController ) {} push() { this.navCtrl.push(HomePage); } ModalCreate() { this.modalCtrl.create(HomePage).present(); } }
this.navCtrl.push(HomePage); を行なった場合は、開発者ツールでみると以下の画像のようになっています。
HomeというPageのみでPushを行なっているため、page-homeというカスタムタグのみが追加されています。
さて、ここで注目すべきは、アクティブではないPageにはhidden属性が付与されている点です。
hidden属性を付与することで、ブラウザのLayout計算から除外されるため、処理が高速化されています。
続いて、ModalCreateを行なった場合です。
page-homeとは別の、Modalを生成する専用の場所にion-modalというカスタムタグが生成されます。
ModalCreateの場合は、hidden属性が付与されません。
この状態でModalCreateを繰り返すと、hidden属性が付いていないカスタムタグがどんどんと生成されるため、無用な計算コストがかかり、表示が崩れます。
私の場合、modalを20〜30個程度表示すると、実機で表示がくずれました。
とはいえ、本来Modalをそんなに重ねて表示することはまずありません。
気をつけるべきは、ModalCreateで表示したModalで、Pushを行うことです。
本来、Pushで表示した表示したPageは専用な場所にカスタムタグが生成されます。
しかし、ModalからPushされたばあい、Modal専用の領域にPageのカスタムタグが生成されます。
上記の画像をみると、ion-modalタグに隣接する形で、page-homeタグが生成されていることがわかります。
そして、hidden属性が付いていないことも見て取れます。
一度、Modal内でPushをしてしまうと、それ以降のPageでPushを行うと、ずっとModalの領域にタグが生成されてしまいます。
そのため、気づかないうちに、hidden属性の付いていないタグが蓄積し、実機が負荷に耐えられなくなった時に、表示が崩れます。
まとめ
Modal内でPushはしちゃだめ!