- リンクを取得
- ×
- メール
- 他のアプリ
- リンクを取得
- ×
- メール
- 他のアプリ
【VisualforceページでのView State制限問題の解決】
VisualforceページでのView Stateが制限(135KB)を超える問題は、ユーザー体験に影響を与える重要な課題です。以下では、View Stateの構造と「Internal」コンポーネントを減らす方法を中心に解説します。
View Stateの構成要素
View Stateには以下の情報が含まれます:
コントローラーとそのプロパティ
- ページでバインドされた変数やリスト、マップなど
- transientでない変数が対象
コンポーネント構造
- ページ上のVisualforceコンポーネントとその階層構造
フォームデータ
- ページ上のフォームの入力データ
「Internal」コンポーネント
- Visualforceによる内部データ(例: コンポーネントの状態、構造のキャッシュ)
「Internal」コンポーネントが大きくなる原因
多量のHTML生成
- Visualforceのデフォルトコンポーネントは、追加情報を埋め込むことでView Stateを増加させます。
繰り返しのリスト表示
- apex:repeatやapex:dataTableが大規模なデータセットに使用されている場合。
複数のフォーム
- フォームが複数存在する場合、各フォームの状態が保存される。
ページレイアウトの複雑さ
- DOMの階層が深いほど内部の状態保存が増える。
解決策:View Stateを最適化する方法
1. 使用していないデータの削除
- transientの活用
すでに利用しているようですが、動的に再生成可能なデータはすべてtransientでマークします。
public transient List<Account> accountList;
2. 大量データのクライアントサイド管理
- サーバー側で管理するデータを最小化
View Stateに格納されるデータ量を減らすため、JavaScriptを活用してクライアントサイドでデータを管理します。
例: データをクライアントサイドに保存する
<script> let accountData = []; function storeAccount(account) { accountData.push(account); } </script>
3. apex:outputPanelで必要な部分のみレンダリング
- データが条件によって表示される場合はrendered属性を使用して非表示部分を省きます。
<apex:outputPanel rendered="{!showData}"> <!-- 必要なデータのみ --> </apex:outputPanel>
4. actionRegionでView Stateのスコープを限定
- フォーム全体ではなく一部だけを再送信することで、View Stateを減らします。
<apex:form> <apex:actionRegion> <apex:commandButton value="Update" action="{!updateRecords}" /> </apex:actionRegion> </apex:form>
5. カスタムコンポーネントを利用
- 再利用可能なコンポーネントを設計し、ページ全体の複雑さを削減します。
例:View Stateを削減したコード設計
以下は、View Stateを抑えるための改良版コード例です:
public class AccountSearchController { public String searchKey { get; set; } public transient List<Account> results { get; private set; } public void search() { if (String.isNotBlank(searchKey)) { results = [SELECT Id, Name FROM Account WHERE Name LIKE :('%' + searchKey + '%')]; } else { results = new List<Account>(); } } }
Visualforceページ:
<apex:page controller="AccountSearchController"> <apex:form> <apex:inputText value="{!searchKey}" /> <apex:commandButton value="Search" action="{!search}" /> </apex:form> <apex:outputPanel rendered="{!NOT(ISNULL(results))}"> <apex:dataTable value="{!results}" var="acc"> <apex:column value="{!acc.Name}" /> </apex:dataTable> </apex:outputPanel> </apex:page>
コメント
コメントを投稿