Apexで大量データを表示するようなページを開発する際に気をつけなければならないのがViewStateの制限です。Visualforceでは最大表示サイズの制限が決められているため、通常気にする必要はありませんが、表示する項目が多い場合は、このエラーが発生する可能性があります。
ビューステートを減らす際の考慮点
- apex:formを複数使っている場合は一つにする。
- apex:form内で利用している項目を減らす。
- controllersやcontroller extensionsにてSOQLにて取得する項目数を減らす。(余分不必要な項目があれば減らす)
- VeiwStateに影響のあるcomponentを減らす(C:等で記載しているcomponentのことになります)
- StandardSetController Class を利用していない場合はその利用を検討する。
ビューステートを減らす考慮点にapex:form内の項目数があります。Apexで使用している項目が影響あるということなので、Apexで開発したときとJavaScriptで開発した時でどのくらいの違いがあるか確認してみました。
検証
- 片方はApexクラスでSOQLを実行
- もう片方ではApexクラスを使用せずにJSforceでクエリを実行
- どちらも2000件のレコードを取得。画面に表示する
コード
Apex開発
JavaScript開発
レコード件数
Apex開発
最後のレコード
JavaScript開発
最後のレコード
結果
Apex開発
JavaScript開発
ApexのViewStateは『29.41』でした。それに対してJavaScriptのViewStateは『1.73』となりました。ページング切り替えが必要になるような大量レコードを検索・表示するページの場合、ApexではなくJavaScriptで対応できるようにしておくとより多くの件数を表示できると思います。
ただ、JavaScriptでの開発はApexよりも難しくなると思います。保守や追加開発のときも考慮してApexで対応できるところはApexで対応しておくと楽になると思います。(状況に応じてApexの方が良いケースとJavaScriptの方が良いケースがあると思います。)
追記
Apexの場合、画面に表示できる件数は1000件までですが、readOnlyをつけることで5万件まで表示することができます。JavaScriptの場合、1000件以上表示することができますが最大2000件までだったと思います。
Javascriptで2000件以上取得する方法
2000件以上画面に表示したい場合はConnectionにqueryMoreメソッドというのが用意されているみたいです。
また、今回使用しているJSforceにもnextRecordsUrlが用意されていました。
残りのレコードがあるかの判定フラグも持っているのでこれを利用して2000件以上表示できるみたいです。
ちなみに件数は全件取得することができます。注意事項としてJavaScriptから取得する場合はAPIを消費することになります。API実行権限の無いユーザが使用する画面では使用エラーになるので最初に確認が必要です。