Skip to content

⚡ Optimize SpeakerCard image usage#13

Merged
anyulled merged 3 commits intomainfrom
perf/optimize-speaker-card-image-6686497524791601587
Feb 2, 2026
Merged

⚡ Optimize SpeakerCard image usage#13
anyulled merged 3 commits intomainfrom
perf/optimize-speaker-card-image-6686497524791601587

Conversation

@anyulled
Copy link
Copy Markdown
Owner

@anyulled anyulled commented Feb 1, 2026

💡 What: Replaced the standard <img> tag with the Next.js <Image> component in components/layout/SpeakerCard.tsx.
🎯 Why: To improve performance by leveraging Next.js built-in image optimizations (lazy loading, resizing, format conversion).
📊 Measured Improvement:

  • Baseline: Verified original <img> tag rendered correctly.
  • Optimization: Implemented next/image with fill and sizes to ensure responsive loading.
  • Verification: Verified using Playwright that the image is visible and has the correct attributes. Ensuring aspectRatio: "1/1" prevents layout shifts and proper sizing.

PR created automatically by Jules for task 6686497524791601587 started by @anyulled

Summary by CodeRabbit

  • New Features

    • Speaker card images now render with enhanced performance and responsive sizing, automatically adapting to different screen sizes and devices for an improved viewing experience.
  • Tests

    • Added comprehensive test coverage for speaker card image rendering, validating proper implementation of alt text, responsive sizing attributes, and styling application.

@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
devbcn Ready Ready Preview, Comment Feb 2, 2026 3:26pm

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Feb 1, 2026

📝 Walkthrough

Walkthrough

The SpeakerCard component is migrated to use Next.js Image component for optimized image rendering, accompanied by responsive container styling and updated test coverage validating proper image attributes and positioning behavior.

Changes

Cohort / File(s) Summary
Image Component Migration
components/layout/SpeakerCard.tsx
Replaced static img element with Next.js Image component, added speaker-image-container and speaker-image-link class names, configured responsive sizing with fill and sizes attributes.
Test Coverage Update
__tests__/components/SpeakerCard.test.tsx
Updated import path to use path alias, changed image URL from local path to external URL, added comprehensive test case validating Image component rendering with correct alt text, src decoding, responsive attributes, and absolute positioning styling.
Responsive Styling
styles/layout/pages/_team.scss
Added new .speaker-image-container (1:1 aspect ratio) and .speaker-image-link (full-bleed, block-level relative positioning) CSS classes for speaker image layout structure.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Hop along! Images now optimized and keen,
Next.js renders the finest we've seen,
Responsive containers dance, clean and pristine,
SpeakerCards glow in this modernized sheen! ✨🖼️

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: replacing img with Next.js Image component in SpeakerCard for image optimization, which is the primary modification across all three files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch perf/optimize-speaker-card-image-6686497524791601587

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello @anyulled, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on enhancing the performance of the application by optimizing how speaker images are loaded. By migrating from native <img> tags to the Next.js <Image> component, the application will benefit from automatic image optimizations, leading to faster page loads, reduced bandwidth usage, and a smoother user experience, particularly on various device sizes.

Highlights

  • Image Optimization: Replaced the standard <img> tag with the Next.js <Image> component in components/layout/SpeakerCard.tsx to leverage built-in optimizations such as lazy loading, resizing, and format conversion for improved performance.
  • New Test File: Added a new test file __tests__/components/SpeakerCard.test.tsx to verify the correct rendering and attributes of the next/image component within the SpeakerCard, ensuring its functionality and responsiveness.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively optimizes image loading in the SpeakerCard component by leveraging the Next.js <Image> component. The change is well-justified for performance, and the addition of a corresponding test file to verify the new implementation is a great practice. I have one suggestion regarding the use of inline styles to improve code maintainability.

Comment thread components/layout/SpeakerCard.tsx Outdated
@anyulled
Copy link
Copy Markdown
Owner Author

anyulled commented Feb 1, 2026

To improve maintainability and follow the separation of concerns principle, it's recommended to move these inline styles into dedicated CSS classes within your stylesheet. This makes the styles more reusable and easier to manage over time.

You could define classes like this in your SCSS file:

.image-container {
aspect-ratio: 1/1;
}

.image-link {
display: block;
width: 100%;
height: 100%;
position: relative;
}
Suggested change
<div className="img1" style={{ aspectRatio: "1/1" }}>
<Link href={/${year}/speakers/${speakerId}} style={{ display: "block", width: "100%", height: "100%", position: "relative" }}>


<Link href={/${year}/speakers/${speakerId}} className="image-link">

@google-labs-jules
Copy link
Copy Markdown
Contributor

To improve maintainability and follow the separation of concerns principle, it's recommended to move these inline styles into dedicated CSS classes within your stylesheet. This makes the styles more reusable and easier to manage over time.

You could define classes like this in your SCSS file:

.image-container {
aspect-ratio: 1/1;
}

.image-link {
display: block;
width: 100%;
height: 100%;
position: relative;
}
Suggested change
<div className="img1" style={{ aspectRatio: "1/1" }}>
<Link href={/${year}/speakers/${speakerId}} style={{ display: "block", width: "100%", height: "100%", position: "relative" }}>


