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 placeholder to NgOptimizedImage #53783

Closed
wants to merge 1 commit into from

Conversation

atcastle
Copy link
Contributor

@atcastle atcastle commented Jan 3, 2024

This PR adds a new automatic placeholders feature to NgOptimizedImage. This feature takes a small placeholder image, generated with an image loader, or provided by the developer in the form of a data URL, and applies it as a background-image with a blur while the primary image is being downloaded. The placeholder styling is removed when loading is complete.

CC: @AndrewKushnir @kara

@angular-robot angular-robot bot added the detected: feature PR contains a feature commit label Jan 3, 2024
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.

@atcastle looks great, just left a few minor comments.

adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
packages/common/test/directives/ng_optimized_image_spec.ts Outdated Show resolved Hide resolved
packages/common/test/directives/ng_optimized_image_spec.ts Outdated Show resolved Hide resolved
packages/common/test/directives/ng_optimized_image_spec.ts Outdated Show resolved Hide resolved
packages/common/src/errors.ts Outdated Show resolved Hide resolved
packages/common/test/directives/ng_optimized_image_spec.ts Outdated Show resolved Hide resolved
@AndrewKushnir AndrewKushnir added action: review The PR is still awaiting reviews from at least one requested reviewer target: minor This PR is targeted for the next minor release labels Jan 3, 2024
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.

Overall, looks good, with some minor changes requested to docs/comments/tests.

One meta-note: this PR could have been split up into 3 PRs: one for basic setup, one for additional configs (e.g. placeholderConfig, resolution), and one for warnings/errors. This makes it a lot easier to review :)

adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
aio/content/guide/image-directive.md Outdated Show resolved Hide resolved
adev/src/content/guide/image-optimization.md Show resolved Hide resolved
* attribute.
*/
export const DATA_URL_WARN_LIMIT = 2000;
export const DATA_URL_ERROR_LIMIT = 5000;
Copy link
Contributor

Choose a reason for hiding this comment

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

Where are these limit numbers coming from?

Copy link
Member

Choose a reason for hiding this comment

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

+1, it would be good to have any links to reference material or an explanation of how they were determined via experiment, trial-and-error, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed. My heuristic for choosing them was to convert some very small images to base64 and see what the smallest reasonable character count is. I'll share some example sizes for different sized source images.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 sharing a few example sizes would help give context

packages/common/test/directives/ng_optimized_image_spec.ts Outdated Show resolved Hide resolved
adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
adev/src/content/guide/image-optimization.md Outdated Show resolved Hide resolved
aio/content/guide/image-directive.md Outdated Show resolved Hide resolved
* Configuration object for placeholder settings. Options:
* blur: Setting this to false disables the automatic CSS blur.
*/
@Input() placeholderConfig?: {blur: boolean} = {blur: true};
Copy link
Member

Choose a reason for hiding this comment

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

What's the thinking behind having one placeholderConfig vs. separate inputs? I typically see the latter in Angular apps since specifying objects with multiple properties in the config can get clunky

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@kara @AndrewKushnir and I had some discussions about this while designing the placeholder feature, and decided that it's quite likely that we'll have additional configuration parameters in the future, assuming we add additional functionality to placeholders. So just starting with a config object seemed wise at it will allow us to keep things backwards compatible.

} else if (typeof placeholderInput === 'string' && placeholderInput.startsWith('data:')) {
return `url(${placeholderInput})`;
}
return null;
Copy link
Member

Choose a reason for hiding this comment

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

Would it make sense to add a developer-mode-only check that throws an error if typeof placeholderInput === 'string' and it doesn't start with "data:"?

@atcastle atcastle force-pushed the img-placeholder branch 5 times, most recently from d467c00 to b38c161 Compare January 11, 2024 21:47
@dylhunn dylhunn added area: common Issues related to APIs in the @angular/common package common: image directive labels Jan 17, 2024
@ngbot ngbot bot modified the milestone: Backlog Jan 17, 2024
@atcastle atcastle force-pushed the img-placeholder branch 2 times, most recently from 7b7690e to b5fdfca Compare January 17, 2024 21:01
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.

Two tiny nits, otherwise LGTM

@@ -337,6 +366,9 @@ export class NgOptimizedImage implements OnInit, OnChanges, OnDestroy {
if (!this.ngSrcset) {
assertNoComplexSizes(this);
}
assertNoPlaceholderConfigWithoutPlaceholder(this);
Copy link
Contributor

Choose a reason for hiding this comment

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

@atcastle Friendly ping

* attribute.
*/
export const DATA_URL_WARN_LIMIT = 2000;
export const DATA_URL_ERROR_LIMIT = 5000;
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 sharing a few example sizes would help give context

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

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.

@atcastle Looking at the public API again, I think we should rename PlaceholderConfig -> ImagePlaceholderConfig to be more specific and avoid potential confusion with @placeholder feature of @defer blocks.

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

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.

LGTM

@atcastle atcastle force-pushed the img-placeholder branch 2 times, most recently from 8b54803 to ee34a28 Compare January 24, 2024 20:03
Add a automatic placeholder implementation supporting loader-based and data URL placeholders
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
Copy link
Contributor

Presubmit.

@AndrewKushnir AndrewKushnir added action: presubmit The PR is in need of a google3 presubmit 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 and removed action: review The PR is still awaiting reviews from at least one requested reviewer action: presubmit The PR is in need of a google3 presubmit labels Jan 26, 2024
@AndrewKushnir
Copy link
Contributor

Caretaker note (cc @jessicajaniuk): this PR was reviewed, but 1 public-api approval is missing. Could you please review it as well when you get a chance? If everything looks good from the public-api perspective, this PR would be ready for merge.

(the presubmit is "green" as well, failing targets are unrelated/flaky)

@jessicajaniuk jessicajaniuk added adev: preview area: adev Angular.dev documentation labels Jan 29, 2024
Copy link
Contributor

@jessicajaniuk jessicajaniuk 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, angular-dev

Copy link

Deployed adev-preview for f10e916 to: https://ng-dev-previews-fw--pr-angular-angular-53783-adev-prev-tr959tfk.web.app

Note: As new commits are pushed to this pull request, this link is updated after the preview is rebuilt.

@jessicajaniuk
Copy link
Contributor

This PR was merged into the repository by commit f5c520b.

nikvarma pushed a commit to nikvarma/angular that referenced this pull request Jan 31, 2024
Add a automatic placeholder implementation supporting loader-based and data URL placeholders

PR Close angular#53783
@bjornharvold
Copy link

Great feature! Is this feature documented somewhere here?

https://angular.dev/guide/image-optimization/

@AndrewKushnir
Copy link
Contributor

@bjornharvold you can find more info about this feature at: https://angular.dev/guide/image-optimization#using-placeholders (note: the content was not there until angular.dev deploy today).

@bjornharvold
Copy link

Cheers Andrew!

@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 Mar 18, 2024
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 adev: preview area: adev Angular.dev documentation area: common Issues related to APIs in the @angular/common package common: image directive detected: feature PR contains a feature commit merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note target: minor This PR is targeted for the next minor release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants