Similar a esta pregunta: Fetch API pierde memoria en Chrome
Cuando se usa fetch para sondear datos regularmente, el uso de memoria de Chrome aumenta continuamente sin liberar la memoria, lo que eventualmente provoca un bloqueo.
https://jsfiddle.net/abfinz/ahc65y3s/13/
const state = { response: {}, count: 0 } function poll(){ fetch('https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg') .then(response => { state.response = response; state.count = state.count + 1; if (state.count < 20){ console.log(state.count); setTimeout(poll, 3000); } else { console.log("Will restart in 1 minute"); state.count = 0; setTimeout(poll, 60000); } }); } poll();Este JSFiddle demuestra el problema bastante bien. Al buscar datos cada 3 segundos, parece que algo está causando que Chrome retenga continuamente la memoria. Si dejo que se detenga y espero unos minutos, generalmente liberará la memoria, pero si continúa el sondeo, generalmente la conservará. Además, si dejo que se ejecute durante algunos ciclos completos, incluso forzar la recolección de basura desde la pestaña de rendimiento de las herramientas de desarrollo no siempre libera toda la memoria.
¿Estoy haciendo algo mal o es un error? ¿Alguna idea sobre cómo puedo hacer que este tipo de sondeo funcione a largo plazo sin la pérdida de memoria?
Jugué un poco con él y parece ser un error con el manejo de la respuesta, por lo que no liberará la memoria asignada si no está llamando a ninguna de las funciones de respuesta.
El administrador de tareas de Chrome y el administrador de tareas de Windows informan el mismo tamaño de 30 MB constantemente si inicio el fragmento de código aquí usando este orden de ejecución. Mientras tanto, también se ejecuta en jsfiddle con 30 MB a pedido #120.
const state = { response: {}, count: 0 }, uri = 'https://upload.wikimedia.org/wikipedia/commons/3/3d/LARGE_elevation.jpg'; !function poll() { const controller = new AbortController(), signal = controller.signal; // using this you can cancel it and destroy it completly. fetch(uri, { signal }) // this is triggered as soon as the header data is transfered .then(response => { /** * Continung without doing anything on response * fills the memory. * * Chrome downloads the file in the background and * seems to wait for the use of a call on the * response.fx() or an abort signal. * * This seems to be a bug or a small design mistake * if response is never used. * * If response.json(), .blob(), .body() or .text() is * called the memory will be free'd. */ return response.blob(); }).then((binary) => { // store data to a var return state.response = binary; }).catch((err) => { console.error(err); }).finally(() => { // and start the next poll console.log(++state.count, state.response.type, (state.response.size / 1024 / 1024).toFixed(2)+' MB'); requestAnimationFrame(poll); // console.dir(state.response); // reduces memory a bit more controller.abort(); }) }()