ios 图片浏览器_使用AWS Lambda提高网站图片加载速度1X倍

news/2024/5/9 18:46:09/文章来源:https://blog.csdn.net/weixin_39841825/article/details/111254882

当你浏览一个网站页面的时候,浏览器开始了加载页面的过程,你当然希望立即看到这个网页的内容,如果网站加载过慢你可能会产生焦虑并直接关闭它,这对网站的影响是致命的,因为搜索引擎会统计网站的跳出率,进而影响网站的域名权重和排名,如果放任网页加载很慢会逐渐导致网站的自然搜索流量降低很多,所以一个好的网站应该加载时间越短越好,最长也不应该超过3秒。现代网站都会使用一些技术去提高网站加载速度,比如我们可以:

  1. 提高域名DNS解析速度;

  2. 通过一些打包工具压缩CSS和JS文件包的大小;

  3. JS延迟或异步加载;

  4. 图片懒加载;

  5. 静态资源加CDN支持;

  6. 使用高压缩比的有损图片格式等。

网站加载速度影响因素分析

以上影响网站加载速度的因素中,图片资源过大是一个很重要的因素。在Web流量中,图片一直是大头,如何将图片压缩的更小却不损失一些细节是大家一直在研究的话题。为了更好的演示这个问题,我使用Google提供的Pagespeed Insights评估了下我博客的这篇文章页面《我的财务管理方案》:

6d83a866820268584607a41e49cbfb14.png

如上图所示,全部图片加载耗时39秒之多,这纵然和我上传了过大的PNG图片有关系,实际我应该在本地上传图片前做一番压缩的,不过由于我的工作流中写文章是用Markdown格式的,图片一般是截图或者复制直接粘贴进Markdown文件中(通过VSCode插件自动帮我从内存中上传到AWS S3中然后插入CDN链接至VSCode),由于图片在内存中上传S3是PNG无损图片格式的,PNG图片一般都很大的,如果图片很多的话会导致用户流量网页需要加载很长时间:

3a970ca89d41eb8a3e4376064d7906de.png

这篇文章如果首次加载需要下载近10MB的图片资源,如果网速慢的话根本加载不完。要解决这个问题,让我们先研究下不同图片格式的差异:

图片格式对比

7bcf46351172531200192284143970d6.png

如上图,考虑到压缩比与浏览器兼容性,一般我们在网页用的图片主要是JPEG(JPG)/GIF/PNG这三种,JPEG和JPG是同一种格式,只因为早期Windows后缀不允许四个的后缀名。这篇Comparison of different image compression formats论文对比了BMP、TIFF、PNG、JPEG、JPEG 2000图片的压缩比较:

043d15fa2c879ffa817ec67353b81526.png

从上可看,一般网站对图片没啥格式要求的话,尽量使用JPG格式图片,压缩比高的有损图片,如果要支持无损图片,可以使用PNG。

不过Google在2010年发布了一种黑科技的图片格式:WebP。

WebP

与PNG相比,WebP无损图像的尺寸要小26%。在同等的SSIM质量指数下,WebP有损图像比同类JPEG图像小25-34%。无损WebP支持透明性(也称为Alpha通道),而仅增加22%的字节数。对于可以接受有损RGB压缩的情况,有损WebP还支持透明性,与PNG相比,文件大小通常小3倍。从我个人的测试中,同一张图片,如:https://img.bmpi.dev/3461797f-6a16-e9a5-a01c-f583d7086b49.png,PNG大小为2.1MB,WebP为198KB,而图片细节并没什么丢失(从网页浏览看)。

这么看WebP很完美,唯一的问题在于兼容性,Safari到2020年了都不支持Webp,十年过去了!!!不仅Safari不支持,所有以Safari内核WebKit开发的浏览器都不支持,包括iOS上的Chrome。那我们能不能不支持Safari或者说iOS平台呢?

1f8a4b9fc73e558c581155a48f993074.png

要不要支持iOS是个问题

如果你网站不在乎iOS的流量,那当然可以不支持,不过当我看到我的一个网站的统计如下时:

5dd268a3aec1b8c8190cc14c84b28efe.png

e4770b2d12437e9ea10e7cb16db13fb8.png

如上图所示,近一半的流量都来自iOS平台,所以还是得支持iOS。

AWS Lambda@Edge方案

简单介绍下我博客(https://bmpi.dev)的技术栈:

  1. 博客使用Hugo静态编译Markdown文件生成页面。

  2. 博客使用Netlify集成Github托管。每次我写完文章通过Git Push到Github后会自动触发Netlify构建网站并发布。

  3. 图片都存放在AWS S3中,通过AWS CloudFront作为CDN加速。

  4. 域名通过AWS Route53服务解析。

我们可以通过判断浏览器User Agent的类型给iOS用户返回jpg/png图片,给支持webp的浏览器返回webp格式图片,如下:

user->browser->js check ua->imgix(image convert api)->s3

不过这个方案存在两个问题:

  1. imgix处理1000个图片3美刀,太贵!

  2. 由于是静态渲染生成网站,并没有可编程控制的Web服务器,没法直接从服务端处理用户请求。

方案设计

我们换一种可行的方案:

user->browser->aws cloudfront->aws lambda->s3

8bf73fe96643e5d7a11b4ac6d0fcefdc.png

如上图,当用户通过CDN访问S3中的图片时会抛出四种事件:Viewer Request、Origin Request、Viewer Response、Origin Response。AWS允许我们使用Lambda@Edge(Lambda的扩展,只能部署在us-east-1区域中,但是可以同步到各区域的cloudfront中)监听这四种事件并做一些处理,比如对浏览器请求的header与cookie做一些修改,对源响应做一些额外处理,比如转换图片之类。具体流程如下分解1:

  1. 监听浏览器对CDN的请求,并触发劫持任何Viewer Request请求的Lambda函数。

  2. 根据我们从请求中收到的浏览器UA,确定请求事件是否针对图像,以及请求资源的浏览器是否支持WebP。

  3. 如果确定请求是针对图像的,并且浏览器支持WebP,则将其替换为.webp的请求uri图像扩展名,并将原始扩展名添加到请求header中。

  4. 接下来,我们触发一个单独的Lambda函数,该Lambda函数劫持任何来自CDN的Origin Response事件。

  5. 如果响应事件的请求uri扩展名为.webp,并且响应状态为404,我们将在S3存储桶中检查同一张图片,但使用原始扩展名,请在步骤3中将其放入请求header中。

  6. 如果在S3中找到具有原始扩展名的图像,则使用Sharp2运行webp转换后先存放至S3中供下次使用然后将其放置在原始响应中,否则,将404响应保持不变。

成本分析

通过AWS这篇文章3分析指出,处理了100万张图像,15GB存储和50GB数据传输也才不到90块钱人民币,的确很便宜。

在上述方案中,我们每次将处理好的webp图片存放至S3中,供下次用户查询时不需要再次转换立即就可以从S3中取出给用户,响应速度提升了,同时减少了Lambda@Edge函数的运行,可以帮我们省钱,相比新增的S3存储,因为webp格式本身是很小的,这个存储成本也是可以接收的。

方案实现

在编写代码之前,确保你先看了这篇AWS官方介绍文章:《Resizing Images with Amazon CloudFront & Lambda@Edge | AWS CDN Blog》4。

最终代码放至aws-lambda-edge-img2webp5。

代码组织结构如下:

.
├── Dockerfile
├── Makefile
├── aws-sam-lambda-edge-webp.yaml
├── dist
│   ├── origin-response-function.zip
│   └── viewer-request-function.zip
├── lambda
│   ├── origin-response-function
│   │   ├── index.js
│   │   ├── package-lock.json
│   │   └── package.json
│   └── viewer-request-function
│   ├── index.js
│   ├── package-lock.json
│   └── package.json
  1. Viewer-Request Function

7a9ad7aa85353aaa66412b8479521a5c.png

  1. Origin-Response Function

f4e220fdacc78857343af79e4f426e17.png

  1. 编写Dockerfile与Makefile构建Lambda部署包:

5f568e83321d384c6d6a72821a9dc4d7.png

6e63d886e680f6fd0549e61950f9cb25.png

在本地项目根目录执行make all后脚本自动使用Docker打包Lambda@Edge压缩包至dist目录,然后我们上传至AWS的us-east-1中的S3桶中,如果没有可以随便建一个,我建立的是bmpidev-aws-lambda-edge,这个必须和下面的CloudFormation配置文件一致才行,方便我们接下来使用,然后将dist中两个压缩包上传至这个S3桶中。

  1. CloudFormation配置文件

9ee8923d879c0eb10dfd9fed292b6fb0.png

将以上文件上传至us-east-1区域的CloudFormation新建一个堆栈,此配置文件会自动生成Lambda函数所需的角色和AWS IAM策略,这个文件执行完毕后,你需要给IAM/角色/权限中赋予S3写入读取权限,这样Origin-Response Function才有权限将webp上传到你的图片资源桶中。

  1. 部署Lambda函数至Lambda@Edge

在Lambda>函数>bmpidevImgTransformResponse/bmpidevImgTransformRequest中,点击操作>功能>部署到Lambda@Edge。

c2abb747c7b828291ae153a5e72734a5.png

如上图,确认后,开始将Lambda函数部署到Lambda@Edge并关联到你的CloudFront中,你在CloudFront监控中应该可以看到部署的Lambda函数的统计信息。

  1. 在CloudWatch中查看Lambda日志

这个在调试的时候很有用,Lambda的Nodejs支持打印日志的,这样我们就可以看到函数执行的具体情况了。

AWS Lambda@Edge方案的坑

  1. AWS Lambda@Edge Viewer Request部署压缩包不能超过1MB,而Origin Response却可以超过1MB,所以在打包的时候必须将这两个函数分别打包才行,因为Origin Response函数中我们需要使用Sharp转换图片格式,而这个包的node_modules很大,整个压缩包快40MB了。而Viewer Request由于只使用了useragent和path的nodejs包,打包后才102KB。

  2. AWS与S3的权限配置也很重要,删除Lambda@Edege函数也需要在CloudFront里取消关联后才能删除,一般耗时几小时才能生效。

  3. Lambda@Edge必须在us-east-1区域部署才行,其他区域无此功能,部署后可以同步到全球各区域的CloudFront关联,如果要删除则必须先全部取消CloudFront Lambda关联才能自行删除。

  4. 需要注意Nodejs版本支持,目前最高支持nodejs10.x。

  5. 给IAM角色赋予S3写入读取权限。

  6. 如果是同一账号,只要给Lambda的执行角色赋予S3操作权限,则无需加入S3 Bucket存储桶策略,否则需要加入相关策略,具体可通过这个工具6生成。

  7. 如果还是无法访问S3,请检阅此文件7

  8. 如果还是不行,则只能通过Lambda测试来发现问题,日志可在CloudWatch查看相关日志流(需注意S3区域,不同用户从不同区域访问CloudFront,日志会放入相关区域的CloudWatch中),也可以通过CloudFront Monitoring查看聚合日志统计。

  9. 如果存储桶是私有的,则Lambda在判定对象是否存在时返回的是403而不是404,这是有意义的,因为可以防止攻击者去枚举桶中的数据。具体查看8。

  10. 通过日志观察函数执行时间和内存消耗来调整内存大小和最大执行时间优化服务可用性。

最终效果

af1cfd2ccc12629f3e4f1cb504ce01ca.png

同一个页面,在支持webp格式的浏览器中总加载大小从10MB降低至不到1MB,加载时间从12秒降至3秒。

References

  1. https://medium.com/nona-web/converting-images-to-webp-from-cdn-9433b56a3d52 ↩︎

  2. https://github.com/lovell/sharp ↩︎

  3. https://docs.aws.amazon.com/solutions/latest/serverless-image-handler/overview.html ↩︎

  4. https://aws.amazon.com/cn/blogs/networking-and-content-delivery/resizing-images-with-amazon-cloudfront-lambdaedge-aws-cdn-blog/ ↩︎

  5. https://github.com/bmpi-dev/aws-lambda-edge-img2webp ↩︎

  6. https://awspolicygen.s3.amazonaws.com/policygen.html ↩︎

  7. https://aws.amazon.com/cn/premiumsupport/knowledge-center/lambda-execution-role-s3-bucket/ ↩︎

  8. https://stackoverflow.com/questions/50008445/aws-cloudfront-returns-access-denied-from-s3-origin-with-query-string ↩︎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_754231.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源自助建站_自助建站还是找建站公司?网站建设方式怎么选?

当有建站需求的时候,很多人都想的是自己自助建站?还是找专业的网站建设公司建站?到底哪种方式,才最适合我?其实网站建设方式不只是自助建站和找专业的网站建设公司这两种,而是有很多。那么,对此…

html下拉列表不居中_每个非网站开发人员都应该了解的21个HTML基础知识

1.标题标题可能是最容易学习的代码之一,并考虑到 它们对您的SEO至关重要,这是一件好事。共有六种不同类型,如下所示。要创建标题,只需将文本包装在所选的标题标签中:2.段落没有一段要详细说明该消息的标题会是什么&…

无人机官方网站_大疆发布全新编程教育无人机,Mind+编程助力其创意无限!

8月25日,大疆发布了全新编程教育无人机新品—ROBOMASTER TT 创造力套装。作为行业领先教育无人机,该款无人机不仅将强大飞行性能注入轻小机身中,使用大疆行业顶尖飞控算法,保障飞行安全性与稳定性,同时搭载500万高清摄…

python网站开发换行_Python在图片中插入大量文字并且自动换行

问题 如何在图片中插入大量文字并且自动换行 效果 原始图效果图注明 若需要写入中文请使用中文字体 实现方式 from PIL import Image, ImageDraw, ImageFont class ImgText: font ImageFont.truetype("micross.ttf", 24) def __init__(self, text): # 预设宽度 可以…

wordpress include 不生效_wordpress零基础建站(4)-在腾讯云搭建LNMP+Redis+wordpress

今天这篇教程我们开始在腾讯云服务器上搭建wordpress环境并安装wordpress,开始涉及到搭建代码了,对于代码不熟悉的小伙伴也不要着急,我会在教程中对于每条命令执行了什么操作作出说明,只要按照步骤操作即可完成wordpress的搭建。本…

云主机管理神器网站管理助手

云主机越来越普及的时代,很多用户苦于没有合适的windows版的管理工具,IIS太弱而且没法支持到目录安全、PHP环境、mysql数据库等。这里推荐西数管理助手给各位,关键是免费可用! 西部数码网站管理助手是一款面向拥有独立服务…

11个与众不同、令人叹为观止的单页网站

单页网站能够给网站浏览者提供一个简洁、叹为观止的体验。在单一的页面内展示完你需要的内容可能是一个富有挑战性的过程,但许多网页设计师喜欢用这种方法 把网站的内容放在一个令人惊讶的页面设计中。从单页所用的图片和文字,以叹为观止的视觉差滚动效果…

java和seo哪个好,seo和java哪个更好

一个seo行业站点,科学的内容制作应该与seo相关,且内容本身是有人搜索的。seo和java哪个更好是有人搜索的语句,且与seo是强相关的,对于seo教程自学网来讲,这样的内容再适合不过了。 任何一门技术,如果精通&a…

Sogou搜狗搜索引擎登录网站 - Blog透视镜

Sogou搜狗是中国搜狐旗下的搜索引擎,其登录方式也很简单,只要输入网址,验证码即可,不需要注册账号,再进行登录,其他非 * 必填的字段,可留下空白不填,验证码只有4码,也很清…

vue+elementui完美实现博客、网站、个人网站,高仿“张凯博客”实现排版

1.本项目Demo实现灵感来源 张凯博客,采用vueelementui实现编码,最终效果图: 完整源码下载 2.首先创建vue项目,采用开发工具Hbuilder。vue创建项目教程可参考:https://www.cnblogs.com/pyjblog/articles/14349370.html …

vue+element简单实现商城网站首页,模仿小米电商商城(一)

1.本案例灵感来源于小米官网 https://www.mi.com/ 项目演示地址:可私聊作者获取(演示地址不定时变化) 源码 官方截图 产品效果图: 二级菜单、产品详情 购物车 2.首先创建vue项目,采用开发工具Hbuilder。vue创建项目教程…

vue+elementui实现非常好看的博客、网站首页,网站模板

1.效果图,设计上美观大方 源码 2.首先创建vue项目,采用开发工具Hbuilder。vue创建项目教程可参考:(一)Vue——如何创建一个Vue项目(完整步骤) - 㭌(mou)七 - 博客园 3.创建项目后安装elementui…

vue+element简单实现商城网站首页,模仿电商商城

1.安装启动vue项目可参考 vueelement简单实现商城网站首页,模仿小米电商商城https://blog.csdn.net/lucky_fang/article/details/121544242 本项目源码下载https://download.csdn.net/download/lucky_fang/85161752 2.产品效果图 3.项目结构图 4.src/page/top/ind…

衣服、商品、商城网站模板首页,仿U袋网,vue+elementui简洁实现

1.本案例灵感来源于网络 项目演示地址:可私聊作者获取(演示地址不定时变化) 仿照来源:网络案例 以下源码是第一版源码,最新源码请私聊作者获取,或通过博客后面微信名片添加作者 源码https://download.c…

生鲜水果商品商城静态网站,vue+elementui简单实现

1.安装启动vue项目 (一)Vue——如何创建一个Vue项目(完整步骤) - 㭌(mou)七 - 博客园 2.elementui官网 Element - The worlds most popular Vue UI framework 3.如果你下载的是本项目源码,则步骤一中可以不用执行&a…

html+css响应式旅游主题网站模板,旅游网站,企业文化新闻类网站,简单web假期课程作业

1.灵感来源预览 社区、企业、公益共享交流平台_优享人app-优享时代官网 2.demo效果图,同时兼容手机端访问,所有菜单都已完善功能,即拿即用,很简单 源码下载https://download.csdn.net/download/lucky_fang/85320989 手机端访问…

web静态网站,css+html旅游景点网站,web假期作业

1.项目共分为8个网页: 首页、历史文化、景区概况、推荐游玩、美食一览、文化活动、地理位置、联系我们 纯csshtml实现的静态网页,很适合新手学习和使用, 源码下载 如下图,首页: 含背景音乐循环播放,自…

vue+elementui+springboot前后端分离实现学校帖子网站,模拟“淘柳职”学校大作业

一.技术实现 项目演示地址:可私聊作者获取(演示地址不定时变化) 前端 vueelementui; 后端: SpringBootOAuth2Spring SecurityRedismybatis-plusmysqlswagger 二.前言 淘柳职网站:淘柳职 本项目完全是…

程序猿最应去的网站有哪些?

2019独角兽企业重金招聘Python工程师标准>>> 要想成为优秀的程序猿,不仅要有一定天分,常与大神交流,自己多加练习才是正确的方法。下面是一些Quora用户推荐的国外网站,与广大程序猿或者希望学习编程的朋友们分享&#…

通过建立自己的AuthorizeAttribute实现网站的权限管理

2019独角兽企业重金招聘Python工程师标准>>> 当我们用.net MVC构建网站平台的时候,势必会对网站平台的安全性和用户的使用权限进行一个统一的构建,首先在.net MVC 架构中,系统已经将权限管理分为三个层面来进行管理,第…