【Salesforce】ビューステートの最大表示サイズの制限 (135 KB) を超えています。このページのビューステートのサイズは、*** KB でした

【Salesforce】ビューステートの最大表示サイズの制限 (135 KB) を超えています。このページのビューステートのサイズは、*** KB でした

Visualforceで開発をした画面を表示した際、エラーが発生しました。

ビューステートの最大表示サイズの制限 (135 KB) を超えています。このページのビューステートのサイズは、136.312 KB でした

久しぶりに見たエラーです。

Apexコントローラの情報なんかを保持するために、Visualforceページ内に暗号化された文字列で持っているとかなんとか。

その情報は135KBまでというガバナ制限があり、135KBを超えるとエラーとなります。

以前は128KBだったような気がしますが、少し緩和されたようですね。

今回のビューステートは250KBを超えていました。

対処法を調べてみると、一番上にこんなページがありました。

https://help.salesforce.com/articleView?id=000004323&language=ja&type=1

そもそも、コントローラ側で取得するレコードが多すぎました。

StandardSetControllerを使いたいところですが、すべてのレコードを画面に表示してjQueryのプラグインでテーブルにしています。

さらに、それらのすべてが編集対象のレコードとのことです。

ビューステートのエラーが出た場合の定番として、transientの修飾子を使うことができます。

この修飾子を使った変数はコントローラ側に情報を残しません。

transientを使用して、編集対象でないレコードの情報は残さないようにしました。

こんな感じです。

// 画面に表示するリストをtransientにする
transient public List<Account> accountList{get;set;}

また、毎回同じ値を使用する選択リスト値はgetメソッドにすることができます。

/**
 * 選択リスト値を取得する
 */
public List<SelectOption> getSelectOptions(){

    List<SelectOption> optionList;

    // ご利用状況の選択リストを作成する
    optionList = new List<SelectOption>();
    optionList.add(new SelectOption('', 'なし'));
    optionList.add(new SelectOption('AA', 'AA'));
    optionList.add(new SelectOption('BB', 'BB'));

    return optionList;
}

ここまでやった段階で、ビューステートは150KBくらいまで落ちました。

あと少しに見えますが、ここからが大変でした。

編集対象のレコードの中にも、表示用の項目と修正用の項目がありました。

そこで、表示用の項目についてはtransientとしてしまいました。

transient public List<Contact> displayContactList{get;set;}
public List<Contact> editContactList{get;set;}

2つの変数は同じレコードを取得していますが、取得しているフィールドが異なります。

表示用のdisplayContactListをtransientすることで、ビューステートの削減をすることができました。

ビューステートについては解決できましたが、SOQLの発行回数なんかは増えてしまいますね。

同じコントローラ内での画面遷移の際にも処理に時間がかかるようになりますから、本当なら表示するレコードの数を削減するのが一番なんですよね。

そうは言っていられないあたり、下っ端の辛いところです。

No comments.

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です