In a previous post, Overview of Browser Integration with Amp.ai, we looked at how to integrate with Amp.ai using the Browser or JS client synchronously. In the synchronous, or blocking integration, the size of the script is about 25KB after compression. This isn't too large until you have multiple projects running on the same page. In this article, we will look at how to integrate Amp.ai asynchronously, or non-blocking way, for highly latency-sensitive applications and for scenarios where you may be running more than one project on a page at the same time. If you haven't done so already, go to amp.ai to signup for an account and create your first project. This will give you the project key needed for the following steps and to begin viewing sessions. Let's get started!Integration OptionsThe table below highlights the pros and cons of each type of integration with Amp.ai. Choose the integration that best meets your needs.OptionProsConsSynchronousClean and simple integrationConfiguration only required if running multiple projects simultaneouslyLatency (50 - 100ms)Size - 96+ KBHybrid - Synchronously loads the asynchronous snippetClean and simple integrationConfiguration only required if running multiple projects simultaneouslyLatency (minimal)Size - 1KBAsynchronousCopy/paste JS on pageConfiguration requiredZero latencyHybrid IntegrationIntegrationPlace the following script in the <head> section of your page.<script src='https://amp.ai/libs/snippet/<PROJECT_KEY>.js'></script>Asynchronous IntegrationConfigurationConfiguration is the same as the synchronous integration but it is necessary to specify your project key here for asynchronous. Simply set an ampConfig object on the window Object as below.window.ampConfig = {
key: <YOUR_PROJECT_KEY>
};Make sure to place this before the script tag (See Integration). See the Amp.ai-Browser Client Integration Document for detailed configuration options.IntegrationTo integrate Amp.ai asynchronously, just place the following snippet in a script block in the <head> section of your page immediately after the configuration.<script>
"use strict";!function(){window.ampInstanceNames||(window.ampInstanceNames={}),window.ampConfig.instanceName?window.ampInstanceName=window.ampConfig.instanceName:window.ampInstanceName="amp";var e={};if(Object.assign(e,window.ampConfig||{}),window.ampInstanceNames[e.key]=window.ampInstanceName,!window.ampInstanceNames||!window[window.ampInstanceNames[e.key]]){for(var n=window[window.ampInstanceName]={replay:[],config:e,v:"1.2.0",ts:(new Date).getTime()},a="observe decide log".split(" "),t=0;t<a.length;t++)!function(e){n[e]=function(){for(var a=arguments.length,t=Array(a),i=0;i<a;i++)t[i]=arguments[i];"decide"===e&&"function"==typeof t[t.length-1]&&3===t.length&&(t=[t[0],t[1],{},t[2]]),n.replay.push([e,t,(new Date).getTime()])}}(a[t]);var i=document,o=i.getElementsByTagName("script")[0],m=i.createElement("script");o.parentNode.insertBefore(m,o),m.type="text/javascript",m.src=e.scriptSrc||(e.domain||"https://amp.ai")+"/libs/"+(e.k... Event("AmpLoaded"));var e=n.config.key,a=window[window.ampInstanceNames[e]];if(a.config=Object.assign(a.config,n.config),a&&n.replay)try{a.config.set("replayTime",(new Date).getTime()-n.ts),n.replay.forEach(function(e){e[2]&&a.timing("requestReplay",{method:name,event:e[0],start:e[2]}).end(),a[e[0]].apply(a,e[1])}),a.config.set("replayTime",0)}catch(e){a.warn(a.error({name:"UNAVAILABLE",message:"Error replaying amp snippet"}))}}}}();
</script>API CallsMaking API calls in an asynchronous integration is the same as with the synchronous integration. The snippet above will setup a replay queue and push any amp.observe and amp.decide calls into it. Once Amp.ai is finished loading, these events will fire off in the order they were received.Decision-makingGetting a decision back from Amp.ai asynchronously requires a little different implementation than synchronously. In the synchronous integration, explained in the Overview of Browser Integration with Amp.ai blog article, we see that we receive the decision immediately from the call. In an asynchronous integration, we must wait for the decision in the callback function.amp.decide('EventName', { ctaColor: ['red', 'green', 'blue']}, function(err, decision) {
// take action on decision returned
amp.utils.ready('#subscribeBtn', function(element) {
element.style.backgroundColor = decision.ctaColor;
});
});The code above will send a decide event into a replay queue while Amp.ai is loading. When it has finished loading, all of the events in the queue will fire off in the order they were sent. Once it reaches the above decide event, the callback function will execute immediately with the decision. We may then check if the DOM element, that we want to take action on with the decision, is available. If it is, we set the background color of the button we are querying. This ensures that we take action as soon as the Amp.ai script has loaded to better our chances of minimizing flicker for above the fold changes.SummaryIn this blog we looked at how to integrate Amp.ai with the Browser client asynchronously. While similar to the synchronous integration, minor changes were needed around making decisions to achieve zero latency. In the beginning, we spoke about integrating multiple projects at the same time. In my upcoming blog, we will see how to integrate Amp.ai both synchronously and asynchronously for multiple projects. This will enable you to run many projects simultaneously to further increase your throughput of tests that you are wanting to run to optimize your application and gain valuable insights for future tests as well.