Skip to content

Commit

Permalink
Fix memory leaks in <Iframe> (#53406)
Browse files Browse the repository at this point in the history
* Unset node._load after unmounting

* Use weakmap to store container in memoized function
  • Loading branch information
kevin940726 authored Aug 10, 2023
1 parent eb6a8f7 commit b60e368
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
1 change: 1 addition & 0 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ function Iframe( {
node.addEventListener( 'load', onLoad );

return () => {
delete node._load;
node.removeEventListener( 'load', onLoad );
iFrameDocument?.removeEventListener(
'dragover',
Expand Down
31 changes: 19 additions & 12 deletions packages/components/src/style-provider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
import { CacheProvider } from '@emotion/react';
import createCache from '@emotion/cache';
import memoize from 'memize';
import * as uuid from 'uuid';

/**
Expand All @@ -12,19 +11,27 @@ import * as uuid from 'uuid';
import type { StyleProviderProps } from './types';

const uuidCache = new Set();
// Use a weak map so that when the container is detached it's automatically
// dereferenced to avoid memory leak.
const containerCacheMap = new WeakMap();

const memoizedCreateCacheWithContainer = memoize(
( container: HTMLElement ) => {
// Emotion only accepts alphabetical and hyphenated keys so we just
// strip the numbers from the UUID. It _should_ be fine.
let key = uuid.v4().replace( /[0-9]/g, '' );
while ( uuidCache.has( key ) ) {
key = uuid.v4().replace( /[0-9]/g, '' );
}
uuidCache.add( key );
return createCache( { container, key } );
const memoizedCreateCacheWithContainer = ( container: HTMLElement ) => {
if ( containerCacheMap.has( container ) ) {
return containerCacheMap.get( container );
}
);

// Emotion only accepts alphabetical and hyphenated keys so we just
// strip the numbers from the UUID. It _should_ be fine.
let key = uuid.v4().replace( /[0-9]/g, '' );
while ( uuidCache.has( key ) ) {
key = uuid.v4().replace( /[0-9]/g, '' );
}
uuidCache.add( key );

const cache = createCache( { container, key } );
containerCacheMap.set( container, cache );
return cache;
};

export function StyleProvider( props: StyleProviderProps ) {
const { children, document } = props;
Expand Down

0 comments on commit b60e368

Please sign in to comment.