Skip to content

Commit

Permalink
Preload project runner (#1067)
Browse files Browse the repository at this point in the history
* preload project runner

* use prefetch instead of preload
  • Loading branch information
nighca authored Nov 5, 2024
1 parent 2200594 commit cc8b7ea
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 14 deletions.
8 changes: 6 additions & 2 deletions spx-gui/src/components/editor/preview/EditorPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { onMounted, ref } from 'vue'
import { useEditorCtx } from '@/components/editor/EditorContextProvider.vue'
import { UICard, UICardHeader, UIButton, UIFullScreenModal } from '@/components/ui'
import StageViewer from './stage-viewer/StageViewer.vue'
import RunnerContainer from '@/components/project/runner/RunnerContainer.vue'
import RunnerContainer, { preload as preloadRunner } from '@/components/project/runner/RunnerContainer.vue'
let show = ref(false)
const editorCtx = useEditorCtx()
onMounted(() => {
preloadRunner()
})
</script>

<style scoped lang="scss">
Expand Down
34 changes: 28 additions & 6 deletions spx-gui/src/components/project/runner/IframeDisplay.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,34 @@
<template>
<iframe ref="iframe" class="iframe" frameborder="0" src="about:blank" />
</template>

<script lang="ts">
import { ref, watch } from 'vue'
import rawRunnerHtml from '@/assets/ispx/runner.html?raw'
import wasmExecUrl from '@/assets/wasm_exec.js?url'
import wasmUrl from '@/assets/ispx/main.wasm?url'
function addPrefetchLink(url: string) {
// Use `prefetch` instead of `preload`:
// * `preload` indicates higher priority than `prefetch`. Preloaded content are expected to be used soon. For example, chrome will warn if the preloaded content is not used within 3 or 5 seconds. While project here will not be runned until the user clicks some "run" button.
// * `preload` results are not shared across different documents, while the iframe content is a different document. The "preloading" is meaningful only when the HTTP cache is shared, which is more like the case of `prefetch`.
const link = document.createElement('link')
link.rel = 'prefetch'
link.href = url
link.crossOrigin = 'anonymous'
link.onload = link.onerror = () => {
document.head.removeChild(link)
}
document.head.appendChild(link)
}
// preload resources (for example, wasm files) to accelerate the loading
export function preload() {
addPrefetchLink(wasmExecUrl)
addPrefetchLink(wasmUrl)
}
</script>

<script setup lang="ts">
const emit = defineEmits<{
console: [type: 'log' | 'warn', args: unknown[]]
Expand All @@ -12,12 +40,6 @@ interface IframeWindow extends Window {
console: typeof console
}
import { ref } from 'vue'
import rawRunnerHtml from '@/assets/ispx/runner.html?raw'
import wasmExecUrl from '@/assets/wasm_exec.js?url'
import wasmUrl from '@/assets/ispx/main.wasm?url'
import { watch } from 'vue'
const props = defineProps<{ zipData: ArrayBuffer | Uint8Array }>()
const iframe = ref<HTMLIFrameElement>()
Expand Down
6 changes: 5 additions & 1 deletion spx-gui/src/components/project/runner/ProjectRunner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,17 @@
</div>
</template>

<script lang="ts">
import IframeDisplay, { preload } from './IframeDisplay.vue'
export { preload }
</script>

<script lang="ts" setup>
import { onUnmounted, ref } from 'vue'
import { registerPlayer } from '@/utils/player-registry'
import { useFileUrl } from '@/utils/file'
import { Project } from '@/models/project'
import { UIImg, UILoading } from '@/components/ui'
import IframeDisplay from './IframeDisplay.vue'
const props = defineProps<{ project: Project }>()
Expand Down
7 changes: 6 additions & 1 deletion spx-gui/src/components/project/runner/RunnerContainer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,16 @@
</div>
</div>
</template>

<script lang="ts">
import ProjectRunner, { preload } from './ProjectRunner.vue'
export { preload }
</script>

<script setup lang="ts">
import { onMounted, ref, type CSSProperties, watch, nextTick } from 'vue'
import dayjs from 'dayjs'
import type { Project } from '@/models/project'
import ProjectRunner from './ProjectRunner.vue'
import { usePublishProject } from '@/components/project'
import { UIButton, UIIcon, UIModalClose } from '@/components/ui'
import { useMessageHandle } from '@/utils/exception'
Expand Down
8 changes: 6 additions & 2 deletions spx-gui/src/pages/community/project.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue'
import { computed, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { useMessageHandle } from '@/utils/exception'
import { useQuery } from '@/utils/query'
Expand Down Expand Up @@ -29,7 +29,7 @@ import {
import CenteredWrapper from '@/components/community/CenteredWrapper.vue'
import ProjectsSection from '@/components/community/ProjectsSection.vue'
import ProjectItem from '@/components/project/ProjectItem.vue'
import ProjectRunner from '@/components/project/runner/ProjectRunner.vue'
import ProjectRunner, { preload as preloadRunner } from '@/components/project/runner/ProjectRunner.vue'
import RemixedFrom from '@/components/community/project/RemixedFrom.vue'
import OwnerInfo from '@/components/community/project/OwnerInfo.vue'
import { useCreateProject, useRemoveProject, useShareProject, useUnpublishProject } from '@/components/project'
Expand Down Expand Up @@ -267,6 +267,10 @@ const remixesRet = useQuery(
},
{ en: 'Failed to load projects', zh: '加载失败' }
)
onMounted(() => {
preloadRunner()
})
</script>

<template>
Expand Down
8 changes: 6 additions & 2 deletions spx-gui/src/widgets/spx-runner/SpxRunner.ce.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
</div>
</template>
<script setup lang="ts">
import ProjectRunner from '@/components/project/runner/ProjectRunner.vue'
import { ref, watch } from 'vue'
import ProjectRunner, { preload as preloadRunner } from '@/components/project/runner/ProjectRunner.vue'
import { onMounted, ref, watch } from 'vue'
import { Project, fullName } from '@/models/project'
import { shallowRef } from 'vue'
const props = defineProps<{ owner?: string; name?: string }>()
Expand Down Expand Up @@ -71,6 +71,10 @@ const onStop = () => {
run.value = false
runner.value.stop()
}
onMounted(() => {
preloadRunner()
})
</script>
<style lang="scss">
.spx-runner-widget {
Expand Down

0 comments on commit cc8b7ea

Please sign in to comment.