‹ All interview questions

Performance

Production Incident form (incident.do) is taking 8-12 seconds to load for end users across multiple roles.

The question

Production Incident form (incident.do) is taking 8-12 seconds to load for end users across multiple roles. OOTB load time should be ~2 seconds. Users report consistent delays even on new incidents. Browser dev tools show 90% of time in 'Waiting (TTFB)' with high server response time. No recent customizations, but team added 3 new Business Rules last sprint: one on 'display' for field population, one on 'query' for list collecting, and one on 'after' insert/update for notifications. Your task: Walk through your diagnosis approach (tools/metrics you'd check first), identify likely root causes with evidence, propose 3 solution options with trade-offs, and provide production rollout considerations. Include a code example showing a problematic Business Rule and its optimized version. What we're evaluating: Systematic problem-solving (not just 'use async'), production impact awareness, and ability to balance performance vs. business needs. Bonus: Mention edge cases like high-volume forms or mobile users.

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.