Reputation: 763
I have a simple function that just executes a transaction to help keep a count of a list.
However, I am noticing when I run it, it takes nearly 5 seconds to execute, which seems really slow for how simple the function is. Is there anything I can do or a faster way to keep a counter?
exports.CountCommentsUp = functions.firestore.document('Groups/{groupID}/TextFeedActive/{postID}/Comments/{commentID}').onCreate(event => {
// ref to the parent document
const docRef = admin.firestore().collection('Groups/' + event.params.groupID+ '/Feed/').doc(event.params.postID);
//Along with Creating Counter, We need to create Notification REF
return admin.firestore().runTransaction(function(transaction) {
return transaction.get(docRef).then(function(sfDoc) {
var newCC = sfDoc.data().CommentCount + 1;
transaction.update(docRef, { CommentCount: newCC });
return newCC;
});
})
});
I looked through it a bunch of times, and it definitely works, just feels really slow. Is there an alternate way to do this? For the database to feel realtime it would be great to have really faster counter variables as well
Upvotes: 4
Views: 3321
Reputation: 13597
For future readers:
There is section of the GCP documentation, where they discuss about ways of improving cloud function performance.
Quoting from the docs:
Use dependencies wisely
Because functions are stateless, the execution environment is often initialized from scratch (during what is known as a cold start). When a cold start occurs, the global context of the function is evaluated.
If your functions import modules, the load time for those modules can add to the invocation latency during a cold start. You can reduce this latency, as well as the time needed to deploy your function, by loading dependencies correctly and not loading dependencies your function doesn't use.
Use global variables to reuse objects in future invocations
There is no guarantee that the state of a Cloud Function will be preserved for future invocations. However, Cloud Functions often recycles the execution environment of a previous invocation. If you declare a variable in global scope, its value can be reused in subsequent invocations without having to be recomputed.
This way you can cache objects that may be expensive to recreate on each function invocation. Moving such objects from the function body to global scope may result in significant performance improvements. The following example creates a heavy object only once per function instance, and shares it across all function invocations reaching the given instance: It is particularly important to cache network connections, library references, and API client objects in global scope. See Optimizing Networking for examples.
Do lazy initialization of global variables
If you initialize variables in global scope, the initialization code will always be executed via a cold start invocation, increasing your function's latency. If some objects are not used in all code paths, consider initializing them lazily on demand:
This is particularly important if you define several functions in a single file, and different functions use different variables. Unless you use lazy initialization, you may waste resources on variables that are initialized but never used.
You may also read the article written by a Google developer advocate : Improving Cloud Function cold start time. To summarizing the key points made in the article (for speeding up cloud functions)
- Trimming dependencies.
- Using dependencies cache.
- Lazy loading
Upvotes: 7