sf-agent-framework
Version:
AI Agent Orchestration Framework for Salesforce Development - Two-phase architecture with 70% context reduction
326 lines (252 loc) • 7.04 kB
Markdown
This task guides the analysis and optimization of Salesforce performance issues.
Enable developers to:
- Identify performance bottlenecks
- Optimize slow operations
- Improve user experience
- Scale effectively
- Monitor performance
**Key Metrics to Monitor**
```yaml
Page Load Times:
- Target: < 3 seconds
- Critical: > 5 seconds
- Measure: Browser dev tools
API Response Times:
- Target: < 500ms
- Critical: > 2 seconds
- Measure: Debug logs
Batch Processing:
- Target: 1000 records/minute
- Critical: < 100 records/minute
- Measure: Batch job logs
SOQL Performance:
- Target: < 100ms
- Critical: > 1 second
- Measure: Query plan tool
```
**SOQL Optimization**
```apex
// Poor Performance
List<Account> accounts = [SELECT Id, Name,
(SELECT Id FROM Contacts),
(SELECT Id FROM Opportunities),
(SELECT Id FROM Cases)
FROM Account];
// Optimized
List<Account> accounts = [SELECT Id, Name FROM Account];
List<Contact> contacts = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds];
// Process with maps for O(1) lookup
```
**Apex Optimization**
```apex
// Poor Performance - N+1 Query
for(Account acc : accounts) {
List<Contact> contacts = [SELECT Id FROM Contact WHERE AccountId = :acc.Id];
}
// Optimized - Bulk Query
Map<Id, List<Contact>> contactsByAccount = new Map<Id, List<Contact>>();
for(Contact c : [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds]) {
if(!contactsByAccount.containsKey(c.AccountId)) {
contactsByAccount.put(c.AccountId, new List<Contact>());
}
contactsByAccount.get(c.AccountId).add(c);
}
```
```yaml
Key Sections:
- EXECUTION_STARTED
- SOQL_EXECUTE_BEGIN/END
- DML_BEGIN/END
- METHOD_ENTRY/EXIT
- CUMULATIVE_LIMIT_USAGE
What to Look For:
- Long running queries
- Multiple similar queries
- High CPU time
- Excessive heap usage
```
```sql
-- Use in Developer Console Query Editor
-- Prefix query with EXPLAIN
EXPLAIN SELECT Id, Name FROM Account
WHERE Industry = 'Technology'
AND AnnualRevenue > 1000000
```
**Selective Queries**
```yaml
Selective Fields:
- Indexed fields
- Unique fields
- External IDs
- Fields with limited values
Non-Selective Fields:
- Text areas
- Checkbox (usually)
- Formula fields
- Multi-picklist
```
**Custom Indexes**
```yaml
When to Request:
- Query returns >100K rows
- Field used in WHERE clause
- Not already indexed
- Selective enough (<30% records)
How to Request:
- Contact Salesforce Support
- Provide query examples
- Show performance impact
```
### 2. Apex Optimization
**Collection Usage**
```apex
// Use Maps for lookups
Map<Id, Account> accountMap = new Map<Id, Account>(
[]
);
// Use Sets for uniqueness
Set<Id> processedIds = new Set<Id>();
for(Opportunity opp : opportunities) {
if(!processedIds.contains(opp.AccountId)) {
processedIds.add(opp.AccountId);
// Process once per account
}
}
```
**Asynchronous Processing**
```apex
// Move heavy operations to async
public static void processLargeDataSet(Set<Id> recordIds) {
if(recordIds.size() > 50) {
// Use Queueable for large sets
System.enqueueJob(new ProcessRecordsQueueable(recordIds));
} else {
// Process synchronously for small sets
processRecords(recordIds);
}
}
```
**Lightning Component Performance**
```javascript
// Lazy Loading
export default class PerformantList extends LightningElement {
@track visibleRecords = [];
allRecords = [];
pageSize = 50;
connectedCallback() {
this.loadInitialData();
}
loadInitialData() {
this.visibleRecords = this.allRecords.slice(0, this.pageSize);
}
loadMore() {
const currentLength = this.visibleRecords.length;
const moreRecords = this.allRecords.slice(currentLength, currentLength + this.pageSize);
this.visibleRecords = [...this.visibleRecords, ...moreRecords];
}
}
```
**Caching Strategy**
```apex
// Platform Cache
public class CacheManager {
private static final String PARTITION = 'local.UserCache';
public static Object get(String key) {
return Cache.Org.get(PARTITION + '.' + key);
}
public static void put(String key, Object value, Integer ttl) {
Cache.Org.put(PARTITION + '.' + key, value, ttl);
}
}
```
```yaml
Test Scenarios:
- Normal load: 100 concurrent users
- Peak load: 500 concurrent users
- Stress test: 1000 concurrent users
Metrics to Capture:
- Response times
- Error rates
- Throughput
- Resource utilization
```
```apex
@isTest
private class VolumeTest {
@isTest
static void testLargeDataVolume() {
// Create test data
List<Account> accounts = TestDataFactory.createAccounts(10000);
insert accounts;
Test.startTest();
// Test performance with large data
Long startTime = System.currentTimeMillis();
AccountService.processAccounts(accounts);
Long endTime = System.currentTimeMillis();
Test.stopTest();
// Assert performance
Long duration = endTime - startTime;
System.assert(duration < 60000, 'Processing took too long: ' + duration + 'ms');
}
}
```
```apex
public class PerformanceMonitor {
private Long startTime;
private String operation;
public PerformanceMonitor(String operation) {
this.operation = operation;
this.startTime = System.currentTimeMillis();
}
public void log() {
Long duration = System.currentTimeMillis() - startTime;
Performance_Log__c log = new Performance_Log__c(
Operation__c = operation,
Duration_ms__c = duration,
Timestamp__c = DateTime.now(),
User__c = UserInfo.getUserId()
);
// Async insert to avoid impact
System.enqueueJob(new LogInserter(log));
}
}
```
- [ ] Remove unnecessary fields
- [ ] Use selective filters
- [ ] Avoid nested queries
- [ ] Leverage indexes
- [ ] Limit result size
- [ ] Bulkify all operations
- [ ] Use collections efficiently
- [ ] Minimize loops
- [ ] Cache repeated calculations
- [ ] Move to async when possible
- [ ] Implement lazy loading
- [ ] Use Lightning Data Service
- [ ] Minimize server calls
- [ ] Cache static data
- [ ] Optimize asset delivery
✅ Performance baselines established ✅ Bottlenecks identified ✅ Optimizations
implemented ✅ Performance improved >30% ✅ Monitoring in place ✅ Documentation
updated