Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix YouTube Embed block from flickering and crashing in Safari #21225

Merged
merged 4 commits into from
Mar 30, 2020

Conversation

ItsJonQ
Copy link

@ItsJonQ ItsJonQ commented Mar 27, 2020

Description

This update fixes the issue where a YouTube video embed in Safari would flicker (and crash).

This issue is due to the inner Sandbox component forcefully re-rendering itself in an loop. This is why there's flickering. This is also why your computer fans may be spinning up (due to requests and stack overflow + memory leaks).

Digging deeper, it appears it has to do with the onLoad callback from the iFrame component.
The onLoad callback provided an event argument, which triggered a force rerender... resulting in a render loop.

How has this been tested?

Tested in local Gutenberg with a YouTube video embed. Both in Chrome and in Safari.

Types of changes

  • Add an additional guard for forceRerender checking to ensure it does not get accidentally triggered by the onLoad callback.

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.
  • I've included developer documentation if appropriate.
  • I've updated all React Native files affected by any refactorings/renamings in this PR.

Resolves: #20614

@ItsJonQ ItsJonQ added [Type] Bug An existing feature does not function as intended [Type] Regression Related to a regression in the latest release [Block] Embed Affects the Embed Block labels Mar 27, 2020
@ItsJonQ ItsJonQ self-assigned this Mar 27, 2020
@ItsJonQ ItsJonQ requested review from aduth and mcsf March 27, 2020 23:25
@github-actions
Copy link

github-actions bot commented Mar 27, 2020

Size Change: -6 B (0%)

Total Size: 861 kB

Filename Size Change
build/block-editor/style-rtl.css 11 kB +6 B (0%)
build/block-editor/style.css 11 kB +6 B (0%)
build/block-library/index.js 110 kB -33 B (0%)
build/components/index.js 190 kB +15 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 998 B 0 B
build/annotations/index.js 3.44 kB 0 B
build/api-fetch/index.js 3.39 kB 0 B
build/autop/index.js 2.58 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/index.js 6.02 kB 0 B
build/block-directory/style-rtl.css 760 B 0 B
build/block-directory/style.css 760 B 0 B
build/block-editor/index.js 102 kB 0 B
build/block-library/editor-rtl.css 7.21 kB 0 B
build/block-library/editor.css 7.21 kB 0 B
build/block-library/style-rtl.css 7.5 kB 0 B
build/block-library/style.css 7.51 kB 0 B
build/block-library/theme-rtl.css 669 B 0 B
build/block-library/theme.css 671 B 0 B
build/block-serialization-default-parser/index.js 1.64 kB 0 B
build/block-serialization-spec-parser/index.js 3.1 kB 0 B
build/blocks/index.js 57.5 kB 0 B
build/components/style-rtl.css 15.8 kB 0 B
build/components/style.css 15.7 kB 0 B
build/compose/index.js 6.2 kB 0 B
build/core-data/index.js 10.6 kB 0 B
build/data-controls/index.js 1.04 kB 0 B
build/data/index.js 8.26 kB 0 B
build/date/index.js 5.37 kB 0 B
build/deprecated/index.js 772 B 0 B
build/dom-ready/index.js 568 B 0 B
build/dom/index.js 3.06 kB 0 B
build/edit-post/index.js 92.3 kB 0 B
build/edit-post/style-rtl.css 8.35 kB 0 B
build/edit-post/style.css 8.34 kB 0 B
build/edit-site/index.js 8.63 kB 0 B
build/edit-site/style-rtl.css 3.44 kB 0 B
build/edit-site/style.css 3.44 kB 0 B
build/edit-widgets/index.js 4.43 kB 0 B
build/edit-widgets/style-rtl.css 2.57 kB 0 B
build/edit-widgets/style.css 2.57 kB 0 B
build/editor/editor-styles-rtl.css 423 B 0 B
build/editor/editor-styles.css 426 B 0 B
build/editor/index.js 42.8 kB 0 B
build/editor/style-rtl.css 3.38 kB 0 B
build/editor/style.css 3.38 kB 0 B
build/element/index.js 4.44 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/index.js 6.95 kB 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/hooks/index.js 1.93 kB 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 3.57 kB 0 B
build/is-shallow-equal/index.js 710 B 0 B
build/keyboard-shortcuts/index.js 2.3 kB 0 B
build/keycodes/index.js 1.7 kB 0 B
build/list-reusable-blocks/index.js 2.99 kB 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/media-utils/index.js 4.84 kB 0 B
build/notices/index.js 1.57 kB 0 B
build/nux/index.js 3.01 kB 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/plugins/index.js 2.54 kB 0 B
build/primitives/index.js 1.5 kB 0 B
build/priority-queue/index.js 781 B 0 B
build/redux-routine/index.js 2.83 kB 0 B
build/rich-text/index.js 14.5 kB 0 B
build/server-side-render/index.js 2.55 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.28 kB 0 B
build/url/index.js 4.01 kB 0 B
build/viewport/index.js 1.61 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.18 kB 0 B

