PRSHL
PRSHL

Reputation: 1444

Firebase update Function is sometimes slower executed

I have a simple update function which sometimes executes really slow compared to other times.

// Five executions with very different execution times
Finished in 1068ms // Almost six times slower than the next execution
Finished in 184ms
Finished in 175ms
Finished in 854ms
Finished in 234ms

The Function is triggered from the frontend and doesn't run on Firebase Cloud Functions.

const startAt = performance.now()
const db = firebase.firestore();
const ref = db.doc(`random/nested/document/${id}`);
ref.update({
        na: boolean // a calculated boolean with array.includes(...)
          ? firebase.firestore.FieldValue.arrayRemove(referenceId)
          : firebase.firestore.FieldValue.arrayUnion(referenceId)
      })
      .then(() => {
        let endAt = performance.now();
        console.log("Finished in " + (endAt - startAt) + "ms");
      });

Is there anything I can improve to fix these performance differences?

Also the longer execution times dont only appear when removing something from an array or adding something to an array. It appears on adding and removing. Sometimes these execution times go up to 3000ms.

Upvotes: 0

Views: 72

Answers (1)

samthecodingman
samthecodingman

Reputation: 26171

Similar to cold-starting a Cloud Function where everything is spun up, initialized and made ready for use, a connection to Cloud Firestore also needs to be resolved through DNS, ID tokens need to be obtained to authenticate the request, a socket to the server opened and any handshakes are exchanged between the server and the SDK.

Any new operations on the database can make use of the previous work taken to initialize the connection and that is why they look like they are faster.

Showing this as loose pseudocode:

let connection = undefined;
function initConnectionToFirestore() {
  if (!connection) {
    await loadFirebaseConfig();
    await Promise.all([
      resolveIpAddressOfFirebaseAuth(),
      resolveIpAddressOfFirestoreInstance()
    ]);
    await getIdTokenFromFirebaseAuth();
    await addAuthenticationToRequest();
    connection = await openConnection();
  }
  return connection;
}

function doUpdate(...args) {
  const connection = await initConnectionToFirestore();
  // do the work
  connection.send(/* ... */);
}

await doUpdate() // has to do work of initConnectionToFirestore
await doUpdate() // reuses previous work
await doUpdate() // reuses previous work
await doUpdate() // reuses previous work

Upvotes: 2

Related Questions