I was looking at the same problem when integrating our contrib with OPC (UK Postcode Address Finder) - it seems like on every onBlur event on any of the form fields the full update sequence gets triggered if all address fiels are populated. This is especially noticable in IE.
I did a little tweak to checkout.js to check for change in the form data before running the update - if data is unchanged we bail out and don't do any of the ajax-y bits.
No guarantee it will help you as I haven't tested extensively, but worth a try.
Here is a chunk out of checkout.js, mods were done to functions processBillingAddress, processShippingAddress and setCheckoutAddress.
last_processBillingAddress : '',
processBillingAddress: function (skipUpdateTotals){
var hasError = false;
var checkoutClass = this;
$('select[name="billing_country"], input[name="billing_street_address"], input[name="billing_zipcode"], input[name="billing_city"], *[name="billing_state"]', $('#billingAddress')).each(function (){
if (checkoutClass.fieldErrorCheck($(this), false, true) == true){
hasError = true;
}
});
if (hasError == true){
return;
}
this.setBillTo();
if ($('#diffShipping').checked && this.loggedIn != true){
this.setSendTo(true);
}else{
this.setSendTo(false);
}
if (this.last_processBillingAddress != $('*', $('#billingAddress')).serialize()) {
this.last_processBillingAddress = $('*', $('#billingAddress')).serialize();
} else {
return;
}
if(skipUpdateTotals != true)
{
this.updateCartView();
this.updateFinalProductListing();
this.updatePaymentMethods(true);
this.updateShippingMethods(true);
this.updateOrderTotals();
}
},
last_processShippingAddress : '',
processShippingAddress: function (skipUpdateTotals){
var hasError = false;
var checkoutClass = this;
$('select[name="shipping_country"], input[name="shipping_street_address"], input[name="shipping_zipcode"], input[name="shipping_city"]', $('#shippingAddress')).each(function (){
if (checkoutClass.fieldErrorCheck($(this), false, true) == true){
hasError = true;
}
});
if (hasError == true){
return;
}
if (this.last_processShippingAddress != $('*', $('#shippingAddress')).serialize()) {
this.last_processShippingAddress = $('*', $('#shippingAddress')).serialize();
} else {
return;
}
this.setSendTo(true);
if (this.shippingEnabled == true && skipUpdateTotals != true){
this.updateShippingMethods(true);
}
if(skipUpdateTotals != true)
{
this.updateCartView();
this.updateFinalProductListing();
this.updatePaymentMethods(true);
this.updateShippingMethods(true);
this.updateOrderTotals();
}
},
last_setBillTo: '',
last_setSendTo: '',
setCheckoutAddress: function (type, useShipping){
var checkoutClass = this;
var selector = '#' + type + 'Address';
var sendMsg = 'Setting ' + (type == 'shipping' ? 'Shipping' : 'Billing') + ' Address';
var errMsg = type + ' address';
if (type == 'shipping' && useShipping == false){
selector = '#billingAddress';
sendMsg = 'Setting Shipping Address';
errMsg = 'billing address';
}
if (selector == '#billingAddress') {
if (this.last_setBillTo != $('*', $('#billingAddress')).serialize()) {
this.last_setBillTo = $('*', $('#billingAddress')).serialize();
} else {
return;
}
} else {
if (this.last_setSendTo != $('*', $('#shippingAddress')).serialize()) {
this.last_setSendTo = $('*', $('#shippingAddress')).serialize();
} else {
return;
}
}
action = 'setBillTo';
if (type == 'shipping'){
action = 'setSendTo';
}
this.queueAjaxRequest({
url: this.pageLinks.checkout,
beforeSendMsg: sendMsg,
dataType: 'json',
data: 'action=' + action + '&' + $('*', $(selector)).serialize(),
type: 'post',
success: function (){
},
errorMsg: 'There was an error updating your ' + errMsg + ', please inform ' + checkoutClass.storeName + ' about this error.'
});
},
Cheers,
Adam