Skip to content

Conversation

@gocanto
Copy link
Contributor

@gocanto gocanto commented Sep 30, 2025

Summary

  • wrap article thumbnail images with a skeleton placeholder that keeps layout consistent while loading
  • fade thumbnails in once loaded and show a fallback icon when the request fails
  • switch thumbnails to lazy loading to reduce initial network pressure

Testing

  • npm run build (fails: vite not found because dependencies are unavailable in the environment)

https://chatgpt.com/codex/tasks/task_e_68db8947b48483339f39cf89d8b1b735

Summary by CodeRabbit

  • New Features
    • Article cards show a loading skeleton for cover images, are lazy-loaded, and fade in for smoother visuals.
    • Image loading and error states are tracked and reset automatically when an article’s image source changes.
  • Bug Fixes
    • A fallback placeholder displays if an image fails to load, replacing broken image icons and preventing layout glitches.

@coderabbitai
Copy link

coderabbitai bot commented Sep 30, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Refactors ArticleItemPartial.vue to replace an inline with a skeleton-capable, lazy-loading wrapper that tracks image status (loading/loaded/error). Adds reactive ImageStatus state, load/error handlers, computed flags, and a watcher on props.item.cover_image_url to reset state and control conditional rendering.

Changes

Cohort / File(s) Summary
Article image loading & error states
src/partials/ArticleItemPartial.vue
Replaced inline <img> with a wrapper managing image status (loading, loaded, error). Introduced const props = defineProps<...>(), ImageStatus reactive state, handleImageLoad/handleImageError handlers, computed flags (isImageError, isImageLoaded, showSkeleton), and an immediate watcher on props.item.cover_image_url to reset state. Template now conditionally renders a skeleton, an error SVG overlay, and a lazy-loaded image with opacity/visibility transitions.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    actor User
    participant ArticleItem as ArticleItemPartial.vue
    participant Img as <img>
    participant UI as Skeleton / Error UI

    User->>ArticleItem: render item
    ArticleItem->>ArticleItem: watch(props.item.cover_image_url) (immediate)\nset imageStatus = loading
    ArticleItem->>UI: show skeleton (showSkeleton = true)
    ArticleItem->>Img: render <img loading="lazy"> (hidden/transparent)

    alt Image loads
      Img-->>ArticleItem: load event
      ArticleItem->>ArticleItem: imageStatus = loaded
      ArticleItem->>UI: hide skeleton
      ArticleItem->>Img: reveal image (opacity transition)
    else Image fails
      Img-->>ArticleItem: error event
      ArticleItem->>ArticleItem: imageStatus = error
      ArticleItem->>UI: show error SVG overlay
      ArticleItem->>Img: remain hidden
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Poem

I nibbled pixels in the twilight code,
A skeleton glow while fetches strode.
If bytes refuse, an SVG will stay,
Then vanish soft when the image plays.
Hop—thumbnail ready, off I go! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the primary change by stating the addition of a skeleton placeholder for article thumbnails, which aligns directly with the pull request’s focus on enhancing image loading with a visual placeholder and does so in clear, concise language.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/improve-image-loading-performance

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
🧪 Early access (Sonnet 4.5): enabled

We are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience.

Note:

  • Public repositories are always opted into early access features.
  • You can enable or disable early access features from the CodeRabbit UI or by updating the CodeRabbit configuration file.

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

@gemini-code-assist
Copy link

Summary of Changes

Hello @gocanto, 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 significantly enhances the user experience and performance related to article thumbnail images. By introducing skeleton loading, users will see a consistent layout while images are fetched. It also gracefully handles image loading failures with a clear fallback icon and optimizes resource usage through lazy loading, ensuring a smoother and more efficient browsing experience.

Highlights

  • Skeleton Placeholder: Implemented a skeleton placeholder for article thumbnail images to maintain layout consistency while images are loading.
  • Image Loading Feedback: Added a fade-in effect for thumbnails once they have successfully loaded, enhancing the user experience.
  • Error Handling: Introduced a fallback icon that displays when an article thumbnail image fails to load, preventing broken image icons.
  • Performance Optimization: Switched article thumbnail images to lazy loading, reducing initial network pressure and improving page load performance.
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

@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 introduces a skeleton loader for article thumbnails, which is a great enhancement for user experience. The implementation correctly handles loading, success, and error states, and adds lazy loading to improve initial page load performance. My review includes a few suggestions to improve code clarity and maintainability, such as simplifying a complex class binding, using a more intuitive icon for errors, and making the state management logic easier to understand.

Copy link

@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: 0

🧹 Nitpick comments (1)
src/partials/ArticleItemPartial.vue (1)

21-33: Consider a more appropriate error icon and add accessibility attributes.

The magnifying glass icon (search/zoom icon) doesn't clearly communicate an image loading failure. Consider using a broken image icon, exclamation mark, or photo placeholder icon instead.

Additionally, the error SVG lacks accessibility attributes. Add aria-label or role="img" with aria-label to describe the error state for screen reader users.

