# JavaScript SDK Enhancements

The following sections cover the finer technical details of the improvements in the RudderStack JavaScript SDK that make it more efficient and easier to use.

## `sendBeacon` as a transport mechanism

The JavaScript SDK hosted at [**https://cdn.rudderlabs.com/v1.1/rudder-analytics.min.js**](https://cdn.rudderlabs.com/v1.1/rudder-analytics.min.js) sends the event payload using the **XHR** (XMLHttpRequest) API.

RudderStack now also supports sending the event payload using the [**`navigator.sendBeacon`**](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon) browser utility, which asynchronously sends a small amount of data over HTTP to the RudderStack server. The JavaScript SDK supports a new Boolean field, `useBeacon`, in the [**`load()`**](https://rudderstack.com/docs/stream-sources/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk/#the-options-parameter) call options. When set to `true`, the SDK sends events using the **`navigator.sendBeacon`** utility.

You can use the `sendBeacon` feature with the [latest version](https://cdn.rudderlabs.com/v1.1/rudder-analytics.min.js) of the JavaScript SDK. For more information on how to use this feature, refer to [this section](https://rudderstack.com/docs/stream-sources/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk/#the-options-parameter).

The `sendBeacon` version of the RudderStack JavaScript SDK located at <https://cdn.rudderlabs.com/v2/rudder-analytics.min.js?transport=beacon> and its XMLHTTP version - <https://cdn.rudderlabs.com/v2/rudder-analytics.min.js> are **not supported** anymore.

### Why use sendBeacon to send your event payload?

There are two key advantages of using the [**`navigator.sendBeacon`**](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon) utility to send your event payload:

* Since pushing events to the Beacon queue is faster compared to the XHR instrumentation, you may see some performance improvements in the JavaScript SDK.
* The Beacon requests are optimized so that the browser waits until the CPU load is lower, or until the network is free before making the actual requests. This can lead to better website performance.

The Beacon queue maintained by the browsers has a limitation on the total size of the elements present in the queue at any point and **peaks at 64 KB**.

### `BeaconQueueOpts`

The JavaScript SDK internally uses a separate queue (`BeaconQueueOpts`) to hold the data and send it through the sendBeacon utility in batches. The structure of `BeaconQueueOpts` is shown below:

```javascript
{
  maxItems: 10 
  flushQueueInterval: 600000
}
```

| Parameter            | Type    | Description                                                           | Default Value |
| -------------------- | ------- | --------------------------------------------------------------------- | ------------- |
| `maxItems`           | Integer | The SDK flushes the queue when this number of payloads is reached.    | `10`          |
| `flushQueueInterval` | Integer | The SDK flushes the queue after this time interval (in milliseconds). | `600000`      |

The SDK flushes the Beacon queue if the total size of the payload exceeds 64 KB before reaching the `maxItems`/`flushQueueInterval` value in the configuration.

### Event delivery guarantees and retry mechanism

This section highlights some important considerations before you opt to use `sendBeacon` for sending your event payload:

* The Beacon requests sent from the SDK using `navigator.sendBeacon()` only push the events to browser’s Beacon queue. As it depends on the browser's engine to send these events from the queue, RudderStack **cannot guarantee** the events getting discarded due to 5xx errors and other network-related errors (request timed out, end resource unavailable, etc.).

If event delivery and retry is an important requirement for your website, we highly recommend using the XHR version of the JavaScript SDK, where RudderStack retries event delivery based on status codes and other errors.

* The Beacon queue maintained by the browsers also has a limitation on the total size of the elements present in the queue at any point, and peaks out at **64 KB**. Therefore, you cannot send high frequency hits from the main thread in one go, as the Beacon queue cannot take up cycles to dequeue itself. The JavaScript SDK handles this by maintaining a separate queue which retries pushing events to the Beacon queue in case they are not successfully pushed in the first attempt.

Currently, the RudderStack queue handles approximately 500 hits per 30ms and ensures eventual successful delivery of events after retries to Beacon. A similar comparison on Google Analytics’ `analytics.js` shows a hit rate of 2 hits/sec.

## Reduced core SDK size by calling `requireIntegration`

**This feature is deprecated and no longer supported by RudderStack**.

As RudderStack supports more native destinations through the JavaScript SDK, more instrumentation code gets added to it. This leads to an increase in the SDK size and requires the browser to evaluate and parse more unused JavaScript.

Therefore, we have decided to not bundle these instrumentation codes for the end destinations in the core JavaScript SDK. Instead, the SDK will now only fetch the destination configuration settings from the RudderStack dashboard such as track ID, API key, secret, etc. using the `requireIntegration` method.

### `requireIntegration` call definition

The `requireIntegration` method contains the following two parameters:

* The first parameter is a **string** or an **array of strings** containing the destination names.

You can also pass `rudderanalytics.requireIntegration(“All”)`. This will fetch all the plugins for the native destinations that are connected to the source in your RudderStack dashboard.

* The second parameter is a **callback** that accepts an object containing the names of the destinations that were successfully or unsuccessfully loaded on the page.

An example is shown below:

```javascript
rudderanalytics.requireIntegration(
  ["GoogleAnalytics", "Hotjar", "Hubspot"],
  function(object) {
    console.log(JSON.stringify(object));
  }
);
```

RudderStack supports a few canonical names for destinations. You can find more information regarding these canonical names in the [common destination names](https://docs.rudderstack.com/rudderstack-sdk-integration-guides/rudderstack-javascript-sdk/#common-destination-names) section of the SDK documentation.

Currently, RudderStack support plugins only for Google Analytics, Hotjar, and HubSpot. We are working on adding support for more destinations very soon, so stay tuned!

### How it works

Once the JavaScript SDK receives a call, e.g. `rudderanalytics.requireIntegration("GA")`, it automatically fetches the Google Analytics instrumentation code (e.g. `GAPlugin.js`). This code handles the transformation and mapping logic for the RudderStack event payload and the call type (`track`, `page`, etc.) to Google Analytics' corresponding payload and API calls (for e.g. `send`, `set`, etc.)

The SDK maintains a call queue and the API calls to it are processed one after the other. The processing of this call queue will be blocked once the `requireIntegration` method is called.

### Use-case

Suppose the user makes a call `rudderanalytics.requireIntegration("GA")`. All the subsequent calls made to the SDK (such as `page`, `track`, `alias`, `group`, etc.) will get enqueued until the `GAPlugin.js` and Google Analytics' `analytics.js` is loaded on the web page. Once the plugin and the end destination snippet is loaded, the calls in the call queue will be processed, and the corresponding calls to `analytics.js` will start flowing.

For this example, Google Analytics' `trackingId` and other configuration settings are fetched from the RudderStack dashboard as noted earlier, and `analytics.js` is configured using these settings.

### Sample call flow

The following workflow sums up the flow of the event payload when the user calls `requireIntegration()`:

![requireIntegration call flow](https://876606571-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lq5Ea6fHVg3dSxMCgyQ%2Fuploads%2Fgit-blob-f1dd17af42386fc9340cf5718b6927db41ce3662%2Frequireintegration-call-flow.png?alt=media)

## Contact us

For more information or queries on any of the sections covered in this guide, you can [**contact us**](mailto:%20docs@rudderstack.com) or start a conversation in our [**Slack**](https://rudderstack.com/join-rudderstack-slack-community) community.

If you come across any issues while using the JavaScript SDK, feel free to submit them on our [**GitHub issues page**](https://github.com/rudderlabs/rudder-sdk-js/issues).
