@firebase/performance 0.7.6 → 0.7.7-canary.2b5731292

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ import { Component } from '@firebase/component';
6
6
  import '@firebase/installations';
7
7
 
8
8
  const name = "@firebase/performance";
9
- const version = "0.7.6";
9
+ const version = "0.7.7-canary.2b5731292";
10
10
 
11
11
  /**
12
12
  * @license
@@ -327,6 +327,9 @@ class SettingsService {
327
327
  this.logNetworkAfterSampling = false;
328
328
  // TTL of config retrieved from remote config in hours.
329
329
  this.configTimeToLive = 12;
330
+ // The max number of events to send during a flush. This number is kept low to since Chrome has a
331
+ // shared payload limit for all sendBeacon calls in the same nav context.
332
+ this.logMaxFlushSize = 40;
330
333
  }
331
334
  getFlTransportFullUrl() {
332
335
  return this.flTransportEndpointUrl.concat('?key=', this.transportKey);
@@ -614,6 +617,12 @@ function processConfig(config) {
614
617
  settingsServiceInstance.tracesSamplingRate =
615
618
  DEFAULT_CONFIGS.tracesSamplingRate;
616
619
  }
620
+ if (entries.fpr_log_max_flush_size) {
621
+ settingsServiceInstance.logMaxFlushSize = Number(entries.fpr_log_max_flush_size);
622
+ }
623
+ else if (DEFAULT_CONFIGS.logMaxFlushSize) {
624
+ settingsServiceInstance.logMaxFlushSize = DEFAULT_CONFIGS.logMaxFlushSize;
625
+ }
617
626
  // Set the per session trace and network logging flags.
618
627
  settingsServiceInstance.logTraceAfterSampling = shouldLogAfterSampling(settingsServiceInstance.tracesSamplingRate);
619
628
  settingsServiceInstance.logNetworkAfterSampling = shouldLogAfterSampling(settingsServiceInstance.networkRequestsSamplingRate);
@@ -704,6 +713,9 @@ const DEFAULT_SEND_INTERVAL_MS = 10 * 1000;
704
713
  const INITIAL_SEND_TIME_DELAY_MS = 5.5 * 1000;
705
714
  const MAX_EVENT_COUNT_PER_REQUEST = 1000;
706
715
  const DEFAULT_REMAINING_TRIES = 3;
716
+ // Most browsers have a max payload of 64KB for sendbeacon/keep alive payload.
717
+ const MAX_SEND_BEACON_PAYLOAD_SIZE = 65536;
718
+ const TEXT_ENCODER = new TextEncoder();
707
719
  let remainingTries = DEFAULT_REMAINING_TRIES;
708
720
  /* eslint-enable camelcase */
709
721
  let queue = [];
@@ -731,13 +743,28 @@ function dispatchQueueEvents() {
731
743
  // The staged events will be used for current logRequest attempt, remaining events will be kept
732
744
  // for next attempt.
733
745
  const staged = queue.splice(0, MAX_EVENT_COUNT_PER_REQUEST);
746
+ const data = buildPayload(staged);
747
+ postToFlEndpoint(data)
748
+ .then(() => {
749
+ remainingTries = DEFAULT_REMAINING_TRIES;
750
+ })
751
+ .catch(() => {
752
+ // If the request fails for some reason, add the events that were attempted
753
+ // back to the primary queue to retry later.
754
+ queue = [...staged, ...queue];
755
+ remainingTries--;
756
+ consoleLogger.info(`Tries left: ${remainingTries}.`);
757
+ processQueue(DEFAULT_SEND_INTERVAL_MS);
758
+ });
759
+ }
760
+ function buildPayload(events) {
734
761
  /* eslint-disable camelcase */
735
762
  // We will pass the JSON serialized event to the backend.
736
- const log_event = staged.map(evt => ({
763
+ const log_event = events.map(evt => ({
737
764
  source_extension_json_proto3: evt.message,
738
765
  event_time_ms: String(evt.eventTime)
739
766
  }));
740
- const data = {
767
+ const transportBatchLog = {
741
768
  request_time_ms: String(Date.now()),
742
769
  client_info: {
743
770
  client_type: 1, // 1 is JS
@@ -747,29 +774,23 @@ function dispatchQueueEvents() {
747
774
  log_event
748
775
  };
749
776
  /* eslint-enable camelcase */
750
- postToFlEndpoint(data)
751
- .then(() => {
752
- remainingTries = DEFAULT_REMAINING_TRIES;
753
- })
754
- .catch(() => {
755
- // If the request fails for some reason, add the events that were attempted
756
- // back to the primary queue to retry later.
757
- queue = [...staged, ...queue];
758
- remainingTries--;
759
- consoleLogger.info(`Tries left: ${remainingTries}.`);
760
- processQueue(DEFAULT_SEND_INTERVAL_MS);
761
- });
777
+ return JSON.stringify(transportBatchLog);
762
778
  }
763
- function postToFlEndpoint(data) {
779
+ /** Sends to Firelog. Atempts to use sendBeacon otherwsise uses fetch. */
780
+ function postToFlEndpoint(body) {
764
781
  const flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl();
765
- const body = JSON.stringify(data);
766
- return navigator.sendBeacon && navigator.sendBeacon(flTransportFullUrl, body)
767
- ? Promise.resolve()
768
- : fetch(flTransportFullUrl, {
782
+ const size = TEXT_ENCODER.encode(body).length;
783
+ if (size <= MAX_SEND_BEACON_PAYLOAD_SIZE &&
784
+ navigator.sendBeacon &&
785
+ navigator.sendBeacon(flTransportFullUrl, body)) {
786
+ return Promise.resolve();
787
+ }
788
+ else {
789
+ return fetch(flTransportFullUrl, {
769
790
  method: 'POST',
770
- body,
771
- keepalive: true
772
- }).then();
791
+ body
792
+ });
793
+ }
773
794
  }
774
795
  function addToQueue(evt) {
775
796
  if (!evt.eventTime || !evt.message) {
@@ -791,12 +812,33 @@ serializer) {
791
812
  };
792
813
  }
793
814
  /**
794
- * Force flush the queued events. Useful at page unload time to ensure all
795
- * events are uploaded.
815
+ * Force flush the queued events. Useful at page unload time to ensure all events are uploaded.
816
+ * Flush will attempt to use sendBeacon to send events async and defaults back to fetch as soon as a
817
+ * sendBeacon fails. Firefox
796
818
  */
797
819
  function flushQueuedEvents() {
820
+ const flTransportFullUrl = SettingsService.getInstance().getFlTransportFullUrl();
798
821
  while (queue.length > 0) {
799
- dispatchQueueEvents();
822
+ // Send the last events first to prioritize page load traces
823
+ const staged = queue.splice(-SettingsService.getInstance().logMaxFlushSize);
824
+ const body = buildPayload(staged);
825
+ if (navigator.sendBeacon &&
826
+ navigator.sendBeacon(flTransportFullUrl, body)) {
827
+ continue;
828
+ }
829
+ else {
830
+ queue = [...queue, ...staged];
831
+ break;
832
+ }
833
+ }
834
+ if (queue.length > 0) {
835
+ const body = buildPayload(queue);
836
+ fetch(flTransportFullUrl, {
837
+ method: 'POST',
838
+ body
839
+ }).catch(() => {
840
+ consoleLogger.info(`Failed flushing queued events.`);
841
+ });
800
842
  }
801
843
  }
802
844