Apply this diff to use a broken image icon and add accessibility:

                                <svg
                                        v-if="imageError"
                                        class="w-6 h-6 text-slate-400 dark:text-slate-600"
                                        xmlns="http://www.w3.org/2000/svg"
                                        fill="none"
                                        viewBox="0 0 24 24"
                                        stroke-width="1.5"
                                        stroke="currentColor"
+                                       role="img"
+                                       aria-label="Image failed to load"
                                >
-                                       <path stroke-linecap="round" stroke-linejoin="round" d="M21 21l-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z" />
+                                       <path stroke-linecap="round" stroke-linejoin="round" d="m2.25 15.75 5.159-5.159a2.25 2.25 0 0 1 3.182 0l5.159 5.159m-1.5-1.5 1.409-1.409a2.25 2.25 0 0 1 3.182 0l2.909 2.909m-18 3.75h16.5a1.5 1.5 0 0 0 1.5-1.5V6a1.5 1.5 0 0 0-1.5-1.5H3.75A1.5 1.5 0 0 0 2.25 6v12a1.5 1.5 0 0 0 1.5 1.5Zm10.5-11.25h.008v.008h-.008V8.25Zm.375 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Z" />
                                </svg>

This uses the Heroicons "photo" icon which better represents an image placeholder.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 081321f and bea18cb.

📒 Files selected for processing (1)
  • src/partials/ArticleItemPartial.vue (2 hunks)
🔇 Additional comments (6)
src/partials/ArticleItemPartial.vue (6)

69-69: LGTM!

The Vue composition API imports are appropriate for the reactive state management implemented in this component.


73-75: LGTM!

Assigning defineProps to a const is the correct approach for accessing props in the composition API, particularly needed for the watcher on props.item.cover_image_url.


77-78: LGTM!

The reactive refs are initialized correctly with false values, representing the initial loading state before the image starts loading.


80-87: LGTM!

The event handlers correctly manage loading states. Setting imageLoaded to true in the error handler is appropriate as it stops the loading animation and switches to the error display.


89-89: LGTM!

The computed property correctly evaluates to true during loading (!imageLoaded) and error states (imageError), controlling skeleton and error icon visibility appropriately.


91-104: LGTM!

The watcher correctly resets loading states when the image URL changes and handles missing URLs by treating them as error states. The immediate: true option ensures proper initialization on mount, and optional chaining safely handles cases where item might be undefined.

@gocanto gocanto marked this pull request as draft September 30, 2025 07:53
@gocanto gocanto marked this pull request as ready for review September 30, 2025 07:57
@gocanto gocanto merged commit edd161b into main Sep 30, 2025
2 checks passed
@gocanto gocanto deleted the codex/improve-image-loading-performance branch September 30, 2025 08:01
Copy link

@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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/partials/ArticleItemPartial.vue (1)

1-120: Fix formatting to satisfy CI checks.

The CI failure indicates uncommitted formatting changes. Apply Prettier and commit the results:

npx prettier --write .
git add .
git commit -m "chore: format code to satisfy CI"

Optionally, add a "format": "prettier --write ." script to package.json for future consistency.

🧹 Nitpick comments (1)
src/partials/ArticleItemPartial.vue (1)

6-6: Simplify the ternary expression for better readability.

The nested ternary can be simplified since both branches when isImageError is true or showSkeleton is false result in 'animate-none'.

Apply this diff:

-                               :class="isImageError ? 'animate-none' : showSkeleton ? 'animate-pulse' : 'animate-none'"
+                               :class="showSkeleton && !isImageError ? 'animate-pulse' : 'animate-none'"

Based on past review comments.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5050e02 and a01854f.

📒 Files selected for processing (1)
  • src/partials/ArticleItemPartial.vue (2 hunks)
🧰 Additional context used
🪛 GitHub Actions: Test Format Workflow
src/partials/ArticleItemPartial.vue

[error] 1-1: Command 'git diff --exit-code' failed with exit code 1. Uncommitted changes detected in src/partials/ArticleItemPartial.vue.

🔇 Additional comments (3)
src/partials/ArticleItemPartial.vue (3)

8-48: LGTM! Clean implementation of skeleton loading with error handling.

The conditional rendering and state transitions work correctly:

  • Image is hidden with opacity-0 while loading and fades in when loaded
  • On error, the image is removed and replaced with an appropriate broken-image icon
  • The skeleton overlay serves both as a loading indicator and error state container

92-102: LGTM! Past review feedback has been successfully addressed.

The ImageStatus type and handlers implement exactly what was suggested in the previous review. This makes the state transitions much clearer and easier to reason about compared to the previous boolean approach.


108-119: LGTM! Watcher correctly handles URL changes and missing images.

The watcher properly:

  • Resets state to 'loading' when the image URL changes
  • Sets state to 'error' immediately if the URL is missing
  • Runs on mount with immediate: true to handle initial state

The image element's @load and @error handlers will fire appropriately when the browser completes the request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants