if inside a location is evaluated per request and interacts badly with most other directives; map is a hash lookup evaluated once.
# evaluated on every request, and the documentation has
# a page explaining why this is considered harmful
location / {
if ($http_user_agent ~* "bot") { set $is_bot 1; }
}
# a hash, built at configuration load
map $http_user_agent $is_bot {
default 0;
"~*bot" 1;
"~*crawl" 1;
}
The map form is also composable in a way the conditional is not — several maps can feed each other, and the resulting variable is available to any directive including access_log and limit_req_zone. The performance difference is small and the correctness difference is not: if inside a location silently changes how try_files and rewrite behave.