Performance
Production Incident form (incident.do) is taking 8-12 seconds to load for end users across multiple roles.
The question
Setting the Stage
Form load delays over 8 seconds indicate synchronous operations blocking the initial page render. Common culprits include Business Rules on 'display'/'query' phases executing heavy GlideRecord queries, client scripts fetching data on load, or unoptimized reference qualifiers. TTFB dominance points to server-side issues, not client rendering. Diagnosis starts with Transaction Logs (filter by URL/transaction time >5s), System Diagnostics > Slow Queries, and enabling Script Debugger at 'All' to trace BR execution time.
First checks: Review BRs/UI Policies/Client Scripts on incident table (sys_script.list with table=incident). Use Form Load Analyzer or Stats.do to quantify contributors. Check Node stats for memory/CPU spikes during peak hours.
The Solution
Problematic Business Rule (on Display, causing 6s delay - nested loops + unindexed query):
(function executeRule(current, previous /*null when async*/) {
var gr = new GlideRecord('sys_user_grmember');
gr.addQuery('group', current.assigned_to.group);
gr.query();
var members = [];
while(gr.next()) {
var userGr = new GlideRecord('sys_user');
userGr.get(gr.user);
members.push(userGr.getDisplayValue());
}
current.u_team_members = members.join(', '); // Populates string field
})(current, previous);
Optimized Solution (Script Include + Async + Indexing):
// Script Include: TeamUtils (Client callable)
var TeamUtils = Class.create();
TeamUtils.prototype = Object.extendsObject(AbstractAjaxProcessor, {
getMembers: function() {
var groupId = this.getParameter('sysparm_group');
var gr = new GlideRecord('sys_user_grmember');
gr.addQuery('group', groupId);
gr.addQuery('user.active', true);
gr.orderBy('user.name');
gr.query();
var members = [];
while(gr.next())
members.push(gr.user.getDisplayValue());
return members.join(', ');
}
});
// Client Script (onLoad) - GlideAjax call
// BR replaced with empty shell: current.setWorkflow(false);
Senior Considerations
- Diagnosis Depth: Listing the suspect BRs is the easy half; quantify with "Transaction Time Breakdown" + the Slow Query log + an ACL trace via Script Debugger. Check reference field lookup stats.
- Solution Options & Trade-offs: 1) Async BR: Fastest user response, but data inconsistency risk (use for notifications). 2) Script Include + GlideAjax: On-demand load, sharply reduces TTFB, but adds client latency. 3) UI Policy + Dictionary Override: No code, but limited to simple logic.
- Production Rollout: Test in sub-prod with Performance Analytics baseline. Stagger BR deactivation (one-by-one). Monitor post-deploy with Node Health Trends. Index query fields (group+active). Edge case: Mobile/next experience ignores client scripts.
- Great Answer Marker: Explains why Display BR blocks (synchronous execution before DOM render), proposes setWorkflow(false) to prevent recursion, discusses GlideRecord best practices (addQuery/addJoinQuery), and covers scale (1000+ users/day).
- Failure Modes: Async orphan jobs on node failure; unindexed queries explode at scale; ignoring browser cache leads to repeated loads.