Vue Progressive Image Loading
The `vue-progressive-image` package provides a plugin for Vue 3 applications, enabling efficient progressive image loading and lazy loading. This approach enhances perceived performance by displaying a low-resolution placeholder that smoothly transitions to the full-resolution image once it has completely loaded. The current stable version, 5.0.6, released in October 2025, indicates active development and maintenance with regular bug fixes. Key differentiators include its deep integration with Vue 3's component and plugin architecture, comprehensive TypeScript support since v5.0.0, and a straightforward API for managing image loading states. The library requires Vue `^3.5.13` as a peer dependency, ensuring compatibility with modern Vue applications and tooling. It focuses on delivering a robust, performant solution for image optimization without complex configuration.
Common errors
-
__dirname is not defined in ES module scope
cause This error occurs because `vue-progressive-image` versions 5.x and above are ESM-only, and `__dirname` is a CommonJS global variable not available in ES module contexts by default.fixEnsure your project's build configuration (e.g., `vite.config.ts`, `webpack.config.js`) is correctly set up for ES Modules. If you're building for Node.js environments and need `__dirname`, you might need to use `import.meta.url` with `fileURLToPath` and `dirname` from the `path` module for an equivalent path. -
[Vue warn]: Failed to resolve component: ProgressiveImage
cause This warning typically appears when the `ProgressiveImage` component is used in a template but has not been properly registered, either globally via `app.use()` or locally in the component where it's being used.fixVerify that `app.use(ProgressiveImage)` is called in your main application entry file (e.g., `main.ts`). If you intend to register it locally, ensure you are importing `{ ProgressiveImage }` (if exported) and adding it to your component's `components` option or importing directly in a `<script setup>` block.
Warnings
- breaking Version 5.0.0 introduced significant breaking changes, including migration to TypeScript, a switch from ESLint/Prettier to Biome, and an update to be ESM-only. Applications using previous major versions (v3.x) will require refactoring for type compatibility and module resolution.
- breaking The peer dependency for Vue has been updated to `^3.5.13`. Versions 5.x are not compatible with Vue 2.x projects. Attempting to use `vue-progressive-image` v5.x with Vue 2 will result in runtime errors.
- gotcha The package transitioned to ESM-only in version 5.0.0. This means CommonJS `require()` statements will fail, and certain Node.js global variables like `__dirname` are not available in the ES module scope, which has caused build issues (e.g., in v5.0.5).
- gotcha While the plugin aims to handle image attributes, a bug in v5.0.3 resulted in placeholder images missing their `alt` tags. Although fixed, always verify accessibility attributes for SEO and user experience.
Install
-
npm install vue-progressive-image -
yarn add vue-progressive-image -
pnpm add vue-progressive-image
Imports
- ProgressiveImage
const ProgressiveImage = require('vue-progressive-image');import ProgressiveImage from 'vue-progressive-image';
- ProgressiveImage
import { ProgressiveImage } from 'vue-progressive-image/components'; - ProgressiveImageOptions
import type { ProgressiveImageOptions } from 'vue-progressive-image';
Quickstart
import { createApp } from 'vue';
import App from './App.vue';
import ProgressiveImage from 'vue-progressive-image';
import 'vue-progressive-image/dist/style.css'; // Import base styles if provided by the library
const app = createApp(App);
// Register the plugin globally with optional default configurations
app.use(ProgressiveImage, {
delay: 300, // Time in ms before the high-res image starts loading after intersection
threshold: 0.2 // Intersection Observer threshold
});
app.mount('#app');
// --- App.vue ---
// <template>
// <div>
// <h1>Product Gallery</h1>
// <div style="height: 500px; overflow-y: auto; padding: 20px; border: 1px solid #eee;">
// <ProgressiveImage
// src="https://picsum.photos/seed/gallery1/1200/800"
// placeholder="https://picsum.photos/seed/gallery1/60/40"
// alt="A serene landscape with mountains and lake"
// style="width: 100%; max-width: 600px; display: block; margin-bottom: 30px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"
// />
// <ProgressiveImage
// src="https://picsum.photos/seed/gallery2/1000/700"
// placeholder="https://picsum.photos/seed/gallery2/50/35"
// alt="City skyline at sunset with vibrant colors"
// style="width: 100%; max-width: 600px; display: block; margin-bottom: 30px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"
// />
// <ProgressiveImage
// src="https://picsum.photos/seed/gallery3/900/1200"
// placeholder="https://picsum.photos/seed/gallery3/45/60"
// alt="Close-up of a blooming flower with dew drops"
// style="width: 100%; max-width: 400px; display: block; margin-bottom: 30px; border-radius: 8px; box-shadow: 0 4px 8px rgba(0,0,0,0.1);"
// />
// </div>
// </div>
// </template>
// <script setup lang="ts">
// // No explicit component import needed in script setup if registered globally
// </script>