Visualforce + Apexを活用したCSVアップロード画面の課題と解決策
課題
あるお客様が別のベンダーに依頼して、VisualforceとApexを活用したCSVアップロード画面を構築しました。しかし、いくつかの問題が発生しています。
課題の詳細
期待値: 一度に最低でもCSVファイル内に一つの列(識別ID)が1000件アップロードできること。
現実: 実際には100件しかアップロードできない。
原因
ファイル読み込み方法: `apex:inputFile`コンポーネントを使用し、サーバーサイドでファイルを読み込んでBlobからStringへ変換。その後、元ファイルがSHIFT-JIS形式なのでUTF-8に変換しています(SalesforceのオブジェクトはUnicodeしか格納できないため)。
CPU処理タイムの上限超過: ファイルを読み込んだ後、各行の識別IDの存在チェックと有効性確認(例:識別IDに紐づくユーザ情報の有効性バリデーション)を行うため、CPU処理タイムの上限を超えてしまう(非同期処理の場合:10秒)。
ガバナー制限の問題: CSVファイルに識別ID以外にオプション列(10列、一列最大4000文字)を追加する場合、HeapSizeの6MBのガバナー制限に引っかかる。
furuCRMの解決策
CPU処理タイムを減らすため、同期処理ではなく非同期処理に変更し、CSVファイルを読み込む処理や一部のバリデーションロジックをバックエンドからフロントエンド(JavaScript)に移植することが推奨されます。また、サーバーサイドへ配列の分割分(100行ずつや1000行ずつ)をポストし、サーバーサイドで処理する方法を取り入れます。この方法でHeapSizeの削減を目指します。
結果として最大1万7000件を取り込めました。
具体的な解決策
Before(従来の方法):
標準`apex:inputFile`コンポーネントを使用し、ファイルを読み込む。
Apexでファイルの文字コード変換、バリデーションチェック、登録可能データの作成、リストへの挿入を行う。
最終的に非同期バッチを呼び出し(パラメータとしてListデータを使用)、分散処理を活用してInsertを行う。
After(改善された方法):
`<input type="file">`を使用し、JavaScriptのFileReaderでファイルを読み込んで文字コード変換を行う。
JavaScriptでバリデーション可能なロジックを実行し、バリデーションが通ったデータを配列に格納する。
配列を100行ずつや1000行ずつに分割し、サーバーサイドにポストする。
サーバーサイドでは、受け取ったデータをString変数に仮に格納し、行・列をSplitして配列(ListまたはSet)に格納。
最終的に全データを読み込み、配列に書き込んで非同期バッチに流し込み、データを登録する。
メリットと注意点
メリット
ガバナー制限の回避: CPU処理タイムやHeapSizeのガバナー制限を回避できます。
パフォーマンス向上: フロントエンドでの処理を増やすことで、サーバーサイドの負荷を軽減し、全体的なパフォーマンスが向上します。
スケーラビリティ: データを分割して送信することで、大規模データの処理が可能になります。
注意点
ブラウザの操作: ファイルを読み込んだり処理中にブラウザを閉じないこと。全データの読み込みが完了し、処理完了通知が来るまで(非同期バッチが起動するまで)、ブラウザを閉じないようにする必要があります。
ユーザエクスペリエンス: 処理が完了するまでユーザーは待機する必要があり、長時間の待機が発生する可能性があります。
ラウンドトリップの遅延: データを分割して送信する際、ラウンドトリップが増加するため、処理時間が長くなる可能性があります。
結論
VisualforceとApexを活用したCSVアップロード画面の課題を解決するためには、非同期処理の導入とフロントエンドでの処理強化が有効です。この方法により、ガバナー制限を回避しながら、大量データの効率的なアップロードが可能となります。特に、サーバーサイドへのデータ送信を分割することでHeapSizeの制限を効果的に回避できます。ただし、ユーザーはブラウザの操作に注意し、処理完了まで待機する必要があります。また、ラウンドトリップの遅延を考慮する必要があります。この解決策を導入することで、システムのパフォーマンス向上とユーザーエクスペリエンスの改善が期待できます。
このように、フロントエンドでの処理を強化し、サーバーサイドへの負荷を軽減することで、CSVファイルの大規模データを効率的にアップロードできるようになります。ユーザーがブラウザを閉じないことを意識することも重要です。また、ラウンドトリップによる遅延を最小限に抑える工夫も必要です。
この記事が気に入ったらサポートをしてみませんか?