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

feat(common): add <link> preload tag on server for priority img #47343

Conversation

yharaskrik
Copy link
Contributor

While in Angular Universal, for images that are priority add a preload tag to the to ensure the image is preloaded before it is rendered. This resolves a warning when running Lighthouse.

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

Currently when using the NgOptimizedImage directive on <img> tags with the priority attribute (as suggested in the docs), Lighthouse will show a warning about preloading some assets to improve LCP metrics.

More here: https://web.dev/preload-critical-assets/#effects-of-preloading-on-core-web-vitals

Issue Number: N/A

What is the new behavior?

While rendering a page in Angular Universal if an image is going to be loaded with priority="true" then add a preload tag to the so that when the browsers renders the static HTML (rendered from the server) there are preload links for the browser to start loading the LCP images ahead of time and thus satisfying Lighthouse.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Investigation numbers here: https://twitter.com/JayCooperBell/status/1566231614849331200

@pullapprove pullapprove bot requested a review from alxhub September 4, 2022 23:57
@yharaskrik yharaskrik force-pushed the jaybell/create-link-preload-tag-in-universal-for-priority-images branch from 593690d to e0dfadb Compare September 5, 2022 20:47
@AndrewKushnir AndrewKushnir requested review from AndrewKushnir and removed request for alxhub September 6, 2022 04:00
@AndrewKushnir AndrewKushnir added action: review The PR is still awaiting reviews from at least one requested reviewer area: common Issues related to APIs in the @angular/common package target: major This PR is targeted for the next major release common: image directive labels Sep 6, 2022
@ngbot ngbot bot added this to the Backlog milestone Sep 6, 2022
Copy link
Contributor

@kara kara 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 PR! In general, looks good, but needs a test

@yharaskrik yharaskrik requested review from kara and removed request for AndrewKushnir September 19, 2022 20:05
@yharaskrik yharaskrik force-pushed the jaybell/create-link-preload-tag-in-universal-for-priority-images branch from c717fb8 to 2951b45 Compare September 19, 2022 20:07
@AndrewKushnir
Copy link
Contributor

@yharaskrik thanks again for working on this feature! We think it'd bring a lot of value in SSR scenarios and we'd like to merge it before the v15 feature freeze date (Oct 12). Please let us know if you may have a chance to look into this and/or you want us to help with some of the changes. If I understand correctly, the remaining items are:

After that we can start the final code-review round, perform the necessary tests in Google's codebase and we should be ready for merge.

Thank you.

@yharaskrik
Copy link
Contributor Author

@AndrewKushnir sounds good! Just replied to Kara for some additional clarification as unless I'm missing something I don't see what she is referring to currently in the code, but maybe I'm missing it!

I'll make the config related changes tonight hopefully!

@AndrewKushnir
Copy link
Contributor

@yharaskrik just wanted to ask if you want us to help somehow with the changes from this PR and/or there are open questions we can help address.

@yharaskrik
Copy link
Contributor Author

@yharaskrik just wanted to ask if you want us to help somehow with the changes from this PR and/or there are open questions we can help address.

Hey @AndrewKushnir! Sorry things got crazy this last week, I do have a question about @kara comment that I have been meaning to post, Kara you are totally right that is is preloading the wrong one, but I am not following how I am going to figure out what one to preload.

We can get the sizes and srcsest as an @Input as you described (we are already reading srcset), but that doesn't tell me what one the user will be loading. I am assuming we don't want to prelaod every size (kinda defeats the purpose) so how should I determine what size that the user is going to be loading, wouldn't it depend on the screensize and what srcset gets matched? Am I misunderstanding the sizes attribute?

Let me know what I am missing here thanks you two!

@kara
Copy link
Contributor

kara commented Oct 3, 2022

@yharaskrik Oh, the whole point of imagesrcset and imagesizes is that you don't have to know which size is being loaded. The browser will determine that. imagesrcset should have the same value as srcset. imagesizes should have the same value as sizes. Just copy them over and the browser will preload the correct URL.

There's more context in the docs here:
https://web.dev/preload-responsive-images/#imagesrcset-and-imagesizes

@yharaskrik
Copy link
Contributor Author

@yharaskrik Oh, the whole point of imagesrcset and imagesizes is that you don't have to know which size is being loaded. The browser will determine that. imagesrcset should have the same value as srcset. imagesizes should have the same value as sizes. Just copy them over and the browser will preload the correct URL.

There's more context in the docs here: https://web.dev/preload-responsive-images/#imagesrcset-and-imagesizes

OH those attributes are on the <link> tag! 🤦 That is why I was so confused.

@yharaskrik yharaskrik force-pushed the jaybell/create-link-preload-tag-in-universal-for-priority-images branch from fce5fb8 to ea32daa Compare October 3, 2022 19:26
@yharaskrik yharaskrik requested review from AndrewKushnir and kara and removed request for pkozlowski-opensource and AndrewKushnir October 3, 2022 19:26
@angular-robot angular-robot bot added the feature Issue that requests a new feature label Oct 3, 2022
@AndrewKushnir
Copy link
Contributor

AndrewKushnir commented Oct 10, 2022

@yharaskrik the PR #47547 that adds sizes input as well has landed. Could you please rebase this PR (and resolve the merge conflicts), so that we can complete the final round of code reviews and proceed with further testing in Google's codebase? Thank you.

@yharaskrik yharaskrik force-pushed the jaybell/create-link-preload-tag-in-universal-for-priority-images branch from 8bf432e to b3576a8 Compare October 10, 2022 16:47
@yharaskrik
Copy link
Contributor Author

