refactor: improve void element parsing perf, fixes #886 and #857 #887
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.
This PR changes the behaviour of templ's void element handling.
Previously, you could do
<input>Text</input>
and templ would allow it, despite it not being valid HTML. The LSP would emit a warning, but it would render.However, this caused a performance issue for unclosed void elements. templ was parsing the rest of the file to look for a closing element, just in case it was present, so that the elements could be nested in templ's object model.
This operation wasn't memoized, so it ran every time a void element was encountered. In files with lots of void elements, it would cause a long delay!
The formatting operation rewrites
<br>
to<br/>
which vastly reduces the time, but it's not a great experience that it takes a long time. It seems that some users don't use the editor extensions, or are unaware of the fmt tool, so they just live with the known bad performance.This PR changes the templ behaviour so that it doesn't have nested content for all known void HTML elements, e.g.:
Becomes:
This improves the performance, see benchmark results:
Before
After
Comparison
The important part is the ns/op figure - how many nanoseconds each operation takes.
46576 / 387117=12%, so the new version is about 8 times faster in the given scenario.