Calls to getTokenSilently() are slow, on the order of 50ms. In our case this breaks a subsequent use of apollo-link-batch-http, as the delay pushes every query outside of the batching window.
The extra time comes from acquiring a lock to avoid multiple requests. The implementation was changed to fix this in https://github.com/auth0/auth0-spa-js/pull/339, but reverted in https://github.com/auth0/auth0-spa-js/pull/525 since it seems to have caused other unwanted behaviour.
Calls should only take a few milliseconds, as they do with getIdTokenClaims.
index.html, replace the implementation of showAuth0Info with: showAuth0Info: function () {
var _self = this;
_self.access_tokens = [];
_self.auth0.getTokenSilently().then(function (token) {
_self.audienceScopes[0].access_tokens.push(token);
_self.auth0.getUser().then(function (user) {
_self.profile = user;
});
_self.auth0.getIdTokenClaims().then(function (claims) {
_self.id_token = claims.__raw;
});
}).then(() => {
const start = performance.now();
_self.auth0.getIdTokenClaims().then(() => {
console.log(`getIdTokenClaims took ${performance.now() - start}ms`);
});
_self.auth0.getTokenSilently().then(() => {
console.log(`getTokenSilently took ${performance.now() - start}ms`);
});
});
},
Login via "Login popup" a few times.
Note the difference in processing times for the two methods. In our app we've seen a range of roughly 15ms - 90ms depending on whatever else the app is doing at the time.
getIdTokenClaims took 10ms
getTokenSilently took 81ms
getIdTokenClaims took 7ms
getTokenSilently took 79ms
getIdTokenClaims took 7ms
getTokenSilently took 67ms
getIdTokenClaims took 10ms
getTokenSilently took 80ms
getIdTokenClaims took 10ms
getTokenSilently took 77ms
(Currently on package version 1.11.0)
Cheers.
Hi @jalovatt - thanks for raising this
The extra time comes from acquiring a lock to avoid multiple requests. The implementation was changed to fix this in #339, but reverted in #525 since it seems to have caused other unwanted behaviour.
The reason that we now check the lock before returning the cache is that, if you have 2 calls to getTokenSilently when there's an empty cache, one immediately after the other, the first call will populate the cache - but the second call wouldn't know about it because it's already checked the cache and is waiting for the lock be released, which makes the 2nd call make an unnecessary request.
But I can see that this has added some unnecessary latency to calls where the cache is populated. So I think the answer will be to check the cache before and after acquiring the lock, let me investigate.
In the meantime, 1.10 will have the old behaviour.
Most helpful comment
Hi @jalovatt - thanks for raising this
The reason that we now check the lock before returning the cache is that, if you have 2 calls to
getTokenSilentlywhen there's an empty cache, one immediately after the other, the first call will populate the cache - but the second call wouldn't know about it because it's already checked the cache and is waiting for the lock be released, which makes the 2nd call make an unnecessary request.But I can see that this has added some unnecessary latency to calls where the cache is populated. So I think the answer will be to check the cache before and after acquiring the lock, let me investigate.
In the meantime,
1.10will have the old behaviour.