Heim >Web-Frontend >js-Tutorial >Testen Sie, dass jeder MutationObserver getrennt ist, um Speicherlecks zu vermeiden

Testen Sie, dass jeder MutationObserver getrennt ist, um Speicherlecks zu vermeiden

WBOY
WBOYOriginal
2024-08-22 22:34:02902Durchsuche

Test that every MutationObserver is disconnected to avoid memory leaks

MutationObserver ist ein nützlicher Mechanismus, um auf Änderungen im DOM zu achten und darauf zu reagieren.

Die MutationObserver-Schnittstelle bietet die Möglichkeit, auf Änderungen zu achten, die am DOM-Baum vorgenommen werden.

Hier ist ein Beispiel, das auf einen Themenklassenwechsel achtet.

    function setUpThemeClassObservers() {
        const observer = new MutationObserver(() => {
            const themeClass = this.getThemeClass();
            this.fireStylesChangedEvent('themeChanged');
        });

        observer.observe(this.eGridDiv, {
            attributes: true,
            attributeFilter: ['class'],
        });

        // we must disconnect otherwise "this" will not be GC'd
        // causing a memory leak
        return () => observer.disconnect();
    }

Wenn Sie jedoch vergessen, die Verbindung zu trennen, kann es zu Speicherverlusten kommen, je nachdem, worauf innerhalb der MutationObserver-Funktionen zugegriffen wird.

Wäre es nicht großartig, einen Test zu haben, der bestätigen kann, dass wir unsere Beobachter abkoppeln?

Automatische Validierung für Code

Es stellt sich heraus, dass es möglich ist, zu validieren, dass jeder MutationObserver, der das DOM beobachtet, ebenfalls getrennt ist. (Möglicherweise benötigen Sie mehr als einen Test, wenn Sie unterschiedliche Codepfade ausführen müssen, um die MutationObservers einzurichten)

Die Idee besteht darin, den globalen MutationObserver mit Sub-Mocks für seine Beobachtungs- und Trennmethoden zu verspotten. Bevor der Mock zurückgegeben wird, zeichnen wir ihn in einem Array auf, damit wir am Ende des Testlaufs alle Instanzen validieren können.

describe('Mutation Observers Disconnected', () => {

    let originalMutationObserver: typeof MutationObserver;

    const allMockedObservers: any = [];
    const mutationObserverMock = jest.fn<MutationObserver, [MutationCallback]>().mockImplementation(() => {
        const mock = {
            observe: jest.fn(),
            disconnect: jest.fn(),
            takeRecords: jest.fn(),
        };
        allMockedObservers.push(mock);
        return mock;
    });

    beforeEach(() => {
        // Ensure we can restore the real MutationObserver after the test
        originalMutationObserver = global.MutationObserver;
        global.MutationObserver = mutationObserverMock;
    });

    afterEach(() => {
        global.MutationObserver = originalMutationObserver;
    });

    test('observer always disconnected after destroy', async () => {
        const api = createGrid();
        // Perform some actions if required to exercise the code paths
        api.destroy();

        expect(allMockedObservers.length).toBeGreaterThan(0);
        for (const mock of allMockedObservers) {
            expect(mock.observe).toHaveBeenCalled();
            expect(mock.disconnect).toHaveBeenCalled();
        }
    });
});

Auf diese Weise können wir validieren, dass jeder MutationObserver, der während des Tests eingerichtet wurde, am Ende des Tests auch getrennt wird.


Stephen Cooper – Senior Developer bei AG Grid
Folge mir auf X @ScooperDev

Das obige ist der detaillierte Inhalt vonTesten Sie, dass jeder MutationObserver getrennt ist, um Speicherlecks zu vermeiden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn