当前位置: 首页 > 科技观察

Web图片组件设计优秀实践

时间:2023-03-11 22:19:42 科技观察

大家好,我是ConardLi。网页中的图像处理一直是Web开发中的主要挑战。今天,我们就来看看Next.js中的Image组件。我觉得这个组件的设计有很多值得借鉴的地方,可以作为图像组件设计的一个很好的实践。英文原文在这里:https://web.dev/image-component/这篇文章会涉及到一些网页性能指标。没看懂的同学可以先看我的文章:网页中图片引起的主要问题和问题优化网页中的图片不仅会影响网页的性能,还可能影响业务。网页加载的图片数量是影响用户访问网站转化率的第二重要因素。作为网页最佳实践检查的一部分,Lighthouse列出了各种优化图片加载的建议,例如:未指定尺寸的图片会降低CLS未指定图片的宽度和高度会导致布局不稳定和原因布局转移指标(CLS)恶化。在img元素上设置width和height属性可以优化这个问题,例如:宽高应该设置的更接近width和图像本身的高度进行比较。差异太大会导致图像看起来失真。使用CSS新添加的纵横比属性来帮助您以更灵敏的方式调整图像大小。图像太大可能会影响LCP图像文件越大,下载时间越长。网页中的大图形可能是触发最大内容绘制指标(LCP)的最重要元素。图片是网页关键内容的一部分,下载时间长,肯定会降低网页的LCP。在许多情况下,开发人员可以通过更好的压缩或使用响应式图像来减小图像大小。元素的srcset和sizes属性可以指定不同大小的图像文件。然后浏览器可以根据屏幕大小和分辨率有选择地加载它。不良的图像压缩会影响LCPAVIF或WebP等现代图像格式可以提供比JPEG和PNG等常用格式更好的压缩。在某些情况下,更好的压缩可以将相同质量图像的文件大小减少25%到50%。这种大小的减小导致更快的下载和更少的数据消耗。加载不必要的图像可能会影响LCP加载网页时,可以延迟用户在首屏上看不到的图像,以免影响LCP。图像优化的主要挑战我们在上面列出了主要问题和优化方向。事实上,由于一些问题,并非所有网站都能进行这些优化,例如:优先级:Web开发人员可能通常更喜欢专注于代码、JavaScript和数据优化。大多数前端可能不知道图像的主要问题以及如何优化它们。开箱即用的解决方案:即使我们意识到这些问题,但我们的研发框架可能会有一些开箱即用的解决方案,这将大大增加优化成本。图片动态加载:除了我们开发时引入的一些图片外,有些图片可能是用户上传的。当图像源是动态的时,定义此类图像的大小可能很困难。浏览器支持AVIFWebP懒加载的复杂性:实现懒加载的方式有很多种,那么至少哪种方式最适合你的网页呢?不同设备上的不同视口大小也会使问题复杂化。Image组件最佳实践在过去的一年里,我们使用Next.js框架设计并实现了Image组件。它可以替代Next.js中的元素,这里是一个用法示例://Beforewithelement:functionLogo(){return}//Afterwithimagecomponent:importImagefrom'next/image'functionLogo(){return}组件提供了一套丰富的函数和原理来解决图像相关的问题。它还允许开发人员配置选项以根据各种图像要求对其进行自定义。防止布局更改如上所述,未指定宽度和高度的图像会导致布局不稳定并导致更差的布局偏移指标(CLS)。使用Next.jsImage组件时,开发人员必须使用宽度和高度属性指定图像大小,以防止任何布局偏移。如果大小未知,开发人员必须指定layout=fill以在容器内提供未知大小的图像。//Imagecomponentwithwidthandheightspecified//Imagecomponentwithlayoutspecified//ImagecomponentwithimageimportimportImagefrom'next/image'importlogofrom'./codeSecretGarden.png'functionLogo(){return}使图片响应为For跨设备适配,开发者必须在元素中设置srcset和sizes属性。如果您使用Image组件,则不必执行此工作。Next.js中的Image组件可以有一个全局的图片设置,可以根据布局方式应用于Image组件的所有实例,有以下三个属性:deviceSizes属性:该属性可以用于基于常见设备的在应用程序用户群上一次配置断点。imageSizes属性:这也是一个可配置的属性,用于获取设备尺寸断点对应的图像尺寸。layoutdeviceSizesimageSizesfixed,fill,intrinsicresponsive当使用fill或responsive布局模式加载图片时,Next.js会根据请求页面的设备大小来识别要提供的图片,并适当设置srcset和sizes。下面的示例展示了如何使用布局模式来控制不同屏幕上的图像大小。Layout=Intrinsic:缩小以适应较小视口上容器的宽度。在更大的视口上放大时,不会超过图像的固有尺寸,容器宽度为100%Layout=Fixed:不管是什么设备,宽高都是固定的。Layout=Responsive:根据容器在不同视口上的宽度收缩或扩展,保持宽高比。Layout=Fill:宽高自动填充父容器懒加载Image组件默认提供了一个内置的、高性能的懒加载方案。元素有一些默认的延迟加载方案,但是它们都有很多缺点,使用起来也很麻烦。我们可能会使用以下一种懒加载方式:指定加载属性:实现简单,但兼容性差使用IntersectionObserverAPI:设计自定义的懒加载方案需要深思熟虑的设计和实现,并不是所有的开发者都有时间和精力做这样的设计。第三方懒加载库:您需要一些时间来选择和评估这些库。在Next.js的Image组件中,图片的默认设置是Lazy。懒加载是使用IntersectionObserver实现的,兼容性好。我们不需要做任何额外的事情来启用它,但是我们可以根据具体场景选择禁用它。预加载如上所述,图像的文件越大,下载所需的时间就越长。网页中的大图像可能是触发最大内容绘制指标(LCP)的最重要元素,预加载一些大图像可能是个好主意。使用元素时,HTML标头中可能包含预加载提示:无论使用何种框架,设计良好的图像组件应该提供一种方法来调整图像的加载顺序。在Next.jsImage组件中,开发者可以使用priority属性来指明哪些图片适合预加载。推荐CDN托管图片Next.jsImage默认使用loader架构处理图片,你可以自定义用于配置图像的CDN前缀。module.exports={images:{loader:'imgix',path:'https://ImgApp/imgix.net',},}通过这个配置,开发者可以在加载图片的时候使用相对路径,框架会拼接相对路径带有CDN路径的路径以生成绝对URL。目前支持Imgix、Cloudinary、Akamai等主流图片CDN。此架构支持通过加载器为应用程序使用自定义CDN提供商。渐进式加载所谓渐进式加载,就是在加载实际图片时先显示质量较差的占位图片。它可以与延迟加载结合使用,以提高感知性能并增强用户体验。Next.jsImage组件支持通过placeholder属性渐进式加载图像,该属性用于在加载实际图像时显示低质量或模糊的图像。效果下面是leboncoin使用Image组件后的优化效果:LCP从2.4s下降到1.7s,页面下载的图片资源总大小从663kB增加到326kB(懒加载图片大小约100kB).