@yharaskrik the PR #47547 that adds sizes input as well has landed. Could you please rebase this PR (and resolve the merge conflicts), so that we can complete the final round of code reviews and proceed with further testing in Google's codebase? Thank you.

There ya go sir.

@yharaskrik yharaskrik force-pushed the jaybell/create-link-preload-tag-in-universal-for-priority-images branch from b3576a8 to d0edffd Compare October 10, 2022 17:07
@yharaskrik
Copy link
Contributor Author

yharaskrik commented Oct 10, 2022

There seems to be some seemingly unrelated test failures now and I cannot for the life of me track them down. It's like there are some leaks between tests as some tests are getting entirely different values than are configured on the <img> tag.

Image directive loaders `ngSrcset` values should set the `srcset` using the `ngSrcset` value with width descriptors FAILED
Expected 'http://localhost:9877/img.png?w=100 1x, http://localhost:9877/img.png?w=200 2x' to be 'http://localhost:9877/img.png?w=100 100w, http://localhost:9877/img.png?w=200 200w'.`

Whereas the <img> tag in this test is configured like so:

const template = `
           <img ngSrc="img.png" ngSrcset="100w, 200w" width="100" height="50">
         `;

whereas the next test down is configured like so

const template = `
           <img ngSrc="img.png" ngSrcset="1x, 2x" width="100" height="50">
         `;

Any help would be appreciated!

@AndrewKushnir
Copy link
Contributor

There seems to be some seemingly unrelated test failures now and I cannot for the life of me track them down. It's like there are some leaks between tests as some tests are getting entirely different values than are configured on the tag.

@yharaskrik thanks for highlighting this issue, I will look into this now and let you know.

yharaskrik and others added 2 commits October 10, 2022 11:35
This commit adds a logic that generates preload tags for priority images, when rendering happens on the server (e.g. Angular Universal).
@AndrewKushnir AndrewKushnir force-pushed the jaybell/create-link-preload-tag-in-universal-for-priority-images branch from d0edffd to 2969b99 Compare October 10, 2022 18:40
@AndrewKushnir
Copy link
Contributor

@yharaskrik it looks like there was an issue with the rebase and an extra condition that was added in the PR #47547 got inserted in a different place. I've added a fixup commit to resolve this: 2969b99

Copy link
Contributor

@atcastle atcastle left a comment

Choose a reason for hiding this comment

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

This looks good to me--I checked where the merge conflicts were resolved with the automatic srcset PR and it seems like it'll work fine.

});

const template =
`<img ngSrc="${src}" width="150" height="50" priority sizes="10vw" ngSrcset="100w">`;
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's also include a test with no ngSrcset to make sure that the link element is picking up the automatically-generated srcset

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok I'll try and get to that today

Copy link
Contributor

Choose a reason for hiding this comment

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

@yharaskrik let's address this feedback in a followup PR (adding changes to this PR would reset approvals).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👌

@AndrewKushnir
Copy link
Contributor

Presubmit #2 (internal link).

Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

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

Reviewed-for: public-api

@AndrewKushnir AndrewKushnir removed the action: presubmit The PR is in need of a google3 presubmit label Oct 10, 2022
@AndrewKushnir
Copy link
Contributor

@yharaskrik FYI, the current state of this PR is "ready for merge", I'm adding it to the merge queue. There is a feedback from @atcastle (see #47343 (comment)), which we can handle in a followup PR. Please do not push any additional changes for now (it'd reset all approvals). I will let you know once this PR is merged.

@AndrewKushnir AndrewKushnir added action: merge The PR is ready for merge by the caretaker merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note labels Oct 10, 2022
@ngbot
Copy link

ngbot bot commented Oct 10, 2022

I see that you just added the action: merge label, but the following checks are still failing:
    failure status "pullapprove" is failing
    pending 2 pending code reviews

If you want your PR to be merged, it has to pass all the CI checks.

If you can't get the PR to a green state due to flakes or broken main, please try rebasing to main and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help.

@AndrewKushnir
Copy link
Contributor

AndrewKushnir commented Oct 10, 2022

Merge-assistance (cc @jessicajaniuk): this PR is ready for merge. Pawel's feedback has been addressed, but since he is OOO, we can't change the status.

@yharaskrik
Copy link
Contributor Author

@yharaskrik FYI, the current state of this PR is "ready for merge", I'm adding it to the merge queue. There is a feedback from @atcastle (see #47343 (comment)), which we can handle in a followup PR. Please do not push any additional changes for now (it'd reset all approvals). I will let you know once this PR is merged.

Ok sounds good!

@jessicajaniuk jessicajaniuk dismissed pkozlowski-opensource’s stale review October 10, 2022 20:46

Feedback addressed and reviewer OOO

@jessicajaniuk jessicajaniuk removed the merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note label Oct 10, 2022
@jessicajaniuk
Copy link
Contributor

This PR was merged into the repository by commit 75e6297.

@AndrewKushnir
Copy link
Contributor

@yharaskrik just wanted to say thank you once again for all your work on this PR 👍
The PR is now merged and the change will be released as a part of the upcoming Angular v15.

@yharaskrik
Copy link
Contributor Author

@yharaskrik just wanted to say thank you once again for all your work on this PR 👍
The PR is now merged and the change will be released as a part of the upcoming Angular v15.

Thank you for all the help and guidance! Hope I can contribute again soon! I'd be curious what the future plans of the image directive is as I think that's a great step forward! (I'm in the angular slack as well)

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: common Issues related to APIs in the @angular/common package common: image directive feature Issue that requests a new feature target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants