-
Notifications
You must be signed in to change notification settings - Fork 1k
[labs/ssr-client] Add digest cache #5074
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@lit-labs/ssr-client': patch | ||
| --- | ||
|
|
||
| Add a digest cache to reduce the overhead of rendering the same template multiple times |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -449,6 +449,10 @@ const createAttributeParts = ( | |
|
|
||
| // Number of 32 bit elements to use to create template digests | ||
| const digestSize = 2; | ||
|
|
||
| // Digest cache | ||
| const digestCache = new WeakMap<TemplateStringsArray, string>(); | ||
|
|
||
| // We need to specify a digest to use across rendering environments. This is a | ||
| // simple digest build from a DJB2-ish hash modified from: | ||
| // https://github.com/darkskyapp/string-hash/blob/master/index.js | ||
|
|
@@ -461,6 +465,11 @@ const digestSize = 2; | |
| // - Easily specifiable and implementable in multiple languages. | ||
| // We don't care about cryptographic suitability. | ||
| export const digestForTemplateResult = (templateResult: TemplateResult) => { | ||
| let digest = digestCache.get(templateResult.strings); | ||
| if (digest !== undefined) { | ||
| return digest; | ||
| } | ||
|
|
||
| const hashes = new Uint32Array(digestSize).fill(5381); | ||
|
|
||
| for (const s of templateResult.strings) { | ||
|
|
@@ -469,6 +478,7 @@ export const digestForTemplateResult = (templateResult: TemplateResult) => { | |
| } | ||
| } | ||
| const str = String.fromCharCode(...new Uint8Array(hashes.buffer)); | ||
|
|
||
| // Use `btoa` in browsers because it is supported universally. | ||
| // | ||
| // In Node, we are sometimes executing in an isolated VM context, which means | ||
|
|
@@ -478,5 +488,9 @@ export const digestForTemplateResult = (templateResult: TemplateResult) => { | |
| // for `btoa` when they set up their VM context, we instead inject an import | ||
| // for `Buffer` from Node's built-in `buffer` module in our Rollup config (see | ||
| // note at the top of this file), and use that. | ||
| return NODE_MODE ? Buffer.from(str, 'binary').toString('base64') : btoa(str); | ||
| digest = NODE_MODE | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. btw, we should start using btoa in Node soon... |
||
| ? Buffer.from(str, 'binary').toString('base64') | ||
| : btoa(str); | ||
| digestCache.set(templateResult.strings, digest); | ||
| return digest; | ||
| }; | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make sure that we're not exacerbating the static template memory leak with this...
I think we're not because once the static template cache frees a template, the forged TemplateStringsArray will be able to be freed and this cache will release the entry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe you're correct based on my understanding of how WeakMaps work in JS
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So as long as the template is only associated with WeakMaps (or I'm assuming other "weak" data structures), we should be good.