Advanced
Compute-intensive functions
Which PAC functions trigger blocking DNS lookups, and how to avoid unnecessary ones.
PAC evaluation is synchronous and blocking โ the browser freezes the request
until FindProxyForURL returns. Functions that perform DNS resolution amplify this
effect: every DNS round-trip adds tens to hundreds of milliseconds to every request.
dnsResolve()
โ High cost
Always triggers a live DNS lookup. Cache the result in a variable โ never call twice for the same host.
isResolvable()
โ High cost
Performs a DNS lookup on every call. Replace with
dnsDomainIs() or shExpMatch() wherever possible.isInNet() + hostname
โ High cost
If the first argument is a hostname (not an IP), isInNet() internally calls dnsResolve(). Always pre-resolve.
isInNet() + IP
โ No cost
If you pass a pre-resolved IP (from dnsResolve), no additional DNS lookup occurs. This is the correct pattern.
dnsDomainIs()
โ No cost
Pure string suffix match. Zero DNS overhead. Always prefer this over isResolvable() for domain checks.
shExpMatch()
โ No cost
Pure string glob match. Zero DNS overhead. Good for URL and host pattern matching.
The golden rule:
DNS optimisation pattern
function FindProxyForURL(url, host) { // โ FAST: domain checks first โ zero DNS cost if ( isPlainHostName(host) || dnsDomainIs(host, ".corp.com") || shExpMatch(host, "*.local")) { return "DIRECT"; } // โ ONE DNS call โ stored and reused below var ip = dnsResolve(host); if (!ip) { return "DIRECT"; } // โ guard failure case // โ FAST: isInNet receives an IP โ no extra DNS if ( isInNet(ip, "10.0.0.0", "255.0.0.0") || isInNet(ip, "192.168.0.0", "255.255.0.0")) { return "DIRECT"; } // โ WRONG โ triggers a second DNS lookup for the same host: // if (isInNet(dnsResolve(host), "10.0.0.0", "255.0.0.0")) { ... } return "PROXY proxy.corp.com:8080"; }