开源日报每天推荐一个 GitHub 优质开源项目和一篇精选英文科技或编程文章原文,坚持阅读《开源日报》,保持每日学习的好习惯。

2024年1月22日,开源日报第1082期:
今日推荐开源项目:《transformers.js》
今日推荐英文原文:《Top Three Causes of Memory Leaks in JavaScript》


开源项目

今日推荐开源项目:《transformers.js》传送门:项目链接

推荐理由: Transformers.js使用ONNX Runtime在浏览器中运行模型,可以轻松地使用🤗 Optimum将预训练的PyTorch、TensorFlow或JAX模型转换为ONNX格式
官网直达:https://huggingface.co/docs/transformers.js/index


英文原文

今日推荐英文原文:Top Three Causes of Memory Leaks in JavaScript

推荐理由:这篇文章主要讲 js 中内存泄漏的三个主要原因:未清除的定时器和计时器、悬挂的事件监听器以及闭包,还有 Chrome DevTools Memory Profiler的实用方法


Top Three Causes of Memory Leaks in JavaScript

Memory Leaks in JavaScript: Top Causes and How to Address Them

One crucial aspect that often goes unnoticed is memory management. Memory leaks, while subtle, can accumulate over time, making applications sluggish and even leading to crashes. This article delves into the top three causes of memory leaks in modern JavaScript and how developers can mitigate them.

What is a Memory Leak?

In simple terms, a memory leak in JavaScript occurs when objects are allocated memory, but that memory isn’t released even after the objects are no longer required. Over time, these leaks accumulate, consuming more and more memory, thereby degrading application performance.

Uncleared Intervals and Timers

Modern web applications often use timers and intervals for tasks like updating UI, polling servers, or adding delays. These are set up using setInterval and setTimeout. However, if these timers aren't cleared when no longer needed, they can lead to significant memory leaks.

Example:

const someData = fetchLatestData(); // A hypothetical function that fetches some data

const intervalID = setInterval(() => {
    updateUI(someData);
}, 1000);

// Later in the code or in some cleanup routine, the interval needs to be cleared.
// If not:
// clearInterval(intervalID);

In this example, if clearInterval isn't called, the interval keeps running indefinitely, holding onto someData and whatever updateUI references.

How to address?

Always ensure that intervals and timeouts are cleared using clearInterval and clearTimeout respectively, especially when the associated tasks or components are destroyed or no longer in use.

Dangling Event Listeners

Event-driven programming is at the heart of JavaScript. However, a common oversight is not removing event listeners after they’ve served their purpose. When DOM elements attached to these listeners are removed, the listeners might still linger if not explicitly detached.

Example:

const buttonElement = document.querySelector("#submit-button");
const userPreferences = getUserPreferences(); // Hypothetical function

buttonElement.addEventListener('click', () => {
    applyPreferences(userPreferences);
});

// Now, if for any reason, the button is removed from the DOM:
// buttonElement.remove();

// The listener is still in memory and so is the 'userPreferences' object.

How to address?

Use the removeEventListener method to detach listeners when they're no longer required or when associated elements are removed from the DOM. Frameworks like React and Vue provide lifecycle methods or hooks to help with this.

Closures

Closures, one of JavaScript’s most powerful features, allow functions to ‘remember’ the environment in which they were created. While incredibly useful, closures can unintentionally hold onto references, leading to memory leaks.

Example:

function createLogger(element) {
    const loggingInfo = getLoggingInfo(); // Hypothetical function fetching some logging data

    return function log() {
        console.log(element, loggingInfo);
    };
}

const someElement = document.querySelector("#info-box");
const logger = createLogger(someElement);
someElement.addEventListener('mouseover', logger);

// If 'someElement' is removed from the DOM or no longer used, the closure 'logger' still retains references.

How to address?

Awareness is the key. While using closures, be mindful of what they reference, especially if those references include large objects or DOM elements. If a closure is used as an event listener, ensure that it’s removed when no longer needed.

img

Tools and Best Practices

Modern browsers and JavaScript engines, like V8 used in Chrome, have made significant strides in garbage collection (an automated process to reclaim unused memory). However, relying solely on garbage collection isn’t foolproof.

Chrome DevTools Memory Profiler is an invaluable tool for developers. It allows for tracking memory usage, spotting leaks, and understanding the overall memory footprint of web applications. Regularly profiling especially during the development phase, can preemptively address memory issues.

In conclusion, while the modern JavaScript landscape has evolved with new frameworks and paradigms, the fundamental principles of good memory management remain. By being aware of common pitfalls like uncleared timers, dangling event listeners, and unintended closures, developers can ensure that their applications remain performant and resilient.


下载开源日报APP:https://openingsource.org/2579/
加入我们:https://openingsource.org/about/join/
关注我们:https://openingsource.org/about/love/