Woocommerce shipping calculations running too often.
Woocommerce shipping setup works great until you build a custom shipping plugin that uses external quoting systems via HTTP API calls, at which point you realize that the shipping is calculated dozens of times unnecessarily during the order process - slowing everything down.
We make API calls to external servers at our Australian Postal System and also a courier aggregator system to get post and shipping rates. This takes about 5 seconds to complete the two API calls and since the calculate_shipping()
function seems to be called on every cart addition & modification, on entry to the checkout page and then on every single keystroke for relevant address fields in the checkout page there are 5-second delays and unnecessary HTTP calls everywhere.
The ajax calls from every keystroke on the checkout page also seem to be queued up and process one after the other so the user can sit watching for 30 seconds while the shipping options are populated then cleared several times before being able to choose one.
Another silly consequence is that the errors that come back from the quoting of an incomplete address end up scrolling the screen up to the top where the notices are being displayed which stops the user from completing typing the address.
So the question is How to stop WC from calling calculate_shipping()
until all shipping fields have been completed and maybe the last field has lost focus - or any alternative suggestions to do similar and avoid the multiple calls.
In order to remove the shipping calculations on every cart addition, I have simply tested for the current request URI and return straight out if it is not
if ('https://aaa.bbb/checkout/' !== $_SERVER['HTTP_REFERER']) {
return;
}
Seems to be ok, however, I expect there are some complications later as otherwise why would WC be doing this on every cart addition.
On the checkout, though it's a different story.
I need the shipping to run, but not on every new character typed into an address field as seems to be the default functionality.
There seems to be a timer in play and if you take more than a seconds pause during typing your address it fires update_checkout()
or similar which calls calculate_shipping()
and I so end up contacting the post servers and couriers servers to ask for a new quote. (they will tire of this DOS attack I'm sure)
I've been looking into the checkout.js script but don't really want to mess with WC functionality and not be able to update so not sure if I want to change this.
None relevant at this stage
What I would like is for shipping not to be calculated until all items are in the cart and the user has finished typing in their address - anything else seems a bit silly.