-
Notifications
You must be signed in to change notification settings - Fork 84
feat: lcp-logo-eager-loading #3377
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
base: dev
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import { faststoreLoader } from './loader' | ||
|
|
||
| export interface CriticalProductImagePreload { | ||
| rel: 'preload' | ||
| as: 'image' | ||
| href: string | ||
| fetchPriority: 'high' | ||
| } | ||
|
|
||
| export function getCriticalProductImagePreload( | ||
| imageUrl?: string | ||
| ): CriticalProductImagePreload | null { | ||
| if (!imageUrl) { | ||
| return null | ||
| } | ||
|
|
||
| return { | ||
| rel: 'preload', | ||
| as: 'image', | ||
| href: faststoreLoader({ | ||
| src: imageUrl, | ||
| width: 320, | ||
| quality: 75, | ||
| }), | ||
| fetchPriority: 'high', | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,6 +1,6 @@ | ||||||
| import { useEffect, useState } from 'react' | ||||||
|
|
||||||
| const TTI_TIMEOUT = 5000 // 5 seconds without long tasks as a criterion for Time To Interactive - https://web.dev/articles/tti | ||||||
| const TTI_TIMEOUT = 1000 // 5 seconds without long tasks as a criterion for Time To Interactive - https://web.dev/articles/tti | ||||||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unrelated This isn't mentioned in the PR summary/deviations and doesn't relate to logo/LCP preload. Two issues:
Was this committed by accident? If intentional, split it into its own PR with a rationale (and fix the comment); otherwise revert:
Suggested change
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pelo que lembro os 5 segundos sao intencionais. 1 segundo tem risco de long task ainda serem carregadas apos esse periodo. |
||||||
|
|
||||||
| /** | ||||||
| * Polyfill for requestIdleCallback, which is not available for every browser | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import { render } from '@testing-library/react' | ||
|
|
||
| import Logo from 'src/components/ui/Logo/Logo' | ||
|
|
||
| const imageSpy = vi.fn() | ||
|
|
||
| vi.mock('src/components/ui/Image', () => ({ | ||
| Image: (props: Record<string, unknown>) => { | ||
| imageSpy(props) | ||
| return <div data-testid="logo-image" /> | ||
| }, | ||
| })) | ||
|
|
||
| describe('Logo', () => { | ||
| beforeEach(() => { | ||
| imageSpy.mockClear() | ||
| }) | ||
|
|
||
| it('uses lazy loading by default', () => { | ||
| render(<Logo alt="FastStore" src="/logo.svg" />) | ||
|
|
||
| expect(imageSpy).toHaveBeenCalledTimes(1) | ||
| expect(imageSpy).toHaveBeenCalledWith( | ||
| expect.objectContaining({ | ||
| loading: 'lazy', | ||
| }) | ||
| ) | ||
| }) | ||
|
|
||
| it('keeps explicit loading overrides', () => { | ||
| render(<Logo alt="FastStore" src="/logo.svg" loading="eager" />) | ||
|
|
||
| expect(imageSpy).toHaveBeenCalledTimes(1) | ||
| expect(imageSpy).toHaveBeenCalledWith( | ||
| expect.objectContaining({ | ||
| loading: 'eager', | ||
| }) | ||
| ) | ||
| }) | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| import { getCriticalProductImagePreload } from 'src/components/ui/Image/getCriticalProductImagePreload' | ||
|
|
||
| describe('getCriticalProductImagePreload', () => { | ||
| it('returns null when no image URL is provided', () => { | ||
| expect(getCriticalProductImagePreload()).toBeNull() | ||
| }) | ||
|
|
||
| it('builds preload metadata for a valid image URL', () => { | ||
| expect(getCriticalProductImagePreload('/product-image.jpg')).toEqual({ | ||
| rel: 'preload', | ||
| as: 'image', | ||
| href: '/product-image.jpg', | ||
| fetchPriority: 'high', | ||
| }) | ||
| }) | ||
|
|
||
| it('transforms VTEX IDs image URLs using the expected preload sizing', () => { | ||
| expect( | ||
| getCriticalProductImagePreload( | ||
| '/ids/1557582/image-6.jpg?v=638808503053270000' | ||
| ) | ||
| ).toEqual({ | ||
| rel: 'preload', | ||
| as: 'image', | ||
| href: '/ids/1557582-320-auto/image-6.webp?v=638808503053270000&quality=8', | ||
| fetchPriority: 'high', | ||
| }) | ||
| }) | ||
| }) |
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.
Update the stale comment.
The comment still says "5 seconds" but the constant is now 1000ms (1 second). This misleads readers about the actual TTI detection threshold.
📝 Proposed fix
📝 Committable suggestion
🤖 Prompt for AI Agents
🧩 Analysis chain
🌐 Web query:
What is the recommended quiet window duration for Time to Interactive (TTI) measurement according to web.dev and web performance standards?💡 Result:
According to web.dev and associated web performance documentation, the recommended quiet window duration for measuring Time to Interactive (TTI) is at least five seconds [1][2]. A quiet window is defined as a period of time during which there are no long tasks (tasks exceeding 50 milliseconds) and no more than two in-flight network GET requests [1][3]. It is important to note that TTI has been deprecated in modern performance auditing tools like Lighthouse (removed as of version 10) due to its high variability and sensitivity to outlier network requests and long tasks [1][4]. Official guidance now recommends using metrics such as Interaction to Next Paint (INP), Total Blocking Time (TBT), and Largest Contentful Paint (LCP) as more reliable indicators of page performance and responsiveness [1][4].
Citations:
🏁 Script executed:
Repository: vtex/faststore
Length of output: 2387
Fix
TTI_TIMEOUTinpackages/core/src/sdk/performance/useTTI.tsto match TTI quiet-window guidanceuseTTIsetsTTI_TIMEOUT = 1000(1s) as the quiet period since the last long task, but the inline comment says “5 seconds”, and web.dev’s TTI guidance uses an at-least-5s quiet window (plus constraints like limited in-flight GETs).TTI_TIMEOUT(likely to5000) and the comment, or clearly document why a 1s threshold is intentional and how the approximation (long tasks only) fits your use case.🤖 Prompt for AI Agents