Snippet Reliability
The A vs B snippet runs inside your shoppers' browsers, so it is built to a strict rule: it must never make your page wait. Every network call it makes has its own time limit. If a call is slow or fails, the snippet falls back to a safe answer instead of hanging.
You do not configure any of this; it is on by default. This page explains what to expect so you know a slow network on a shopper's device can never freeze their experience.
Every call has a deadline
Each request the snippet makes stops waiting after a set time. If the server has not answered by then, the snippet gives up on that one call and moves on. It never leaves a request open forever, and it never leaves a timer running in the background.
| Snippet feature | Waits up to | If it times out or fails |
|---|---|---|
| Recommendations | ~3 seconds | Resolves to an empty result reported as not served, instead of hanging. No impression event fires for that attempt, since the request never completed. |
| Dataset lookups | ~2 seconds | The lookup degrades to a negative result and the cached value is dropped, so the next call retries cleanly. |
| Audience prefetch | ~1.5 seconds total | Any lookup that did not resolve in time is simply treated as "not matched" for that shopper. |
| Experiment config | your tag timeout, never under ~3 seconds | Experiments do not run for that page view; the page is revealed and your code keeps working via the normal API. |
What "degrade gracefully" means
Two principles keep a failed call safe:
- Recommendations fail to a miss. If the recommendation request is slow or errors,
avsb.recs.get()resolves to an empty result reported as not served, instead of throwing or hanging. It hands back data, not markup. A vs B never draws a placeholder for a recommendation slot, so your own code decides what an empty slot looks like. - Lookups and audiences degrade to
false. If a dataset lookup or an audience-membership check cannot complete, it resolves as no / not a member rather than throwing. Your targeting rule simply does not match that shopper, and the page continues normally.
In every case the outcome is a defined, safe value: never an exception thrown into your page and never an unresolved promise.
Shoppers only download what your project uses
The snippet ships in two parts. The core file that runs your experiments is deliberately small and loads on every page. The commerce features live in a second file. They are product and cart events, recommendations, dataset lookups, and cart or purchase-history audiences. That file is fetched separately, and only when your project needs it.
For a project with commerce set up, that second file is fetched as the page loads, so nothing waits on it later. For every other project it is fetched only when something asks for it. That happens when your code calls a commerce, recommendations or dataset method. It also happens when a running experiment targets an audience built on cart value, products viewed or purchase history. A project that uses none of those never downloads it at all.
Nothing changes in how you write your code. Every method is there and behaves the same either way. The only difference is that the first call may wait a moment for its file to arrive. If that file cannot be fetched, the rules above apply. Lookups resolve as not found, recommendations report not served, and commerce audiences simply do not match.
If the snippet itself crashes
On any start-up failure the page is revealed first, before anything else happens. A harmless stand-in API is then installed on window.avsb, so avsb.ready(...) callbacks still run. Every method stays callable and answers honestly: getVariation returns null, getActiveExperiments returns an empty list, and tracking calls do nothing rather than throw. The failure is logged to the browser console, and reported to your dashboard whenever a config was reachable.
Errors thrown by variation code always show in the visitor's browser console. They also appear in the experiment's error log on the dashboard. So a broken variation never shows a clean console while the dashboard quietly collects the failure.
Error reporting retries
Error reports batch and ship every 10 seconds. If the browser refuses to send a batch, the snippet keeps it and tries again on later flushes, up to 3 attempts, before dropping it. The current batch is also sent when the page is hidden or closed, so the last errors of a session are not lost with the tab.
Old browsers
Some browsers are too old to cancel a request. On those, the snippet sends an ordinary request with no time limit of its own, but it still returns a normal result and never throws. The behaviour degrades to "no client timeout" without ever breaking the calling code.
Why this matters
A shopper on a weak mobile connection is exactly the shopper you least want to lose to a frozen page. Every A vs B call has a time limit and falls back to a safe default. So on a slow network the worst case is an empty recommendation slot, or a test that does not run for that visit. It is never a page that hangs.
Related
- Recommendations API: the headless recommendations calls.
- Background Jobs and Status: how the server-side jobs behind these features report their own health.
- A Change Stopped Applying: what to do when a live visual change can no longer find its spot on a page that changed underneath it.