開源日報每天推薦一個 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/