Improve caching
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { NativeLink, useNativeRouter } from '@native-vue-router/core'
|
||||
import AppHeader from '../components/AppHeader.vue'
|
||||
import { runtimeLabGuard, setRuntimeLabBlocked } from '../lab-state'
|
||||
import { setStoryEntryBlocked, storyEntryGuard } from '../guard-state'
|
||||
|
||||
const native = useNativeRouter()
|
||||
|
||||
function toggleLabGuard() {
|
||||
setRuntimeLabBlocked(!runtimeLabGuard.blockEntry)
|
||||
function toggleStoryGuard() {
|
||||
setStoryEntryBlocked(!storyEntryGuard.blockEntry)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -25,8 +25,8 @@ function toggleLabGuard() {
|
||||
</section>
|
||||
<section class="settings-list">
|
||||
<a href="/profile/runtime-lab" @click.prevent="native.sibling('/profile/runtime-lab')"><span>⌁</span><strong>Runtime stress lab</strong><i>›</i></a>
|
||||
<button type="button" aria-label="Block Runtime Lab re-entry" :aria-pressed="runtimeLabGuard.blockEntry" @click="toggleLabGuard">
|
||||
<span>⌽</span><strong>Block cached lab re-entry</strong><i>{{ runtimeLabGuard.blockEntry ? 'On' : 'Off' }}</i>
|
||||
<button type="button" aria-label="Block Stories re-entry" :aria-pressed="storyEntryGuard.blockEntry" @click="toggleStoryGuard">
|
||||
<span>⌽</span><strong>Block cached Stories re-entry</strong><i data-testid="story-guard-status">{{ storyEntryGuard.blockEntry ? storyEntryGuard.status : 'Off' }}</i>
|
||||
</button>
|
||||
<NativeLink to="/settings"><span>⚙︎</span><strong>Navigation lab</strong><i>›</i></NativeLink>
|
||||
<a href="https://github.com" target="_blank" rel="noreferrer"><span>⌘</span><strong>Project source</strong><i>↗</i></a>
|
||||
|
||||
@@ -1,27 +1,26 @@
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { useNativeViewActiveEffect } from '@native-vue-router/core'
|
||||
import AppHeader from '../components/AppHeader.vue'
|
||||
import AsyncLabData from '../components/AsyncLabData.vue'
|
||||
import { runtimeLabGuard } from '../lab-state'
|
||||
import { runtimeLabGuard } from '../guard-state'
|
||||
|
||||
const mountedSeconds = ref(0)
|
||||
let mountedAt = 0
|
||||
let timer: number | undefined
|
||||
const mountedAt = Date.now()
|
||||
const mountId = crypto.randomUUID()
|
||||
|
||||
onMounted(() => {
|
||||
mountedAt = Date.now()
|
||||
timer = window.setInterval(() => {
|
||||
useNativeViewActiveEffect(() => {
|
||||
const update = () => {
|
||||
mountedSeconds.value = Math.floor((Date.now() - mountedAt) / 1_000)
|
||||
}, 200)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (timer !== undefined) window.clearInterval(timer)
|
||||
}
|
||||
update()
|
||||
const timer = window.setInterval(update, 200)
|
||||
return () => window.clearInterval(timer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="screen screen--tabs runtime-lab-screen">
|
||||
<main class="screen screen--tabs runtime-lab-screen" data-testid="runtime-lab-view" :data-mount-id="mountId">
|
||||
<AppHeader title="Runtime stress lab" subtitle="A cached push-history sibling" back />
|
||||
|
||||
<section class="lab-intro lab-intro--timer">
|
||||
@@ -31,7 +30,7 @@ onBeforeUnmount(() => {
|
||||
<p
|
||||
data-testid="mounted-seconds"
|
||||
:data-seconds="mountedSeconds"
|
||||
>This timer continues while the route is cached and out of view.</p>
|
||||
>Elapsed mount time is preserved, while interval work pauses whenever this view is inactive.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -61,7 +60,7 @@ onBeforeUnmount(() => {
|
||||
<span><strong>Sibling history</strong><small>This route pushes instead of replacing Profile</small></span>
|
||||
<b>push</b>
|
||||
</div>
|
||||
<p>Use Back to return to Profile. The route remains mounted in the native view cache, so its timer and resolved async component keep their state.</p>
|
||||
<p>Use Back to return to Profile. Because this is a pushed sibling, it is unmounted after its exit animation; replaced primary siblings remain lazily cached instead.</p>
|
||||
</section>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { useNativeRouter } from '@native-vue-router/core'
|
||||
import AppHeader from '../components/AppHeader.vue'
|
||||
import { useDemoStore } from '../data'
|
||||
import { pwaBuildId, pwaEnvironment } from '../pwa'
|
||||
|
||||
const store = useDemoStore()
|
||||
const native = useNativeRouter()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -22,6 +24,14 @@ const store = useDemoStore()
|
||||
<p v-if="pwaEnvironment.ios && !pwaEnvironment.standalone">In Safari, choose Share → Add to Home Screen, then launch the new icon. Edge interception is intentionally disabled inside a normal browser tab.</p>
|
||||
<p v-else-if="pwaEnvironment.ios">The leading edge is reserved before WebKit navigation begins. Open a conversation and drag from the extreme left edge to verify the live back preview.</p>
|
||||
</section>
|
||||
<section class="settings-group">
|
||||
<h2>Native view cache</h2>
|
||||
<div><span><strong>Mounted views</strong><small>{{ native.cacheStats.value.inactive }} inactive of {{ native.cacheStats.value.maxInactive }} allowed</small></span><b data-testid="cache-mounted">{{ native.cacheStats.value.mounted }}</b></div>
|
||||
<div><span><strong>Route descriptors</strong><small>{{ native.cacheStats.value.evicted }} currently evicted</small></span><b>{{ native.cacheStats.value.descriptors }}</b></div>
|
||||
<div><span><strong>Total evictions</strong><small>{{ native.cacheStats.value.lastEviction?.reason ?? 'No eviction yet' }}</small></span><b data-testid="cache-evictions">{{ native.cacheStats.value.totalEvictions }}</b></div>
|
||||
<p>Sibling tabs are created on first visit, then retained. Back-stack screens stay warm only while they remain useful as a predictive-back target.</p>
|
||||
</section>
|
||||
<button class="reset-button reset-button--neutral" type="button" @click="native.trimCache()">Trim inactive view cache</button>
|
||||
<section class="settings-group">
|
||||
<h2>Simulation</h2>
|
||||
<label><span><strong>Network latency</strong><small>{{ store.settings.simulatedLatency }} ms</small></span><input v-model.number="store.settings.simulatedLatency" type="range" min="0" max="1200" step="20" /></label>
|
||||
|
||||
@@ -1,9 +1,25 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useNativeViewActiveEffect } from '@native-vue-router/core'
|
||||
import AppAvatar from '../components/AppAvatar.vue'
|
||||
import AppHeader from '../components/AppHeader.vue'
|
||||
import { useDemoStore } from '../data'
|
||||
|
||||
const store = useDemoStore()
|
||||
const mountId = crypto.randomUUID()
|
||||
const mountedAt = Date.now()
|
||||
const mountedSeconds = ref(0)
|
||||
const activeTicks = ref(0)
|
||||
|
||||
useNativeViewActiveEffect(() => {
|
||||
const update = () => {
|
||||
mountedSeconds.value = Math.floor((Date.now() - mountedAt) / 1_000)
|
||||
activeTicks.value += 1
|
||||
}
|
||||
update()
|
||||
const timer = window.setInterval(update, 200)
|
||||
return () => window.clearInterval(timer)
|
||||
})
|
||||
const gradients = [
|
||||
'linear-gradient(155deg, #f4a261, #d64e7d 48%, #5427a8)',
|
||||
'linear-gradient(155deg, #44c6e9, #4378db 48%, #1b245d)',
|
||||
@@ -13,7 +29,13 @@ const gradients = [
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="screen screen--tabs">
|
||||
<main
|
||||
class="screen screen--tabs"
|
||||
data-testid="stories-view"
|
||||
:data-mount-id="mountId"
|
||||
:data-mounted-seconds="mountedSeconds"
|
||||
:data-active-ticks="activeTicks"
|
||||
>
|
||||
<AppHeader title="Stories" subtitle="Moments from your circle" large />
|
||||
<section class="story-grid">
|
||||
<article v-for="(person, index) in store.people.value.slice(0, 4)" :key="person.id" class="story-card" :style="{ background: gradients[index] }">
|
||||
@@ -26,6 +48,6 @@ const gradients = [
|
||||
<span class="story-card__mark">{{ ['✦', '◌', '△', '◇'][index] }}</span>
|
||||
</article>
|
||||
</section>
|
||||
<p class="gesture-tip">Swipe horizontally anywhere to move between primary routes.</p>
|
||||
<p class="gesture-tip">Mounted {{ mountedSeconds }}s · active work {{ activeTicks }} ticks. The tick loop pauses while this sibling is cached.</p>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user