Put previews in a web worker to help with slower parsing

This commit is contained in:
Ben Visness 2021-07-17 18:20:47 -05:00
parent 17e9e0b735
commit 059f407ee4
6 changed files with 1698 additions and 68 deletions

View File

@ -0,0 +1,33 @@
importScripts('../go_wasm_exec.js');
/*
NOTE(ben): The structure here is a little funny but allows for some debouncing. Any postMessages
that got queued up can run all at once, then it can process the latest one.
*/
let ready = false;
let inputData = null;
onmessage = ({ data }) => {
inputData = data;
setTimeout(doPreview, 0);
}
const go = new Go();
WebAssembly.instantiateStreaming(fetch('../parsing.wasm'), go.importObject)
.then(result => {
go.run(result.instance); // don't await this; we want it to be continuously running
ready = true;
setTimeout(doPreview, 0);
});
const doPreview = () => {
if (!ready || !inputData) {
return;
}
const result = parseMarkdown(inputData);
inputData = null;
postMessage(result);
}

1650
src/parsing/corpus_test.go Normal file

File diff suppressed because it is too large Load Diff

View File

@ -63,58 +63,8 @@ func main() {
}) })
} }
const allBBCode = ` func BenchmarkSharlock(b *testing.B) {
[b]bold[/b] for i := 0; i < b.N; i++ {
ParsePostInput(sharlock, RealMarkdown)
[i]italic[/i] }
[u]underline[/u]
[h1]heading 1[/h1]
[h2]heading 2[/h2]
[h3]heading 3[/h3]
[m]monospace[/m]
[ol]
[li]ordered lists[/li]
[/ol]
[ul]
[li]unordered list[/li]
[/ul]
[url]https://handmade.network/[/url]
[url=https://handmade.network/]Handmade Network[/url]
[img=https://handmade.network/static/media/members/avatars/delix.jpeg]Ryan[/img]
[quote]quotes[/quote]
[quote=delix]Some quote[/quote]
[code]
Code
[/code]
[code language=go]
func main() {
fmt.Println("Hello, world!")
} }
[/code]
[spoiler]spoilers[/spoiler]
[table]
[tr]
[th]Heading 1[/th] [th]Heading 2[/th]
[/tr]
[tr]
[td]Body 1[/td] [td]Body 2[/td]
[/tr]
[/table]
[youtube]https://www.youtube.com/watch?v=0J8G9qNT7gQ[/youtube]
[youtube]https://youtu.be/0J8G9qNT7gQ[/youtube]
`

View File

@ -267,7 +267,7 @@ func TimelineItemsToJSON(items []TimelineItem) string {
builder.WriteString(`",`) builder.WriteString(`",`)
builder.WriteString(`"owner_name":"`) builder.WriteString(`"owner_name":"`)
builder.WriteString(item.OwnerName) builder.WriteString(item.OwnerName) // TODO: Do we need to do escaping on these other string fields too? Feels like someone could use this for XSS.
builder.WriteString(`",`) builder.WriteString(`",`)
builder.WriteString(`"owner_avatar":"`) builder.WriteString(`"owner_avatar":"`)

View File

@ -7,11 +7,7 @@
<script src="{{ static "go_wasm_exec.js" }}"></script> <script src="{{ static "go_wasm_exec.js" }}"></script>
<script> <script>
const go = new Go(); const previewWorker = new Worker('{{ static "js/editorpreviews.js" }}');
const goLoaded = WebAssembly.instantiateStreaming(fetch("{{ static "parsing.wasm" }}"), go.importObject)
.then(result => {
go.run(result.instance);
});
</script> </script>
{{ end }} {{ end }}
@ -105,17 +101,18 @@
const tf = document.querySelector('#editor'); const tf = document.querySelector('#editor');
const preview = document.querySelector('#preview'); const preview = document.querySelector('#preview');
function updatePreview() { function updatePreview(previewHtml) {
const previewHtml = parseMarkdown(tf.value);
preview.innerHTML = previewHtml; preview.innerHTML = previewHtml;
MathJax.typeset(); MathJax.typeset();
} }
goLoaded.then(() => { previewWorker.onmessage = ({ data }) => {
updatePreview(); updatePreview(data);
}); };
previewWorker.postMessage(tf.value);
tf.addEventListener('input', () => { tf.addEventListener('input', () => {
updatePreview(); previewWorker.postMessage(tf.value);
}); });
</script> </script>
{{ end }} {{ end }}

View File

@ -21,8 +21,8 @@
{{ end }} {{ end }}
{{ end }} {{ end }}
</style> </style>
<script type="text/javascript" src="{{ static "js/templates.js" }}"></script> <script src="{{ static "js/templates.js" }}"></script>
<script type="text/javascript" src="{{ static "js/showcase.js" }}"></script> <script src="{{ static "js/showcase.js" }}"></script>
{{ end }} {{ end }}
{{ define "content" }} {{ define "content" }}