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 = `
[b]bold[/b]
[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!")
func BenchmarkSharlock(b *testing.B) {
for i := 0; i < b.N; i++ {
ParsePostInput(sharlock, RealMarkdown)
}
}
[/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(`"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(`"owner_avatar":"`)

View File

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

View File

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