腾讯云边缘安全加速(EdgeOne)之图片优化

查看 20|回复 0
作者:panisertoller   
应用背景
前面已经介绍过 EdgeOne 的基本使用方法(参见 腾讯云下一代 CDN ( EdgeOne/边缘安全加速)开箱即用 一文),本文将介绍如何使用 EdgeOne Worker 实现图片格式转换。
通过云边缘函数实现自动优化图片格式,可以提升页面加载速度,优化图片加速性能,进而提高网站的用户体验。
产品简介
腾讯云边缘函数( Edge Functions )提供了 EdgeOne 边缘节点的 Serverless 代码执行环境,只需编写业务函数代码并设置触发规则,无需配置和管理服务器等基础设施,即可在靠近用户的边缘节点上弹性、安全地运行代码。
目前该功能已公测上线,个人版优惠后仅 9.9 元/月,最近一段时间用下来,感觉还是方便的,尤其是处理图片缩放和格式转化的时候,使用免费的边缘函数来实现,香飘四野啊~~
套餐信息请查阅产品购买地址
实现步骤
官方最佳实践示例代码通过判断浏览器类型来设置转化格式,但是判断逻辑过于简单,容易产生误判导致返回不支持的编码格式。本文通过获取请求头中的 Accept 信息,来识别浏览器支持的图片类型,并使用 fetch API 获取源站图片,根据浏览器支持的图片编码类型对图片进行格式转换,以实现图片自适应格式的效果。

  • 接入 EdgeOne ,参见 从零开始快速接入 EdgeOne

  • 启用 站点加速 > 媒体处理 > 图片缩放 功能,参见 EdgeOne 图片处理

  • 创建 Worker ,并将以下 边缘函数代码 复制到 代码编辑器 中,参见 边缘函数( EdgeOne Functions )快速指引

  • 设置 Worker 触发规则,匹配类型选择 文件后缀,运算符选择 等于,值输入 png、jpg、jpeg


  • 验证函数是否按照预期运行,您可通过在浏览器或 Curl 发起请求测验,查看返回的头信息是否包含Backend-Option,以及其值是否为{"eo":{"image":{"format":"avif"}}}或{"eo":{"image":{"format":"webp"}}}。若包含且值正确,则表示函数已按照预期运行


  • 另外还支持调整图片尺寸,使用示例 https://www.rehiy.com/logo.png?100x100,其中 100x100 代表 长 x 宽,如果其中一个为 0 则表示对应的边自适应

    边缘函数代码
    /**
    * 图片转换 for EdgeOne Worker
    * @url https://www.rehiy.com/post/505/
    * @author Rehiy
    */
    async function handleEvent(request) {
        const uObj = new URL(request.url);
        const resize = uObj.search.match(/(\d+)x(\d+)/);
        const accept = request.headers.get('Accept');
        const option = {
            eo: {
                image: {},
                cacheKey: request.url,
            }
        };
        if (resize) {
            if (resize[1] > 0) {
                option.eo.image.width = +resize[1];
            }
            if (resize[2] > 0) {
                option.eo.image.height = +resize[2];
            }
        }
        for (const format of ['avif', 'webp', 'jp2', 'jxr', 'heif']) {
            if (accept.includes(format)) {
                option.eo.image.format = format;
                option.eo.cacheKey += '.' + format;
                break;
            }
        }
        const resp = await fetch(request, option);
        resp.headers.set('Backend-Option', JSON.stringify(option));
        resp.headers.set('Vary', 'Accept');
        return resp;
    }
    // eo listener
    addEventListener('fetch', event => {
        event.passThroughOnException();
        event.respondWith(handleEvent(event.request));
    });
  • 您需要登录后才可以回帖 登录 | 立即注册

    返回顶部