【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); を行なった場合は、開発者ツールでみると以下の画像のようになっています。

Pushの場合のHTML構造

HomeというPageのみでPushを行なっているため、page-homeというカスタムタグのみが追加されています。

さて、ここで注目すべきは、アクティブではないPageにはhidden属性が付与されている点です。

hidden属性を付与することで、ブラウザのLayout計算から除外されるため、処理が高速化されています。

続いて、ModalCreateを行なった場合です。

ModalCreateの場合のHTML構造

page-homeとは別の、Modalを生成する専用の場所にion-modalというカスタムタグが生成されます。

ModalCreateの場合は、hidden属性が付与されません。

この状態でModalCreateを繰り返すと、hidden属性が付いていないカスタムタグがどんどんと生成されるため、無用な計算コストがかかり、表示が崩れます。

私の場合、modalを20〜30個程度表示すると、実機で表示がくずれました。

とはいえ、本来Modalをそんなに重ねて表示することはまずありません。

気をつけるべきは、ModalCreateで表示したModalで、Pushを行うことです。

本来、Pushで表示した表示したPageは専用な場所にカスタムタグが生成されます。

しかし、ModalからPushされたばあい、Modal専用の領域にPageのカスタムタグが生成されます。

ModalからPushしたの場合のHTML構造

上記の画像をみると、ion-modalタグに隣接する形で、page-homeタグが生成されていることがわかります。

そして、hidden属性が付いていないことも見て取れます。

一度、Modal内でPushをしてしまうと、それ以降のPageでPushを行うと、ずっとModalの領域にタグが生成されてしまいます。

そのため、気づかないうちに、hidden属性の付いていないタグが蓄積し、実機が負荷に耐えられなくなった時に、表示が崩れます。

まとめ

Modal内でPushはしちゃだめ!

人気記事すべて表示

ハイブリッドアプリすべて表示