Kee doesn’t typically take very long to do most of the work needed to fill and save passwords for you; in most cases less than 1ms but when many thousands of tasks need to be done in a short space of time, the total amount of time can sometimes be noticeable.
Some Kee users have reported a few web sites where Kee performs unusually slowly so thanks to them, I have now spent some time optimising the parts of Kee that were most inefficient. The result of that work will be in Kee 2.2 but if you’re interested in some more of the technical details of what’s been done, read on.
Firstly, while it’s tempting to point at a headline figure of some evidence-backed benchmarked improvements resulting from this work, I’m not going to. I have put some figures on GitHub but these are only applicable to a specific website being used in a specific way on a specific computer. In exploring the potential performance improvements I identified that Kee will be between 5 and 20,000 percent faster depending upon context so for you, it may be an entirely unnoticeable, or an amazing change.
These performance improvements are most useful when the page contains a large number of forms, a deep DOM tree (e.g. many div wrappers for constructing complex layouts) and a large number of items on the page that could theoretically be a login button (which Kee has to perform a variety of investigations on before establishing which is really the login button).
The main improvements come from these changes:
As we build up the “score” for each button, we use that to skip some of the more time consuming tasks for buttons that we know can’t possibly beat the best score found so far.
We use a plain for loop instead of Array.forEach when looking at whether any words describing the button make it more or less likely to be the login submit button.
In that same word comparison algorithm, we cache the results of our calculations for each word found on the page. For pages with many buttons that have the same name this can save a lot of time, even more so if we increase the number of “magic” words in future.
We now attach the submit handlers asynchronously. This means that KeePass can start looking for matches sooner and the web page can get on with other things while we gradually prepare the page to detect any new or changed logins you enter.
We store a Map of every DOM Node on the page that we come across while looking for the submit buttons. That Map can be inspected much more quickly than the DOM itself so we see huge performance gains in the part of the algorithm that weights the buttons by their distance from the “probably username or password” field in a given form. Because we store the distance from each node to the common ancestor of that node and the target form field, we need to create a new map for every form. If we continue to see performance problems in this area in relation to sites with multiple forms, we can possibly improve performance further by calculating some kind of difference tree between the form fields in each form.