如何在 AWS 上構建支持 AVIF 的前端圖片優化方案

一、為什么使用 AVIF 圖片格式?

優勢點

說明

高壓縮率

在相似質量下,AVIF 文件比 JPEG/PNG/WebP 更小,能有效節省帶寬和存儲空間。

更高畫質

即使在低碼率下也能保持清晰細節,減少壓縮帶來的馬賽克或模糊問題。

支持透明度

像 PNG 一樣支持 Alpha 通道透明效果,且文件更小。

支持 HDR

支持高動態范圍(HDR)色彩,亮部與暗部細節表現更出色。

支持動畫

支持多幀動畫,體積遠小于 GIF,可實現流暢動畫效果。

開源免費

基于開放標準,無需支付版權費用,適合廣泛應用。

更好的色彩表現

支持更高位深(如 10 位、12 位色深),色彩過渡更加自然。

瀏覽器支持不斷提升

已被 Chrome、Firefox、Safari、Edge 等主流瀏覽器廣泛支持,兼容性持續提升。

采用 AVIF 圖片格式,可以大幅提升網頁加載性能、優化視覺體驗,并有效降低服務器及流量成本。

二、圖片上傳為 PNG/JPG,為什么最終返回的是 AVIF?

我們上傳至 AWS S3 桶中的圖片文件,最初是以傳統格式(如 PNG、JPG)存在的。但用戶最終訪問時,返回的是 AVIF 格式,主要是因為配置了以下動態處理流程:

  1. 攔截請求與格式判斷

  • 當瀏覽器請求圖片資源時,AWS 會攔截請求,檢測瀏覽器是否支持 AVIF 格式。

  • 如果支持,將在 S3 中查找對應的 AVIF 文件。

2. 動態生成 AVIF 圖片

- 如果 S3 桶中已有對應的 AVIF 圖片,直接返回。

- 如果沒有現成的 AVIF 圖片,則根據用戶請求的源圖片(PNG/JPG),實時生成一張新的 AVIF 圖片,并保存到 S3 桶中,隨后返回給用戶。

3. 兼容老瀏覽器

  • 如果瀏覽器不支持 AVIF,則直接返回原始格式的圖片(如 PNG、JPG),確保訪問兼容性。

三、替換同名圖片后,是否還會訪問到舊的 AVIF 圖片?

不會。

為了避免用戶訪問到緩存中的老圖片,系統在圖片上傳階段進行了以下處理:

  • 當上傳新的同名圖片時,AWS 會自動檢測并刪除已有的同名 AVIF 圖片資源。

  • 這樣一來,舊版 AVIF 圖片被清除。

  • 當用戶下次訪問時,因找不到舊的 AVIF 圖片,系統會根據新的源圖重新生成新的 AVIF 文件并返回。

  • 從而確保用戶訪問到的永遠是最新版本的圖片內容。

? 此機制有效避免了 CDN 緩存失效等待問題,大大簡化了圖片更新和運維管理流程。

四、我們訪問的圖片后綴明明是jpg 或者png 為什么我們下載下來是avif

  1. 瀏覽器發起請求,比如?GET https://yourdomain.com/path/image.jpg

  2. **請求頭(Accept)**中會帶上瀏覽器支持的圖片格式,比如:

Accept: image/avif,image/webp,image/apng,image/*,*/*;q=0.8

瀏覽器告訴服務器:"我可以接受 avif 格式哦!"

  1. Lambda@Edge 或 CDN(如 CloudFront)攔截了請求,根據請求頭里的?Accept?判斷,發現瀏覽器支持?avif,于是就做了智能格式替換:

  • 雖然你請求的是?image.jpg

  • 但是它在 S3 或緩存中找到了對應的?image.avif

  • 返回的時候,偷偷換了資源文件,返回的是?AVIF?內容

  • 當用戶下次訪問時,因找不到舊的 AVIF 圖片,系統會根據新的源圖重新生成新的 AVIF 文件并返回。

  • 從而確保用戶訪問到的永遠是最新版本的圖片內容。

  • ?返回的 HTTP 響應里,重要的是Content-Type?頭:

Content-Type: image/avif

瀏覽器收到的是一個 AVIF 格式的數據,雖然 URL 還是?.jpg,但實際上它知道應該用 AVIF 解碼來展示。

為什么下載下來是 AVIF?

  • 你點右鍵下載時,瀏覽器是根據返回的?Content-Type?類型來確定文件格式的,不是根據 URL 后綴。

  • Content-Type: image/avif,所以瀏覽器保存成了?.avif?文件,即使鏈接上還是?.jpg

  • 瀏覽器內部已經知道這張圖實際上是 AVIF 格式了。

總結一句話:

請求是 JPG,返回是 AVIF,靠的是 HTTP Content-Type,瀏覽器根據返回類型進行識別和保存。

五、補充說明

  • 動態生成 AVIF 圖片一般通過?AWS Lambda@Edge?來實現,支持實時生成并自動回寫存儲。

  • 項目如果對首屏加載性能要求極高,可以結合 CDN 對 AVIF 圖片進行緩存加速。

  • 建議統一規范圖片命名,避免因頻繁重名導致過多歷史資源堆積,影響桶管理效率。

要通過?AWS Lambda@Edge?動態把 S3 上的 PNG、JPG 轉成 AVIF 圖片,基本思路是:

  • 攔截圖片請求(比如?.jpg、.png)

  • 判斷瀏覽器?Accept?請求頭是否支持?image/avif

  • 如果支持:

  • 查詢 S3 中是否已有對應?.avif?文件

  • 如果沒有,就實時讀取源圖,轉碼成?.avif,存回 S3,再返回

  • 如果不支持:

  • 直接返回原圖

下面是一個簡單版的 Node.js(AWS Lambda@Edge)腳本示例:

const AWS = require('aws-sdk');
const sharp = require('sharp'); // sharp 用于圖片處理// S3 客戶端
const s3 = new AWS.S3({ region: 'your-bucket-region' });const BUCKET = 'your-bucket-name';exports.handler = async (event, context, callback) => {const request = event.Records[0].cf.request;const headers = request.headers;const uri = request.uri;console.log('Request URI:', uri);// 只處理 jpg/png 請求if (!uri.match(/\.(jpg|jpeg|png)$/i)) {return callback(null, request);}// 檢查瀏覽器是否支持 AVIFconst acceptHeader = headers['accept'] ? headers['accept'][0].value : '';const supportsAvif = acceptHeader.includes('image/avif');if (!supportsAvif) {// 不支持 AVIF,直接返回原圖console.log('Browser does not support AVIF');return callback(null, request);}// 構造 avif 文件的路徑const avifUri = uri.replace(/\.(jpg|jpeg|png)$/i, '.avif');try {// 先檢查 AVIF 是否已經存在await s3.headObject({Bucket: BUCKET,Key: decodeURIComponent(avifUri).substring(1), // 去掉開頭的 /}).promise();// 已存在,修改請求路徑,返回 avifconsole.log('AVIF exists, serving AVIF');request.uri = avifUri;return callback(null, request);} catch (error) {if (error.code !== 'NotFound') {// 其他異常console.error('Error checking AVIF file:', error);return callback(error);}console.log('AVIF not found, generating dynamically');// AVIF 不存在,讀取源圖const originImage = await s3.getObject({Bucket: BUCKET,Key: decodeURIComponent(uri).substring(1),}).promise();// 用 sharp 轉 AVIFconst avifBuffer = await sharp(originImage.Body).avif({ quality: 50 }).toBuffer();// 寫回 S3,生成新的 AVIF 文件await s3.putObject({Bucket: BUCKET,Key: decodeURIComponent(avifUri).substring(1),Body: avifBuffer,ContentType: 'image/avif',CacheControl: 'public, max-age=31536000', // 設置長緩存}).promise();// 修改請求路徑,返回新的 AVIFrequest.uri = avifUri;return callback(null, request);}
};

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81160.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81160.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81160.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++中的std::allocator

C中的std::allocator 文章目錄 C中的std::allocator1.std::allocator1.1C中的placement new 和operator new1.2一個custom allocator的實現1.3使用std::allocator_traits實現allocator 1.std::allocator C中的std::allocator默默工作在CSTL中的所有容器的內存分配上&#xff0…

CodeBuddy編程新范式

不會寫?不想寫? 騰訊推出的CodeBuddy徹底解放雙手。 示例 以下是我對CodeBuddy的一個小體驗。 我只用一行文字對CodeBuddy說明了一下我的需求,剩下的全部就交給了CodeBuddy,我需要做的就是驗收結果即可。 1.首先CodeBuddy會對任…

QML學習01(設置寬度、高度、坐標點、標題,信號與槽,鍵盤事件)

QML學習 1、前言2、QML3、QML和QWidget的區別3、QtQuick下的Windows應用4、總結 1、前言 記錄一下QML學習的過程,方便自己日后回顧,也可以給有需要的人提供幫助。 2、QML QML是 Qt 框架中的一種聲明式編程語言,專門用于快速設計和開發用戶…

在VSCode中接入DeepSeek的指南

本文將介紹三種主流接入方式,涵蓋本地模型調用和云端API接入方案。 一、環境準備 1.1 基礎要求 VSCode 1.80+Node.js 16.x+Python 3.8+(本地部署場景)已部署的DeepSeek服務(本地或云端)1.2 安裝必備插件 # 打開VSCode插件面板(Ctrl+Shift+X) 搜索并安裝: - DeepSeek Of…

機器學習-計量經濟學

機器學習 不要事前決定變量關系,關鍵是誰也不知道啊,機器學習學習的模型(那也不是真實的關系啊) 這就是自然學科的好處:只要不斷的優化這個未知的東西(函數),然后在數據上&#xff…

五、Linux賬號與權限管理

1、管理用戶和組賬號 1.1、用戶 1.1.1、用戶的概念及作用 在Linux系統中,用戶(User)指的是可以訪問系統資源的個體實體。每個用戶都有一個唯一的用戶賬號,用于標識和管理其在系統中的活動和訪問權限。 用戶的重要性和功能: 身份認證和訪問控制: 用戶賬號用于身份認證,確…

精益數據分析(61/126):移情階段評分體系構建與實戰案例解析

精益數據分析(61/126):移情階段評分體系構建與實戰案例解析 在創業的移情階段,如何科學評估用戶需求的真實性與緊迫性,是決定后續產品方向的關鍵。今天,我們結合《精益數據分析》中的評分框架,…

完成反射宇宙的最后一塊拼圖:泛型集合

反射,c#的黑科技,一手打造漂亮的,專屬于自己的屬性框 之前分享的: 如何寫一個自定義屬性控件的功能,但是只是對基礎的類型,比如String,bool,int等,但是對list<T>,Vector<T>這種泛型集合類型支持的不是很好,剛好最近重新研究了一下,將這個非常重要的功能完成了. 效…

Redis--基礎知識點--26--過期刪除策略 與 淘汰策略

Redis 的過期策略和淘汰策略是內存管理的核心機制&#xff0c;分別用于處理鍵的自動失效和內存不足時的數據清理。以下是詳細說明&#xff1a; 1 、過期刪除策略&#xff08;Expiration Policy&#xff09; 處理已設置過期時間&#xff08;EXPIRE&#xff09;的鍵&#xff0c;…

第六天——貪心算法——字符串分隔

1. 題目 給定一個字符串 s&#xff0c;我們需要將其劃分為盡可能多的部分&#xff0c;使得同一字母最多出現在一個部分中。 例如&#xff1a;字符串 "ababcc" 可以劃分為 ["abab", "cc"]&#xff0c;但要避免 ["aba", "bcc&quo…

[原創](現代Delphi 12指南):[macOS 64bit App開發]: 注意“回車換行“的跨平臺使用.

[作者] 常用網名: 豬頭三 出生日期: 1981.XX.XX 企鵝交流: 643439947 個人網站: 80x86匯編小站 編程生涯: 2001年~至今[共24年] 職業生涯: 22年 開發語言: C/C++、80x86ASM、Object Pascal、Objective-C、C#、R、Python、PHP、Perl、 開發工具: Visual Studio、Delphi、XCode、…

Maven 插件參數注入與Mojo開發詳解

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家&#xff0c;歷代文學網&#xff08;PC端可以訪問&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移動端可微信小程序搜索“歷代文學”&#xff09;總架構師&#xff0c;15年工作經驗&#xff0c;精通Java編…

擴增子分析|R分析之微生物生態網絡穩定性評估之節點和連接的恒常性、節點持久性以及組成穩定性指數計算

一、引言 周集中老師團隊于2021年在Nature climate change發表的文章&#xff0c;闡述了網絡穩定性評估的原理算法&#xff0c;并提供了完整的代碼。自此對微生物生態網絡的評估具有更全面的指標&#xff0c;自此網絡穩定性的評估廣受大家歡迎。本文將介紹網絡穩定性之節點和連…

人體肢體渲染-一步幾個腳印從頭設計數字生命——仙盟創夢IDE

人體肢體動作數據集-太極拳 渲染代碼 # 初始化Pygame pygame.init()# 設置窗口尺寸 WINDOW_WIDTH 800 WINDOW_HEIGHT 600 window pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT)) pygame.display.set_caption("動作回放")# 設置幀率 FPS 30 clock pyg…

強化學習入門:馬爾科夫獎勵過程

文章目錄 前言1、組成部分2、應用例子3、馬爾科夫獎勵過程總結 前言 最近想開一個關于強化學習專欄&#xff0c;因為DeepSeek-R1很火&#xff0c;但本人對于LLM連門都沒入。因此&#xff0c;只是記錄一些類似的讀書筆記&#xff0c;內容不深&#xff0c;大多數只是一些概念的東…

騰訊開源實時語音大模型VITA-audio,92mstoken極速響應,支持多語言~

簡介 VITA-Audio 是一個由騰訊優圖實驗室&#xff08;Tencent Youtu Lab&#xff09;、南京大學和廈門大學的研究人員共同開發的項目&#xff0c;旨在解決現有語音模型在流式生成&#xff08;streaming&#xff09;場景下生成第一個音頻令牌&#xff08;token&#xff09;時的高…

測序的原理

Sanger 測序原理 https://v.qq.com/x/page/d0124c0k44t.html illumina 測序原理&#xff1a; https://v.qq.com/x/page/i0770fd7r9i.html PacBio 第三代 SMRT 單分子測序 https://v.qq.com/x/page/r03534cry7u.html Ion torrent 測序原理 https://v.qq.com/x/page/v01754s6r82.…

高項-邏輯數據模型

邏輯數據模型的核心理解 1. 定義與特點 邏輯數據模型&#xff08;Logical Data Model, LDM&#xff09;&#xff1a; 是一種抽象的數據結構設計&#xff0c;用于描述業務實體&#xff08;如客戶、訂單&#xff09;及其關系&#xff08;如“客戶下單”&#xff09;&#xff0c…

《數字分身進化論:React Native與Flutter如何打造沉浸式虛擬形象編輯》

React Native&#xff0c;依托JavaScript語言&#xff0c;借助其成熟的React生態系統&#xff0c;開發者能夠快速上手&#xff0c;將前端開發的經驗巧妙運用到移動應用開發中。它通過JavaScript橋接機制調用原生組件&#xff0c;實現與iOS和Android系統的深度交互&#xff0c;這…

提高繩牽引并聯連續體機器人運動學建模精度的基于Transformer的分段學習方法

合肥工業大學王正雨老師團隊針對繩牽引并聯連續體機器人的運動學建模提出一種基于Transformer網絡的分段學習方法&#xff0c;該方法較傳統建模性能卓越、精度更高。相關研究論文“Transformer-based segmented learning for kinematics modelling of a cable-driven parallel …