<Link href={/${year}/speakers/${speakerId}} className="image-link">

Thank you for the suggestion. I've moved the inline styles to public/assets/scss/layout/pages/_team.scss using the classes .speaker-image-container and .speaker-image-link to improve maintainability.

@anyulled
Copy link
Copy Markdown
Owner Author

anyulled commented Feb 1, 2026

This branch has conflicts that must be resolved
Use the command line to resolve conflicts before continuing.

@google-labs-jules
Copy link
Copy Markdown
Contributor

This branch has conflicts that must be resolved
Use the command line to resolve conflicts before continuing.

Merged origin/main and resolved conflicts in __tests__/components/SpeakerCard.test.tsx by combining tests from both branches. Also verified that styles were correctly applied to the renamed styles/layout/pages/_team.scss file.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@next-env.d.ts`:
- Line 3: Remove the hard-coded dev-only import line (import
"./.next/dev/types/routes.d.ts";) from next-env.d.ts and instead rely on
tsconfig.json includes to cover both build outputs; add both ".next/types/**"
and ".next/dev/types/**" to the "include" array in tsconfig so TypeScript picks
up production and dev-only route types without importing a path that doesn't
exist in CI/production.
🧹 Nitpick comments (5)
__tests__/components/schedule/ScheduleGrid.perf.test.tsx (1)

71-88: Test name is misleading — this is a smoke test, not a performance test.

The test is labeled "ScheduleGrid Performance" but doesn't measure any performance metrics (render time, memory, re-render counts). It's actually a smoke test verifying the component renders and handles state updates without crashing.

Consider renaming to ScheduleGrid.smoke.test.tsx or ScheduleGrid.test.tsx, or add actual performance assertions (e.g., using React.Profiler or measuring render duration).

components/schedule/ScheduleGrid.tsx (1)

119-123: Clarify the 15-minute vs 30-minute slot discrepancy in comments.

The slotDuration is 30 minutes (line 51), but session positioning divides by 15 (lines 122-123). This works because gridTemplateRows doubles totalRows (line 86), effectively creating 15-minute precision.

Consider adding a brief comment to explain this intentional design:

📝 Suggested clarification
+              // Note: rowStart/rowSpan use 15-minute granularity (totalRows is doubled in gridTemplateRows)
               const rowStart = Math.floor(offset / 15) + 2; // +2 for header
               const rowSpan = Math.ceil(duration / 15);
hooks/useTalks.ts (2)

24-27: Inconsistent default parameter between getTalks and getAllTalks.

getTalks has a default parameter year = "default" (line 14), but getAllTalks requires an explicit year argument. This inconsistency could lead to confusion or runtime errors if callers expect the same defaulting behavior.

♻️ Suggested fix for consistency
-export const getAllTalks = cache(async (year: string | number): Promise<Talk[]> => {
+export const getAllTalks = cache(async (year: string | number = "default"): Promise<Talk[]> => {

29-32: getTalksMap is internal but not marked as such.

Consider adding an underscore prefix or a JSDoc comment to indicate this is an internal helper not intended for external use, since only getTalkByYearAndId calls it.

📝 Suggested documentation
+/**
+ * Internal cached helper - builds a Map for O(1) talk lookups
+ */
 const getTalksMap = cache(async (year: string | number): Promise<Map<string, Talk>> => {
__tests__/components/SpeakerCard.test.tsx (1)

42-54: Consider avoiding Next/Image inline-style assertions (brittle across mocks/versions).

The toHaveStyle checks can fail if next/image is mocked (common in Jest) or if Next changes internal styling. You already validate sizes and class; that’s typically sufficient.

♻️ Suggested adjustment
-    // fill={true} applies absolute position
-    expect(img).toHaveStyle({
-      position: "absolute",
-      height: "100%",
-      width: "100%",
-      left: "0",
-      top: "0",
-      right: "0",
-      bottom: "0",
-    });

Comment thread next-env.d.ts Outdated
@anyulled
Copy link
Copy Markdown
Owner Author

anyulled commented Feb 1, 2026

This branch has conflicts that must be resolved
Use the command line to resolve conflicts before continuing.

@google-labs-jules
Copy link
Copy Markdown
Contributor

This branch has conflicts that must be resolved
Use the command line to resolve conflicts before continuing.

I have verified that the branch is up-to-date with origin/main and all conflicts have been resolved locally. The tests are passing. I'm pushing the resolved state again to ensure the PR is updated.

google-labs-jules Bot and others added 3 commits February 2, 2026 16:21
Co-authored-by: anyulled <100741+anyulled@users.noreply.github.com>
Co-authored-by: anyulled <100741+anyulled@users.noreply.github.com>
Co-authored-by: anyulled <100741+anyulled@users.noreply.github.com>
@anyulled anyulled force-pushed the perf/optimize-speaker-card-image-6686497524791601587 branch from 90cbefb to 34dbe0f Compare February 2, 2026 15:23
@anyulled anyulled merged commit 5f73261 into main Feb 2, 2026
4 checks passed
@anyulled anyulled deleted the perf/optimize-speaker-card-image-6686497524791601587 branch February 2, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant