Skip to content

feat: add dioxus support && update props & docs #5

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

Merged
merged 1 commit into from
May 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 154 additions & 0 deletions DIOXUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
# 🧬 Image RS Dioxus Usage

Adding Image RS to your project is simple:

1. Make sure your project is set up with **Dioxus**. Refer to the [Dioxus Getting Started Guide](https://dioxuslabs.com/learn/0.6/getting_started) for setup instructions.

1. Add the **image-rs** library to your dependencies by including it in your `Cargo.toml` file:

```sh
cargo add image-rs --features=dio
```

1. Import the `Image` component into your Dioxus application.

## πŸ› οΈ Usage

Incorporating `Image RS` into your **Dioxus** application is simple. Here's how:

1. Add the `Image` component to your Dioxus project:

```rust
use dioxus::prelude::*;
use image_rs::dioxus::Image;
```

1. Use the `Image` component in your app like this:

```rust
use dioxus::prelude::*;
use image_rs::dioxus::Image;
use image_rs::{Layout, Loading};

fn App() -> Element {
rsx! {
Image {
src: "/images/photo.jpg",
alt: "A beautiful view",
width: "800",
height: "600",
layout: Layout::Responsive,
loading: Loading::Lazy,
}
}
}
```

## πŸ”§ Props

### πŸ–ΌοΈ Main Props

| Property | Type | Description | Default |
| -------------- | -------------- | --------------------------------------- | ------------ |
| `src` | `&'static str` | Image source path or URL | `""` |
| `alt` | `&'static str` | Alt text for accessibility | `"Image"` |
| `fallback_src` | `&'static str` | Fallback image if `src` fails | `""` |
| `width` | `&'static str` | Width in pixels | `""` |
| `height` | `&'static str` | Height in pixels | `""` |
| `layout` | `Layout` | Layout strategy: Responsive, Fill, etc. | `Responsive` |
| `placeholder` | `&'static str` | Placeholder while loading | `"empty"` |
| `loading` | `Loading` | Load strategy: `Lazy` or `Eager` | `Lazy` |

### 🎨 Styling Props

```sh
+-----------------------------------------------------------+
| [Image Container] | <-- `class` & `style`
| |
| +-----------------------------------------------+ | <-- `layout`
| | [Loaded Image] | | <-- `src`
| +-----------------------------------------------+ |
| |
+-----------------------------------------------------------+
```

| Property | Type | Description | Default |
| ----------------- | -------------- | ------------------------------------------- | --------- |
| `class` | `&'static str` | CSS classes | `""` |
| `style` | `&'static str` | Inline CSS styles | `""` |
| `object_fit` | `ObjectFit` | Resizing mode: `Cover`, `Contain`, etc. | `Contain` |
| `object_position` | `Position` | Alignment inside container | `Center` |
| `sizes` | `&'static str` | Responsive image size hints | `""` |
| `quality` | `&'static str` | Image quality hint | `""` |
| `blur_data_url` | `&'static str` | Low-res blurred image to show while loading | `""` |

### βš™οΈ Behavioral Props

| Property | Type | Description | Default |
| ---------- | ------------------ | ------------------------------------------ | ------- |
| `on_load` | `Callback<()>` | Called when image has loaded | No-op |
| `on_error` | `Callback<String>` | Called when image fails to load | No-op |
| `decoding` | `Decoding` | Image decoding strategy: Auto, Sync, Async | `Auto` |

### 🌐 Network & Source Props

| Property | Type | Description | Default |
| ---------------- | ---------------- | -------------------------------------------- | ------------ |
| `srcset` | `&'static str` | Set of image sources for responsive behavior | `""` |
| `crossorigin` | `CrossOrigin` | CORS mode | `None` |
| `referrerpolicy` | `ReferrerPolicy` | Controls how much referrer info is sent | `NoReferrer` |
| `usemap` | `&'static str` | Use with image maps | `""` |
| `ismap` | `bool` | Server-side image maps inside `<a>` tags | `false` |

### ⚑ Performance Props

| Property | Type | Description | Default |
| ---------------- | --------------- | ------------------------------------------------ | --------- |
| `fetchpriority` | `FetchPriority` | Image fetch priority (`Auto`, `High`, `Low`) | `Auto` |
| `elementtiming` | `&'static str` | Performance marker ID | `""` |
| `attributionsrc` | `&'static str` | Attribution reporting URL (experimental) | `""` |
| `lazy_boundary` | `&'static str` | How early to trigger lazy load (`e.g., "200px"`) | `"100px"` |
| `unoptimized` | `bool` | Disables automatic image optimizations | `false` |

### 🧠 Accessibility Props (ARIA)

| Property | Type | Description | Default |
| ------------------ | -------------- | -------------------------------------------------------------- | --------- |
| `aria_current` | `&'static str` | Current step/item indicator (`"page"`, `"step"`, etc.) | `""` |
| `aria_describedby` | `&'static str` | ID of an element describing the image | `""` |
| `aria_expanded` | `&'static str` | `"true"` or `"false"` if content is expanded | `""` |
| `aria_hidden` | `&'static str` | Hides image from assistive tech | `"false"` |
| `aria_live` | `AriaLive` | Priority of live region updates (`Off`, `Polite`, `Assertive`) | `Off` |
| `aria_pressed` | `AriaPressed` | Toggle state (`True`, `False`, `Mixed`, `Undefined`) | `False` |
| `aria_controls` | `&'static str` | ID of element this image controls | `""` |
| `aria_labelledby` | `&'static str` | ID of label element | `""` |

## πŸ’‘ Notes

- **Required**: `src` and `alt` are essential for accessibility and rendering.
- **Layout behavior**:

- `Responsive`, `Fill`, `Intrinsic`, and `Fixed` alter how dimensions are applied.
- `Fill` ignores width/height and stretches the image.

- **Loading**:

- `placeholder` and `blur_data_url` create a smoother user experience.
- Use `on_load` / `on_error` for lifecycle management.

- **Lazy loading**:

- Uses [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API).
- `lazy_boundary` controls how early the image loads.

- **Optimization**:

- `unoptimized = true` disables default optimizations.

- **Performance tracking**:

- `elementtiming` and `attributionsrc` assist in analytics and attribution.

- **Accessibility**:

- Add `aria-*` attributes to enhance usability with screen readers and assistive devices.
53 changes: 2 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
| Framework | Live Demo |
| --- | --- |
| Yew | [![Netlify Status](https://api.netlify.com/api/v1/badges/a0efc7e9-f20e-4dd9-93e1-c8f4fde7506f/deploy-status)](https://image-rs.netlify.app) |
| Dioxus | TODO |
| Dioxus | [![Netlify Status](https://api.netlify.com/api/v1/badges/a0efc7e9-f20e-4dd9-93e1-c8f4fde7506f/deploy-status)](https://image-dio.netlify.app) |
| Leptos | TODO |

## πŸ“œ Intro
Expand All @@ -46,7 +46,7 @@ The following features make Image RS a must-have for modern WASM apps:
<!-- absolute url for docs.rs cause YEW.md is not included in crate -->
Refer to [our guide](https://github.com/opensass/image-rs/blob/main/YEW.md) to integrate this component into your Yew app.

## 🧬 Dioxus Usage (TODO)
## 🧬 Dioxus Usage

<!-- absolute url for docs.rs cause DIOXUS.md is not included in crate -->
Refer to [our guide](https://github.com/opensass/image-rs/blob/main/DIOXUS.md) to integrate this component into your Dioxus app.
Expand All @@ -56,55 +56,6 @@ Refer to [our guide](https://github.com/opensass/image-rs/blob/main/DIOXUS.md) t
<!-- absolute url for docs.rs cause LEPTOS.md is not included in crate -->
Refer to [our guide](https://github.com/opensass/image-rs/blob/main/LEPTOS.md) to integrate this component into your Leptos app.

## πŸ“ˆ Benchmark

1. Open browser DevTools (Press F12) > **Lighthouse** tab.
1. Record page load by clicking "Analyze Page Load".
1. Observe:
- **First Contentful Paint (FCP)**
- **Largest Contentful Paint (LCP)**
- **Time to Interactive (TTI)**
- **Total network transfer size**
- **Memory usage**

### πŸš€ Summary

| Feature | Yew Image RS | Next.js Image |
|:-------|:-------------|:--------------|
| Native Rust+Wasm | βœ… | ❌ |
| Built-in Image Optimization | βœ… | βœ… |
| SSR/SEO Friendly | βœ… | βœ… |
| Fine-grained DOM Control | βœ… | ❌ |
| Smaller JS Payload | βœ… | βœ… |

### πŸ“Š Performance Results

When loading **10 images**, **Yew Image RS** and **Next.js Image** are **on par**:

| Metric | Yew (Wasm) | Next.js |
|:------|:-----------|:--------|
| Performance Score (Lighthouse) | 100 | 100 |
| Memory Usage (Heap) | ~8 MB | ~8 MB |

However, when scaling up to **10,000 images loaded simultaneously**:

| Metric | Yew (Wasm) | Next.js |
|:------|:-----------|:--------|
| Performance Score (Lighthouse) | 64 | ❌ (Lighthouse fails) |
| Memory Usage (Heap) | ~78 MB | ~83 MB |
| Scrolling Smoothness | Very Smooth | Laggy |

**Key observations:**
- **Wasm** (Yew) handles large DOM updates much better than **JavaScript**.
- **Memory usage** is slightly lower with **Wasm**.
- **Next.js** site **failed Lighthouse audit** at 10,000 images (due to TTI timeout).
- **Smoothness** is significantly better with Yew under heavy load.

### πŸ› οΈ Future Improvements

- **Image RS** is working on **automatic image optimization**.
- **Progressive loading** and **lazy hydration** strategies are being researched for even better large-scale performance.

## 🀝 Contributions

Contributions are welcome! Whether it's bug fixes, feature requests, or examples, we would love your help to make Image RS better.
Expand Down
Loading