Skip to content

Conversation

@AbeJellinek
Copy link

@AbeJellinek AbeJellinek commented Aug 5, 2025

We've seen some serious performance issues in Zotero since the recent CMOS style updates - as long as 10 seconds to initialize citeproc-js and generate a citation. I did some profiling, and it seems like the major bottleneck was CSL.XmlJSON#getNodesByName(). It gets called repeatedly during initialization, often with the same arguments (in my testing, 4250 calls with only 11 unique name arguments). Before this PR, it had to perform a full recursive tree walk every time, which ended up accounting for the majority of the initialization time.

This PR implements a cache that allows that function to avoid repeating work. The first time #getNodesByName() is called with a myjson argument that it hasn't seen before (including as a subtree of another tree), it walks the whole tree and caches name mappings. Mappings are propagated upwards so every node's cache includes mappings for itself and all its descendants.

In my testing, this reduces the time to initialize CSL.Engine in demo.js from 450 ms to 200 ms in Firefox (55% faster), and from 300 ms to 115 ms in Chrome (62% faster).

Tests all pass on my machine.

59a11cb can be dropped before merge to go back to APA and remove the new logging in demo.js. I kept those changes in this PR so it's easier to test.

@bwiernik
Copy link
Contributor

bwiernik commented Aug 5, 2025

Thanks for the investigation and fix. We hadn't encountered serious performance impacts in our tests ahead of merging the Chicago update, so apologies for not catching this problem ahead of that merge

@AbeJellinek
Copy link
Author

No worries! Let me know if this needs anything.

@dstillman
Copy link
Contributor

Zotero 8 beta startup:

Before:

zotero(3)(+0000195): Cached CSL.Engine instance with {"locale":"en-US","format":"html","automaticJournalAbbreviations":false} for http://www.zotero.org/styles/apa

zotero(3)(+0000702): Cached CSL.Engine instance with {"locale":"en-US","format":"html","automaticJournalAbbreviations":false} for http://www.zotero.org/styles/chicago-notes-bibliography

zotero(3)(+0000767): Cached CSL.Engine instance with {"locale":"en-US","format":"text","automaticJournalAbbreviations":false} for http://www.zotero.org/styles/chicago-notes-bibliography

After:

zotero(3)(+0000140): Cached CSL.Engine instance with {"locale":"en-US","format":"html","automaticJournalAbbreviations":false} for http://www.zotero.org/styles/apa

zotero(3)(+0000353): Cached CSL.Engine instance with {"locale":"en-US","format":"html","automaticJournalAbbreviations":false} for http://www.zotero.org/styles/chicago-notes-bibliography

zotero(3)(+0000418): Cached CSL.Engine instance with {"locale":"en-US","format":"text","automaticJournalAbbreviations":false} for http://www.zotero.org/styles/chicago-notes-bibliography

dstillman added a commit to zotero/zotero that referenced this pull request Aug 7, 2025
dstillman added a commit to zotero/citeproc-js-server that referenced this pull request Aug 7, 2025
@bwiernik
Copy link
Contributor

bwiernik commented Aug 7, 2025

This looks good to me. Will remove the logging @AbeJellinek mentioned and merge tomorrow or Saturday

dstillman added a commit to zotero/zotero that referenced this pull request Aug 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants