EdgeOne边缘函数实现全站图片转AVIF

AVIF 相较于传统图片格式(如 JPEG、PNG)具有更高的压缩效率,文件体积更小,支持 HDR 和透明通道,同时画质更佳。与 WebP 相比,AVIF 的压缩率高 10%-30%,在低码率下画质更出色。本文老白博客基于腾讯云EdgeOne自带的边缘函数,实现全站图片转AVIF,并对不支持的浏览器采用对应的格式显示。

EdgeOne边缘函数实现全站图片转AVIF

1.avif与webp对比

avif格式与webp格式图片的对比

  • 压缩效率:与 WebP 和其他图像格式相比,AVIF 提供了卓越的压缩效率。它可以实现更高水平的压缩,同时保持出色的图像质量。
  • 图像质量:AVIF 支持广泛的色彩空间,包括 HDR(高动态范围)、宽色域和深色。它还支持无损和有损压缩,允许多种图像质量选项。

WordPress图片avif和webp格式转换插件WP AWR

广泛的浏览器支持

虽然 AVIF 仍然相对较新,但近年来它获得了重要的浏览器支持。Google Chrome,Mozilla Firefox和Microsoft Edge等主要浏览器增加了对AVIF的支持

参考网页:https://caniuse.com/?search=avif

WordPress图片avif和webp格式转换插件WP AWR

2.EdgeOne边缘函数转avif

点击函数管理,选择新建函数

腾讯云edgeone图片自适应缩放边缘函数

任意选择一个,比如图片处理,然后点击下一步

腾讯云edgeone图片自适应缩放边缘函数

全选删除原来的,将下面的代码①,或者代码②粘贴即可

边缘函数代码①

全选删除已有的函数代码,然后添加下方的代码,点击部署。

// 此处规定浏览器使用图片格式-https://www.xcbtmw.com/31278.html
const broswerFormat = {
  Chrome: 'avif',
  Opera: 'webp',
  Firefox: 'avif',
  Safari: 'avif',
  Edge: 'avif',
  IE: 'jxr',
  QQBrowser: 'webp' // QQ 浏览器使用 WebP 格式
};

addEventListener('fetch', event => {
  // 当函数代码抛出未处理的异常时,边缘函数会将此请求转发回源站
  event.passThroughOnException();
  event.respondWith(handleEvent(event));
});

async function handleEvent(event) {
  const { request } = event;
  const userAgent = request.headers.get('user-agent');
  const browser = getBroswer(userAgent);
  const format = broswerFormat[browser] || 'webp';

  // 始终转换图片格式,根据浏览器设置的格式进行处理
  const response = await fetch(request, {
    eo: {
      image: {
        format
      }
    }
  });

  // 设置响应头并返回转换后的图片
  const modifiedResponse = new Response(response.body, response);
  modifiedResponse.headers.set('x-ef-format', format);
  return modifiedResponse;
}

function getBroswer(userAgent) {
  if (/QQBrowser/i.test(userAgent)) {
    return 'QQBrowser'; // 新增对 QQ 浏览器的判断
  }
  if (/Edg/i.test(userAgent)) {
    return 'Edge';
  }
  if (/Trident/i.test(userAgent)) {
    return 'IE';
  }
  if (/Firefox/i.test(userAgent)) {
    return 'Firefox';
  }
  if (/Chrome/i.test(userAgent)) {
    return 'Chrome';
  }
  if (/Opera|OPR/i.test(userAgent)) {
    return 'Opera';
  }
  if (/Safari/i.test(userAgent)) {
    return 'Safari';
  }
}

边缘函数代码②

修改说明:

  • 增加了一个大小判断,如果转avif后,图片体积增大,则强制转化为webp
// 浏览器使用图片格式-https://www.xcbtmw.com/31278.html
const broswerFormat = {
  Chrome: 'avif',
  Opera: 'webp',
  Firefox: 'avif',
  Safari: 'avif',
  Edge: 'avif',
  IE: 'jxr',
  QQBrowser: 'webp' // QQ 浏览器使用 WebP 格式
};

addEventListener('fetch', event => {
  // 当函数代码抛出未处理的异常时,边缘函数会将此请求转发回源站
  event.passThroughOnException();
  event.respondWith(handleEvent(event));
});

async function handleEvent(event) {
  const { request } = event;
  const userAgent = request.headers.get('user-agent');
  const browser = getBroswer(userAgent);
  let format = broswerFormat[browser] || 'webp'; // 默认格式为 WebP

  // 获取原始图片的响应
  const originalResponse = await fetch(request);
  const originalBuffer = await originalResponse.arrayBuffer();
  const originalSize = originalBuffer.byteLength;

  // 尝试转换为目标格式(初始为 AVIF 或其他指定格式)
  const transformedResponse = await fetch(request, {
    eo: {
      image: {
        format
      }
    }
  });
  const transformedBuffer = await transformedResponse.arrayBuffer();
  const transformedSize = transformedBuffer.byteLength;

  // 如果转换为 AVIF 后体积增大,则强制转换为 WebP
  if (format === 'avif' && transformedSize > originalSize) {
    format = 'webp';
    const webpResponse = await fetch(request, {
      eo: {
        image: {
          format
        }
      }
    });
    const response = new Response(webpResponse.body, webpResponse);
    response.headers.set('x-ef-format', format);
    return response;
  }

  // 设置响应头并返回转换后的图片
  const response = new Response(transformedBuffer, transformedResponse);
  response.headers.set('x-ef-format', format);
  return response;
}

function getBroswer(userAgent) {
  if (/QQBrowser/i.test(userAgent)) {
    return 'QQBrowser'; // 新增对 QQ 浏览器的判断
  }
  if (/Edg/i.test(userAgent)) {
    return 'Edge';
  }
  if (/Trident/i.test(userAgent)) {
    return 'IE';
  }
  if (/Firefox/i.test(userAgent)) {
    return 'Firefox';
  }
  if (/Chrome/i.test(userAgent)) {
    return 'Chrome';
  }
  if (/Opera|OPR/i.test(userAgent)) {
    return 'Opera';
  }
  if (/Safari/i.test(userAgent)) {
    return 'Safari';
  }
}

3.EdgeOne触发规则

选择and,然后host填写你添加的网站域名,然后这里还可以选择你想要的图片格式

EdgeOne边缘函数实现全站图片转AVIF

3.1 效果演示

测试用原始图片请求 URL 为:https://www.xcbtmw.com/wp-content/uploads/2024/11/sitelogo.webp

访问后查看响应头如:content-type:image/avif

EdgeOne边缘函数实现全站图片转AVIF

4.说明

这种转换方式未改变原始图片格式,未改变数据库结构

如果想要永久性转换,参考:

更多有关腾讯云EdgeOne边缘函数使用可见文末标签。