-
Notifications
You must be signed in to change notification settings - Fork 26k
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
Conversation
There was a problem hiding this 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.
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this 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 :)
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
* attribute. | ||
*/ | ||
export const DATA_URL_WARN_LIMIT = 2000; | ||
export const DATA_URL_ERROR_LIMIT = 5000; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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/src/directives/ng_optimized_image/ng_optimized_image.ts
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}; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
} else if (typeof placeholderInput === 'string' && placeholderInput.startsWith('data:')) { | ||
return `url(${placeholderInput})`; | ||
} | ||
return null; |
There was a problem hiding this comment.
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:"
?
d467c00
to
b38c161
Compare
b38c161
to
2dff8a3
Compare
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
7b7690e
to
b5fdfca
Compare
There was a problem hiding this 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); |
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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
There was a problem hiding this 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
There was a problem hiding this 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.
packages/common/src/directives/ng_optimized_image/ng_optimized_image.ts
Outdated
Show resolved
Hide resolved
b5fdfca
to
a147770
Compare
There was a problem hiding this 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
a147770
to
80bf9f5
Compare
80bf9f5
to
9ec94a6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
8b54803
to
ee34a28
Compare
Add a automatic placeholder implementation supporting loader-based and data URL placeholders
ee34a28
to
f10e916
Compare
There was a problem hiding this 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
Caretaker note (cc @jessicajaniuk): this PR was reviewed, but 1 (the presubmit is "green" as well, failing targets are unrelated/flaky) |
There was a problem hiding this 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
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. |
This PR was merged into the repository by commit f5c520b. |
Add a automatic placeholder implementation supporting loader-based and data URL placeholders PR Close angular#53783
Great feature! Is this feature documented somewhere here? |
@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). |
Cheers Andrew! |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
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