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

Validator: Allow SSR for amp-img's img #29025

Closed
wants to merge 6 commits into from

Conversation

jridgewell
Copy link
Contributor

This adds validator support for server-side rendering an <amp-img>.

The one weird part of this is the requirement that the SSR'd <amp-img> include a i-amphtml-ssr attribute. I think this was necessary because we couldn't properly support intrinsic and blurry-image placeholder SSR at the same time. But with recent bug fixes, this shouldn't be a blocker anymore. So, we could remove the i-amphtml-ssr requirement, which will remove the duplicate tag spec here.

Fixes #28672.

@jridgewell jridgewell requested a review from sebastianbenz June 24, 2020 18:50
@amp-owners-bot amp-owners-bot bot requested a review from amaltas June 24, 2020 18:50
@amp-owners-bot
Copy link

amp-owners-bot bot commented Jun 24, 2020

Hey @ampproject/wg-caching! These files were changed:

validator/testdata/transformed_feature_tests/amp-img.html
validator/testdata/transformed_feature_tests/amp-img.out
validator/validator-main.protoascii

# requires an i-amphtml-ssr attribute on the amp-img. We could do away with
# that, though.
mandatory_parent: "amp-img (transformed)"
attrs: { name: "alt" }
Copy link
Contributor

@sebastianbenz sebastianbenz Jun 24, 2020

Choose a reason for hiding this comment

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

Do we need to require class="i-amphtml-fill-content i-amphtml-replaced-content" which get added by the runtime?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could, but:

Copy link
Contributor

Choose a reason for hiding this comment

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

It wouldn't allow the reverse order, which might be weird?

Agree, not ideal. Could be OK in the case of transformed AMP.

Copy link
Member

Choose a reason for hiding this comment

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

@jridgewell jridgewell requested review from Gregable and removed request for amaltas June 24, 2020 21:13
Copy link
Contributor

@sebastianbenz sebastianbenz left a comment

Choose a reason for hiding this comment

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

Looks good! Thanks for the quick turnaround.

@jridgewell jridgewell force-pushed the amp-img-ssr branch 2 times, most recently from 6ddf602 to 8bf129d Compare June 26, 2020 02:24
@banaag banaag requested a review from twifkak June 29, 2020 19:35
@banaag
Copy link
Contributor

banaag commented Jun 29, 2020

@Gregable is out this week, adding @twifkak

<body>
<!-- Valid: amp-img > img -->
<amp-img src="/img/canoe_900x600.jpg" alt="An image about canoeing" layout="responsive" width="900" height="600" i-amphtml-ssr>
<img src="/img/canoe_900x600.jpg" alt="An image about canoeing" decoding="async" loading="lazy">
Copy link
Member

Choose a reason for hiding this comment

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

In advance of landing this PR, it would be helpful to add a Google-internal test that the cache-side transforms, when applied to such a file, convert both of these URLs to cache URLs. Reasons:

  • Privacy preservation on browsers that don't support loading=lazy (plus maybe they'll add more interventions over time besides scripting disabled?).
  • Ensure cache-side image transforms for UX/sec.

Filed b/160184148.

# requires an i-amphtml-ssr attribute on the amp-img. We could do away with
# that, though.
mandatory_parent: "amp-img (transformed)"
attrs: { name: "alt" }
Copy link
Member

Choose a reason for hiding this comment

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

@jridgewell
Copy link
Contributor Author

Closing for cl/320708127.

@jridgewell jridgewell closed this Jul 11, 2020
}
attrs: {
name: "loading"
value: "lazy"
Copy link
Member

Choose a reason for hiding this comment

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

Did we test whether loading=lazy still triggers preload scanner to fetch the hero image pre-layout?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, this is a good point. Testing with https://output.jsbin.com/husuxij/quiet:

Browser Loading Pre-scan?
Chrome 83 Lazy
^ Eager
Safari TP 109 Lazy
^ Eager
Firefox 80 Nightly Lazy
^ Eager

@sebastianbenz: I'm assuming this means we need to use non-lazy loading for SSR images?

Copy link
Member

Choose a reason for hiding this comment

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

We should probably only allow 1-2 non-lazy images per doc. I'm not sure how much sense it makes to add the lazy images at all. I think the simplest would be to make these non-lazy and only allow a small amount.

Copy link
Contributor

Choose a reason for hiding this comment

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

preload scanner to fetch the hero image pre-layout

for my own edification: Is this relevant in the case of SSR without boilerplate?

Copy link
Member

Choose a reason for hiding this comment

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

Yep, the impact is actually roughly the same in both cases as the boilerplate does not block layout (it just blocks visibility of content). You still get a win without the prescanner, as you can get downloads before JS loads, however, you'd expect a big win with the prescanner because

  • layout can be expensive
  • AMP's JS may run before layout when it is cached

Copy link
Contributor

Choose a reason for hiding this comment

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

Outside of Chrome, this would only work for images without srcset due to lack of support for imagesrcset.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's currently a imagesrcset transformer that rewrite them to multiple <link rel=preload media="…"> with mutually exclusive media queries. We need to expand this to support imagesizes, but I think we can use the same general idea for better support.

Copy link
Member

Choose a reason for hiding this comment

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

I've given feedback before that while that might seem to work it is a very dangerous game. E.g. a browser in data-saver mode might choose to pick a smaller srcset value than the media query would yield leading to double download.

Why can't we generate <img srcset="…" sizes="…" style="display:none"> in place of <link rel=preload as=image>?

Copy link
Member

@twifkak twifkak Aug 18, 2020

Choose a reason for hiding this comment

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

Re: @jridgewell's comment from Jul 14, if I set the script to async and set body visibility to hidden, the lazy image is fetched immediately. See https://output.jsbin.com/potuwanuco.

Are the pre-visibility: visible AMP layouts a useful approximation of which images will be above the fold post-full-layout? If so, there could be value in setting <img loading=lazy> on all images. Then we let the browser decide which images to fetch/decode before AMP layout has finished.

Could be combined with hero image detection for a more explicit <link rel=preload> (or <img style="display:none"> per @cramforce's last comment) where we're confident.

On cache side, it would need to be removed for privacy, but still useful on-origin and on-SXG.

Copy link
Member

Choose a reason for hiding this comment

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

correction: Wouldn't need to be removed for privacy, since they'd be rewritten URLs. Might want to remove to reduce data usage, for when navigation doesn't happen.

honeybadgerdontcare pushed a commit to ampproject/amppackager that referenced this pull request Jul 21, 2020
…re applied to all <img> tags, not just those inside <noscript>. This is relevant as of ampproject/amphtml#29025.

PiperOrigin-RevId: 318935030
Gregable pushed a commit to ampproject/amppackager that referenced this pull request Jul 28, 2020
…re applied to all <img> tags, not just those inside <noscript>. This is relevant as of ampproject/amphtml#29025.

PiperOrigin-RevId: 318935030
twifkak added a commit to ampproject/amppackager that referenced this pull request Jul 28, 2020
…re applied to all <img> tags, not just those inside <noscript>. This is relevant as of ampproject/amphtml#29025.

PiperOrigin-RevId: 318935030
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 Validator: support server-side rendering img tags
6 participants