perf: use setInterval instead of setTimeout chain in MkTime

This commit is contained in:
tamania 2023-06-23 18:33:37 -07:00 committed by ThatOneCalculator
parent be83ac8f43
commit c462d48bdb
No known key found for this signature in database
GPG key ID: 8703CACD01000000
2 changed files with 60 additions and 21 deletions

View file

@ -1,21 +1,23 @@
<template> <template>
<time :title="absolute"> <time :title="absolute">
<template v-if="mode === 'relative'">{{ relative }}</template> <template v-if="invalid">{{ i18n.ts._ago.invalid }}</template>
<template v-else-if="mode === 'relative'">{{ relative }}</template>
<template v-else-if="mode === 'absolute'">{{ absolute }}</template> <template v-else-if="mode === 'absolute'">{{ absolute }}</template>
<template v-else-if="mode === 'detail'" <template v-else-if="mode === 'detail'"
>{{ absolute }} ({{ relative }})</template >{{ absolute }} ({{ relative }})</template
> >
<slot></slot>
</time> </time>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onUnmounted } from "vue"; import { onMounted, onUnmounted } from "vue";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { dateTimeFormat } from "@/scripts/intl-const";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
time: Date | string; time: Date | string | number | null;
origin?: Date | null;
mode?: "relative" | "absolute" | "detail"; mode?: "relative" | "absolute" | "detail";
}>(), }>(),
{ {
@ -24,12 +26,23 @@ const props = withDefaults(
); );
const _time = const _time =
typeof props.time === "string" ? new Date(props.time) : props.time; props.time == null
const absolute = _time.toLocaleString(); ? NaN
: typeof props.time === "number"
? props.time
: (props.time instanceof Date
? props.time
: new Date(props.time)
).getTime();
const invalid = Number.isNaN(_time);
const absolute = !invalid ? dateTimeFormat.format(_time) : i18n.ts._ago.invalid;
let now = $shallowRef(new Date()); let now = $ref((props.origin ?? new Date()).getTime());
const relative = $computed(() => { const relative = $computed<string>(() => {
const ago = (now.getTime() - _time.getTime()) / 1000; /*ms*/ if (props.mode === "absolute") return ""; // absoluterelative使
if (invalid) return i18n.ts._ago.invalid;
const ago = (now - _time) / 1000; /*ms*/
return ago >= 31536000 return ago >= 31536000
? i18n.t("_ago.yearsAgo", { n: Math.round(ago / 31536000).toString() }) ? i18n.t("_ago.yearsAgo", { n: Math.round(ago / 31536000).toString() })
: ago >= 2592000 : ago >= 2592000
@ -49,22 +62,36 @@ const relative = $computed(() => {
: i18n.ts._ago.future; : i18n.ts._ago.future;
}); });
function tick() {
// TODO:
now = new Date();
tickId = window.setTimeout(() => {
window.requestAnimationFrame(tick);
}, 10000);
}
let tickId: number; let tickId: number;
if (props.mode === "relative" || props.mode === "detail") { function tick() {
tickId = window.requestAnimationFrame(tick); const _now = new Date().getTime();
const agoPrev = (now - _time) / 1000; /*ms*/ // interval
now = _now;
const ago = (now - _time) / 1000; /*ms*/ // interval
const prev = agoPrev < 60 ? 10000 : agoPrev < 3600 ? 60000 : 180000;
const next = ago < 60 ? 10000 : ago < 3600 ? 60000 : 180000;
if (!tickId) {
tickId = window.setInterval(tick, next);
} else if (prev < next) {
window.clearInterval(tickId);
tickId = window.setInterval(tick, next);
}
}
if (
!invalid &&
props.origin === null &&
(props.mode === "relative" || props.mode === "detail")
) {
onMounted(() => {
tick();
});
onUnmounted(() => { onUnmounted(() => {
window.cancelAnimationFrame(tickId); if (tickId) window.clearInterval(tickId);
}); });
} }
</script> </script>

View file

@ -0,0 +1,12 @@
import { lang } from "@/config";
export const versatileLang = (lang ?? "ja-JP").replace("ja-KS", "ja-JP");
export const dateTimeFormat = new Intl.DateTimeFormat(versatileLang, {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
});
export const numberFormat = new Intl.NumberFormat(versatileLang);