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

amp-script: Filter user-visible mutations during hydration #26401

Merged
merged 5 commits into from Feb 4, 2020

Conversation

dreamofabear
Copy link

@dreamofabear dreamofabear commented Jan 18, 2020

@dreamofabear dreamofabear marked this pull request as ready for review January 24, 2020 19:27
errors[type] = errors[type] + 1 || 1;
});
// Emit an error message for each mutation type, including count.
Object.keys(errors).forEach(type => {
Copy link
Member

Choose a reason for hiding this comment

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

nit: Object.entries would give you both key and value, for a more concise loop.

Copy link
Author

Choose a reason for hiding this comment

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

Not safe to use unfortunately. https://caniuse.com/#feat=object-entries

Looks like we ban it in conformance-config.textproto too.

Comment on lines +89 to +94
// However, gesture-backed (e.g. click) mutations are OK.
const button = await controller.findElement('#mutate button');
controller.click(button);

const h1 = await controller.findElement('#mutate h1');
await expect(controller.getElementText(h1)).to.contain('Lorem Ipsum');
Copy link
Member

Choose a reason for hiding this comment

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

only the first part of this test is actually for the 'hydration' phase. The 'click' occurs afterwards, and is really testing that the event listener was added. I think thats fine, since the second half is still useful (test that adding event listeners still works)

Copy link
Author

Choose a reason for hiding this comment

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

Yea, as you mention the distinction for "hydration" is not really useful. It's only mentioned here due to the bug.

// In layout=container, amp-script requires mutations to be backed by
// user gestures. This ensures that this requirement is also enforced
// on load AKA "hydration".
it('should not mutate on load in layout=container', async () => {
Copy link
Member

Choose a reason for hiding this comment

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

Is there anywhere where we are testing the inverse? e.g. it('should mutate on load in layout=fixed').

Copy link
Author

Choose a reason for hiding this comment

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

Yea, the first two tests cover that case.

Copy link
Member

@samouri samouri left a comment

Choose a reason for hiding this comment

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

this is a useful change, feel free to ignore my nits

@samouri
Copy link
Member

samouri commented Jan 28, 2020

question! why do we special case hydration?
could we always allow invisible mutations? (incl. setState w/ skipEval)

@dreamofabear
Copy link
Author

question! why do we special case hydration?

Right, this PR kind of removes it. The remainder is probably what you're suggesting: https://github.com/ampproject/amphtml/pull/26401/files#diff-2309faf5b32ca308fd2bb6e38e44d29eR440

@dreamofabear dreamofabear merged commit 56fff2c into ampproject:master Feb 4, 2020
@dreamofabear dreamofabear deleted the hydrate-mutate-bug branch February 4, 2020 01:07
@samouri
Copy link
Member

samouri commented Feb 11, 2020

Do Preact/React need to be able to take advantage of the hydration phase mutations to create their dom elements?

e.g. if someone were using amp-script and had code like this example, wouldn't Preact try to initialize it by instantly rendering (or rendering without user input) all the initial dom nodes.

<amp-script id="root" height="400" width="400" script="preact-script"></amp-script>
<script type="text/plain" target="amp-script">

  import { render } from 'preact';

  function MyApp() {
   ...
  }

  const root = document.getElementById('root');
  render(<MyApp/> root)
</script>

@dreamofabear
Copy link
Author

Correct, you need to configure Preact/React to use SSR mode. https://reactjs.org/docs/react-dom.html#hydrate

@morsssss
Copy link
Contributor

And this will apply to all <amp-script>'s? Not just ones with layout!='container' and defined dimensions?

@samouri
Copy link
Member

samouri commented Feb 13, 2020

This only applies to the dynamic size amp-scripts (layout==container and layout!=container, dimensions not set).

Fixed size components still have no restrictions

@morsssss
Copy link
Contributor

Thanks!

/cc @AndrewKGuan

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

amp-script: Size-changing DOM mutations on initial load
5 participants