Merge pull request #10747 from supabase/docs/storage-image-resizing

This commit is contained in:
Inian authored and GitHub committed 2022-12-13 11:50:22 +08:00
commit f3721a51ec
4 files changed
+179 -6

No files matched your search

@@ -248,6 +248,7 @@ export const menuItems: NavMenu = {
{ name: 'Quickstart', url: '/guides/storage/quickstart', items: [] },
{ name: 'Access Control', url: '/guides/storage/access-control', items: [] },
{ name: 'CDN', url: '/guides/storage/cdn', items: [] },
{ name: 'Image Resizing', url: '/guides/storage/image-resizing', items: [] },
],
},
{
+39 -5
View File
@@ -9,20 +9,54 @@ export const meta = {
All assets uploaded to Supabase Storage are cached on a Content Delivery Network (CDN) to improve the latency for users all around the world. CDNs are a geographically distributed set of servers or **nodes** which caches content from an **origin server**. For Supabase Storage, the origin is the storage server running in the [same region as your project](https://app.supabase.com/project/_/settings/general). Aside from performance, CDNs also help with security and availability by mitigating Distributed Denial of Service and other application attacks.
## Example
## Basic CDN - TTL Caching
Let’s walk through an example of how a CDN helps with performance. A new bucket is created for a Supabase project launched in Singapore. All requests to the Supabase Storage API first hit the CDN. A user from the United States requests an object and is routed to the U.S. CDN. At this point, that CDN node does not have the object in its cache and pings the origin server in Singapore. Another user, also in the United States, requests the same object and is served directly from the CDN cache in the United States instead of routing the request back to Singapore.
### Example
## Cache duration
Let’s walk through an example of how a CDN helps with performance.
By default, assets are cached both in the CDN and in the user's browser for 1 hour. After this, the CDN nodes ping the storage server to see if an object has been updated. You can modify this cache time when you are [uploading](/docs/reference/javascript/storage-from-upload) or [updating](/docs/reference/javascript/storage-from-update) an object by modifying the `cacheControl` parameter. If you expect the object to not change at a given URL, setting a longer cache duration is preferable.
A new bucket is created for a Supabase project launched in Singapore. All requests to the Supabase Storage API are routed to the CDN first.
If you need to update the version of the object stored in the CDN, there are various cache-busting techniques you can use. The most common way to do this is to add a version query parameter in the URL. For example, you can use a URL like `/storage/v1/object/sign/profile-pictures/cat.jpg?token=eyJh...&version=1` in your applications and set a long cache time of 1 year. When you want to update the cat picture, you can increment the version query parameter in the URL. The CDN will treat `/storage/v1/object/sign/profile-pictures/cat.jpg?token=eyJh...&version=2` as a new object and pings the origin for the updated version.
A user from the United States requests an object and is routed to the U.S. CDN. At this point, that CDN node does not have the object in its cache and pings the origin server in Singapore. Another user, also in the United States, requests the same object and is served directly from the CDN cache in the United States instead of routing the request back to Singapore.
### Cache duration
By default, assets are cached both in the CDN and in the user's browser for 1 hour. After this, the CDN nodes ping the storage server to see if an object has been updated. You can modify this cache time when you are [uploading](/docs/reference/javascript/storage-from-upload) or [updating](/docs/reference/javascript/storage-from-update) an object by modifying the `cacheControl` parameter.
If you expect the object to not change at a given URL, setting a longer cache duration is preferable.
If you need to update the version of the object stored in the CDN, there are various cache-busting techniques you can use. The most common way to do this is to add a version query parameter in the URL.
For example, you can use a URL like `/storage/v1/object/sign/profile-pictures/cat.jpg?token=eyJh...&version=1` in your applications and set a long cache time of 1 year.
When you want to update the cat picture, you can increment the version query parameter in the URL. The CDN treats `/storage/v1/object/sign/profile-pictures/cat.jpg?token=eyJh...&version=2` as a new object and pings the origin for the updated version.
Note that CDNs might still evict your object from their cache if it has not been requested for a while from a specific region. For example, if no user from United States requests your object, it will be removed from the CDN cache even if you set a very long cache control duration.
The cache status of a particular request is sent in the `cf-cache-status` header. A cache status of `MISS` indicates that the CDN node did not have the object in its cache and had to ping the origin to get it. A cache status of `HIT` indicates that the object was sent directly from the CDN.
## Smart CDN Caching
<Admonition type="note">
Smart CDN caching is enabled for [PRO tiers and above](https://supabase.com/pricing).
</Admonition>
With Smart CDN caching enabled, the asset metadata (not the content) in your database is synchronized to the edge. This automatically revalidates the cache when the content of an asset is changed or deleted.
Additionally, the cache HIT ratio is increased as the origin server is shielded from asset requests that haven't changed when using a different query string URL.
### Cache duration
The Smart CDN cache duration is controlled on the server and cached for as long as possible. However, you can still control the browser caching TTL using the [cacheControl](/docs/reference/javascript/storage-from-upload) option when uploading a file. Smart CDN caching works with all types of operations including signed URLs.
When a file is updated or deleted, the CDN cache is automatically invalidated to reflect the change (including transformed images).
It can take **up to 60 seconds** for the CDN cache to be invalidated as it has to propagate across all the data-centers around the globe.
When an asset is invalidated at the CDN level, it doesn't affect browser caching.
If you don't see the changes, make sure the browser cache has been updated.
If your asset is updated frequently, we recommend setting a low browser TTL value using the `cacheControl` option when using smart CDN caching.
## Public vs Private Buckets
Objects in public buckets do not require any Authorization to access objects. This leads to a better cache hit rate compared to private buckets. For private buckets, permissions for accessing each object is checked on a per user level. For example, if two different users access the same object in a private bucket from the same region, it results in a cache miss for both the users since they might have different security policies attached to them. On the other hand, if two different users access the same object in a public bucket from the same region, it results in a cache hit for the second user.
@@ -0,0 +1,117 @@
import Layout from '~/layouts/DefaultGuideLayout'
export const meta = {
id: 'storage-image-resizing',
title: 'Storage Image Resizing',
description: 'Resize images with Storage',
sidebar_label: 'Image Transformation',
}
Supabase Storage offers the functionality to transform and resize images dynamically. Any image stored in your buckets can be transformed and optimized for fast delivery.
<Admonition type="note">
Image Resizing is currently in beta and enabled for [PRO tiers and above](https://supabase.com/pricing).
</Admonition>
## Get a public URL for a transformed image
You can pass a `transform` option to the functions you are currently using to interact with your objects. This returns the public URL that serves the resized image.
```ts
supabase.storage.from('bucket').getPublicUrl('image.jpg', {
transform: {
width: 500,
height: 600,
}
})
```
An example URL could look like this:
`https://project_id.supabase.co/storage/v1/render/image/public/bucket/image.jpg?width=500&height=600`
## Signing URLs with transformation options
To share a transformed image for a fixed amount of time, provide the transform options when you create the signed URL:
```ts
supabase.storage.from('bucket').createSignedUrl('image.jpg', 60000, {
transform: {
width: 200,
height: 200,
}
})
```
The transformation options are embedded into the token—they cannot be changed once signed.
## Downloading images
To download a transformed image, pass the `transform` option to the `download` function.
```ts
supabase.storage.from('bucket').download('image.jpg', {
transform: {
width: 800,
height: 300,
}
})
```
## Transformation options
We currently support a few transformation options focusing on resizing and cropping images.
### Resizing
You can use `width` and `height` parameters to resize an image to a specific dimension. If only one parameter is specified, the image will be resized and cropped, maintaining the aspect ratio.
### Modes
You can use different resizing modes to fit your needs, each of them uses a different approach to resize the image:
Use the `resize` parameter with one of the following values:
- `cover` : resizes the image while keeping the aspect ratio to fill a given size and crops projecting parts. (default)
- `contain` : resizes the image while keeping the aspect ratio to fit a given size.
- `fill` : resizes the image without keeping the aspect ratio.
Example:
```ts
supabase.storage.from('bucket').download('image.jpg', {
transform: {
width: 800,
height: 300,
resize: 'contain' // 'cover' | 'fill'
}
})
```
### Limits
- Width and height must be an integer value between 1-2500.
- The image size cannot exceed 25MB.
- The image resolution cannot exceed 50MP.
### Supported Image Formats
| Format | Extension | Source | Result |
| -------|-----------|--------|--------|
| PNG | `png` | ☑️ | ☑️ |
| JPEG | `jpg` | ☑️ | ☑️ |
| WebP | `webp` | ☑️ | ☑️ |
| AVIF | `avif` | ☑️ | ☑️ |
| GIF | `gif` | ☑️ | ☑️ |
| ICO | `ico` | ☑️ | ☑️ |
| SVG | `svg` | ☑️ | ☑️ |
| HEIC | `heic` | ☑️ | ❌ |
| BMP | `bmp` | ☑️ | ☑️ |
| TIFF | `tiff` | ☑️ | ☑️ |
export const Page = ({ children }) => <Layout meta={meta} children={children} />
export default Page
+22 -1
View File
@@ -187,6 +187,17 @@ function StoragePage() {
title="CDN"
text="Serve from the edge to reduce latency."
/>
<Link href="/docs/guides/storage/cdn" passHref>
<Button
as="a"
size="small"
type="default"
className="mt-4"
icon={<IconArrowUpRight />}
>
Explore docs
</Button>
</Link>
</div>
<div className="col-span-6 lg:col-span-12 xl:col-span-4">
<FeatureColumn
@@ -194,7 +205,17 @@ function StoragePage() {
title="Transformations"
text="Resize and compress your media before you serve it."
/>
<Badge>Coming soon</Badge>
<Link href="/docs/guides/storage/image-resizing" passHref>
<Button
as="a"
size="small"
type="default"
className="mt-4"
icon={<IconArrowUpRight />}
>
Explore docs
</Button>
</Link>
</div>
</div>,
]}