несогласованная скорость выполнения setinterval в проекте expo на разных платформах (web, expo go и apk)

#react-native #react-hooks #expo #setinterval #expo-go

Вопрос:

Я запускаю функцию каждую секунду и наблюдаю за временем ее выполнения, сравнивая с ее точным временем выполнения.

Когда я запускаю приведенный ниже код с помощью открытого веб-сайта expo, скорость рендеринга/выполнения компонента в порядке, и я вижу, что дата.теперь время идет вперед и назад с приблизительной разницей в 10 миллисекунд, что здорово.

Однако, когда я запускаю этот код на своем телефоне с помощью expo go. Скорость выполнения замедляется из-за кучи, и дрейф постепенно увеличивается. Что, как я предполагаю, вызвано тем, что expo go имитирует окружающую среду.

Обновление: Но тогда все становится действительно интересным: после компиляции apk (сборка expo:android-t apk) время выполнения каждого подсчета на самом деле последовательно составляет менее 1 секунды. Так как при выполнении в 5-й раз время с даты может быть 1637372693 123, время выполнения в 6-й раз будет 1637372694 110.

Это наблюдается уже более 400 казней и потенциально может стать более серьезной проблемой. Я хотел бы знать систематический способ решения этой проблемы.

 import React, { useEffect, useState } from "react";
import {Text,Button, View} from 'react-native';
export default function Home(props){
    const [timerCount, setTimer] = useState(parseInt(props.time))
    const [timepair,setTimePair] = useState([[0,0]])
    const [start,setStart] = useState(false)
    useEffect(() => {
        let interval = setInterval(() => {
        setTimer(lastTimerCount => {
            //lastTimerCount <= 0 amp;amp; clearInterval(interval);
            //console.log(lastTimerCount)
            if (lastTimerCount === 0){
                return props.time
            } else{
                return lastTimerCount - 1
            }
        });
        setTimePair(lasttimepair=>{
            let timepair = JSON.parse(JSON.stringify(lasttimepair))
            timepair.push([timepair[timepair.length-1][0] 1,(new Date()).getTime()]) 
            return timepair
        });
      }, 1000) //each count lasts for a second
      //cleanup the interval on complete
      return () => clearInterval(interval)
    }, []);
    return (
        <View>
            <Text>{timerCount}</Text>
            <Text>{timepair[timepair.length-1]} </Text>
            <Button title = "start" onPress = {()=>setStart(startstatus=>{return !startstatus})}/>
            <Text>{String(start)}</Text>
        </View>
    )
}
 

Ответ №1:

Код, который вы запускаете в режиме отладки, всегда будет работать медленнее, чем скомпилированное приложение. Это не тот же код — это приближение, но с добавленными слоями для удобства использования и отладки. Вполне вероятно, что ваш веб-браузер работает на гораздо более мощном процессоре, что поможет объяснить увеличение производительности.

Что касается скомпилированного приложения, работающего с опережением графика, это более интересно, и у меня нет для этого хорошей теории. Возможно, собственная среда пытается компенсировать обработку, которую она выполняет в другом месте, и запускает ваш таймер слишком рано. Если вы позволите ему работать некоторое время, будет ли он быстрее по сравнению с часами?