compressed-size-action

@ItsJonQ
Copy link
Author

ItsJonQ commented Mar 27, 2020

Shout out to @mcsf for debugging and collab'ing on this one!

Copy link
Contributor

@mcsf mcsf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix!

While I'm fine with this approach and have approved the PR, I'm wondering (nitpicking?) about the type juggling that happens due to trySandbox being called either with a boolean or with an event as a handler of onLoad.

(It's the kind of thing we would have caught with type checking, which is always a little frustrating.)

In my mind, the event should not be passed to the function in the first place, so the alternative fix would be to have onLoad={ () => this.trySandbox() } — or the equivalent using components methods, e.g. onLoad={ this.onLoad } and this.onLoad = this.trySandbox.bind( this, false ).

@ItsJonQ
Copy link
Author

ItsJonQ commented Mar 30, 2020

In my mind, the event should not be passed to the function in the first place, so the alternative fix would be to have onLoad={ () => this.trySandbox() } — or the equivalent using components methods, e.g. onLoad={ this.onLoad } and this.onLoad = this.trySandbox.bind( this, false ).

@mcsf I agree! I'll make that update :)

@ItsJonQ ItsJonQ force-pushed the fix/embed-preview-safari-iframe-flickering branch from 5e45245 to 3618795 Compare March 30, 2020 14:08
@@ -232,7 +233,7 @@ class Sandbox extends Component {
title={ title }
className="components-sandbox"
sandbox="allow-scripts allow-same-origin allow-presentation"
onLoad={ this.trySandbox }
onLoad={ () => this.trySandbox() }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you test this to make sure it's not causing unnecessary re-renders down the tree? Since this component is already a class, then to avoid re-renders we might as well add:

constructor() {
  
  this.onLoad = this.trySandbox.bind( this, false );
}


<FocusableIframe
  onLoad={ this.onLoad }

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mcsf I just tested! Both solutions (the one I pushed) and the one you proposed, have the same amount of renders for both Sandbox and FocusableIframe (4 for me).

As far as implementation, I'm happy to go with either 👍 .

Just lemme know :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for checking — merge away :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, actually, make it an explicit => this.trySandbox( false )!

@ItsJonQ
Copy link
Author

ItsJonQ commented Mar 30, 2020

Thank you so much @mcsf !!

I'll merge as soon as Travis is green and happy

@ItsJonQ ItsJonQ merged commit ab7b81b into master Mar 30, 2020
@ItsJonQ ItsJonQ deleted the fix/embed-preview-safari-iframe-flickering branch March 30, 2020 15:57
@github-actions github-actions bot added this to the Gutenberg 7.9 milestone Mar 30, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Block] Embed Affects the Embed Block [Type] Bug An existing feature does not function as intended [Type] Regression Related to a regression in the latest release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Embeds flicker in editor in Safari as of 7.6
2 participants