<img>标签从入门到实战:性能、SEO、可访问性一篇讲透

更新日期: 2026-05-11 阅读: 77 标签: 标签

做前端开发,图片处理是最容易出问题的地方。很多人觉得图片不就是写个src就能显示吗?等上线以后才发现,页面加载慢、搜索抓不到、屏幕阅读器读不出来,甚至页面还会来回跳动。

先看一个最常见的写法:

<img src="/images/product-detail.jpg">

这段代码能跑,但问题不少:

  • 没有alt,盲人用户用屏幕阅读器时不知道这张图是什么

  • 没有width和height,图片加载时页面会突然跳动

  • 没有懒加载,列表页所有图片一次性全下载

  • 没有响应式图片,手机上也加载大尺寸原图

  • 图片文件太大,影响LCP(最大内容绘制)指标

开发环境下看不出来,一到弱网、手机端、搜索引擎抓取,这些问题全暴露了。


一、先把性能基础打好

下面是一个比较完善的图片写法:

<img
  src="/images/product-800.jpg"
  srcset="/images/product-400.jpg 400w,
          /images/product-800.jpg 800w,
          /images/product-1200.jpg 1200w"
  sizes="(max-width: 768px) 50vw, 33vw"
  alt="黑色降噪耳机"
  width="800"
  height="800"
  loading="lazy"
  decoding="async"
/>

每个属性的作用:

  • width和height:让浏览器提前知道图片占多大地方,避免图片加载后页面跳动

  • loading="lazy":图片滚动到可视区域才开始加载,节省流量

  • decoding="async":异步解码图片,不阻塞其他内容渲染

  • srcset和sizes:根据屏幕宽度加载不同尺寸的图片

注意:首屏的关键图片不要用懒加载。比如首页的大图,应该直接加载,不然LCP反而会更差。首屏图可以这样写:

<img
  src="/images/hero-1280.webp"
  alt="在线协作平台首页主视觉"
  width="1280"
  height="720"
  fetchpriority="high"
/>

fetchpriority="high"告诉浏览器这张图优先级高,要先加载。但不要给页面里十几张图都加这个属性,那就没意义了。


二、响应式图片,不同设备用不同尺寸

手机屏幕只有375像素宽,如果加载一张2000像素的大图,浏览器虽然能缩小显示,但流量浪费了。正确的做法是准备多个尺寸,让浏览器自己选。

<img
  src="/images/avatar-160.jpg"
  srcset="/images/avatar-80.jpg 80w,
          /images/avatar-160.jpg 160w,
          /images/avatar-320.jpg 320w"
  sizes="80px"
  alt="用户头像"
  width="80"
  height="80"
/>

用户的头像、商品缩略图、文章封面图都适合这样处理,图片体积能减少不少。

如果图片在不同屏幕下需要显示不同的裁剪区域,比如手机上看人和手机上方的标题文字,桌面版看完整的风景,这时候用<picture>更合适:

<picture>
  <source media="(max-width: 768px)" srcset="/images/banner-mobile.webp">
  <source media="(min-width: 769px)" srcset="/images/banner-desktop.webp">
  <img
    src="/images/banner-desktop.webp"
    alt="夏季活动宣传横幅"
    width="1200"
    height="500"
  >
</picture>

手机版和桌面版用两张不同的图,各自按合适的比例和构图来设计,比一张图硬缩要好得多。


三、SEO层面,图片不是摆设

很多人优化SEO只盯着标题和关键词,图片这块反而随便写写。实际上搜索引擎读不懂图片内容,全靠你提供的信息。

先说alt属性。别写成这样:

<img src="/images/a1.jpg" alt="图片">

这等于没写。alt应该描述这张图承载的信息:

<img src="/images/cover.jpg" alt="Node.js日志清洗流程示意图">

如果图片只是装饰性的,比如分割线、背景装饰,alt写空字符串就行:

<img src="/images/divider.svg" alt="">

注意:alt=""和直接不写alt不是一回事。不写alt,屏幕阅读器可能会把文件名、路径这些乱七八糟的东西读出来,体验很差。

文件名也有讲究。IMG_9483.JPG和noise-cancelling-headphones-black.jpg,哪个更容易被搜索引擎理解,不用多说。

如果项目里图片很多,建议封装一个统一的渲染函数:

const articles = [
  {
    title: 'img标签性能优化清单',
    cover: {
      src: '/images/img-guide-cover-800.webp',
      alt: 'img标签性能优化清单文章封面',
      width: 800,
      height: 450
    }
  }
];

function renderCover(cover) {
  return `
    <img
      src="${cover.src}"
      alt="${cover.alt}"
      width="${cover.width}"
      height="${cover.height}"
      loading="lazy"
      decoding="async"
    >
  `;
}


四、可访问性,不能最后才想起来补

alt首先是给人用的。图片加载失败时用户能看到提示,盲人用户靠屏幕阅读器读取。

判断标准很简单:这张图去掉以后,页面会丢失重要信息吗?

  • 会丢失 → 认真写alt

  • 不会丢失,只是装饰 → alt=""

  • 别省略这个属性

另外,按钮里如果只有图标没有文字,别这么写:

<button>
  <img src="/icons/search.svg">
</button>

屏幕阅读器读这个按钮,可能只读到“按钮”,用户不知道点下去是干什么。应该这样写:

<button aria-label="搜索">
  <img src="/icons/search.svg" alt="">
</button>

真正该被感知的是按钮的动作(搜索),不是里面那张放大镜图标。


五、项目里怎么统一规范,不靠人工盯

代码评审时一个一个图片去检查,很累而且容易漏。更好的办法是封一个组件:

function SmartImage({
  src,
  alt,
  width,
  height,
  lazy = true,
  priority = false
}) {
  const attrs = [
    `src="${src}"`,
    `alt="${alt ?? ''}"`,
    `width="${width}"`,
    `height="${height}"`,
    lazy && !priority ? 'loading="lazy"' : '',
    !priority ? 'decoding="async"' : '',
    priority ? 'fetchpriority="high"' : ''
  ].filter(Boolean).join(' ');

  return `<img ${attrs}>`;
}

调用的时候,首屏图和普通图分开处理:

// 首屏大图,优先级高
const hero = SmartImage({
  src: '/images/hero.webp',
  alt: '数据看板首页主视觉',
  width: 1280,
  height: 720,
  priority: true
});

// 普通卡片图,懒加载
const card = SmartImage({
  src: '/images/card-cover.webp',
  alt: '文章封面图',
  width: 320,
  height: 180
});


六、排查顺序,按这个来

页面图片多了以后,不要上来就怀疑CDN或者框架。按这个顺序检查:

  1. 首屏关键图是不是太大了

  2. 有没有加上width和height

  3. 该懒加载的是否懒了,不该懒的是不是误加了懒加载

  4. srcset有没有按屏幕尺寸下发合适的图片

  5. alt是不是认真写了,还是用“图片”两个字糊弄

  6. 装饰图有没有空alt,按钮里的图标有没有语义

<img>标签本身不复杂,复杂的是它同时连着性能、SEO、可访问性三条线。写得太随便,三条线一起扣分。写得仔细点,页面更稳、加载更快、语义也更干净。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

相关推荐

js动态添加html标签和属性_手动插入meta、script、div、img等标签

web网页是由 html标签一层层组成的,js也可以动态添加对应的标签,比如mate标签、script标签、div标签、img标签等,动态创建的方法基本都差不多,下面将简单介绍下如何实现

Html中a标签用法总结:创建email,电话,描点链接等。以及防止链接被搜索引擎收录

a标签是我们常用的一个标签之一,这篇文章主要讲解如何使用a来创建email,电话,描点链接等。以及防止链接被搜索引擎收录。

关于v-if和v-for不能一起使用在同一个标签上

遍历object的所有value(即li中的v-for),当拿到testData的第一个元素TESTOBJECT时,执行div中的v-for,此时的item对应T E S T O B J E C T这10个元素,于是循环10次,每一次都判断当前元素是否是array,很显然每次判断都是object

<script>标签的属性

src定义引用外部脚本的URI,这可以用来代替直接在文档中嵌入脚本。指定了 src 属性的script元素标签内不应该再有嵌入的脚本。type该属性定义script元素包含或src引用的脚本语言。

用css设置a标签无效,让链接跳转失效

这个代码有个坑,就是如果a标签里面放了一个图片,然后给a标签设置这个样式,这个时候是不起效果的,只能在a标签外面包一个div,然后给div设置这个样式

html的title和alt的区别

alt标签是html标签的属性,而title即使标签,又是标签的属性。 当title作为属性时,用来为元素提供额外的说明信息。当鼠标移入变迁内会显示title的内容,以达到补充说明或提示的效果。

video标签的属性

HTML5是下一代HTML,新增了许多新的标签,这些标签实现了许多新的功能。并且还减少了对外部插件的要求同时也可以更好的处理错误。比如HTML5中的video标签就可以很好的实现了在页面上播放视频的效果。

HTML中<base>标签的正确使用

<base> 标签必须位于 <head> 元素内部,在一个文档中,最多能使用一个 <base> 标签,使用了<base>标签的链接后,其他链接必须在<base>标签的链接里面,不然将无法找到。

html富文本的 ↵ 转为</br>标签

‘↵’是回车符/n,这段内容是通过textarea人为编辑,提交给后端保存的。编辑框中可以识别的字符,在普通的标签里面没办法识别到,所以要转换成可以识别的<br/>

web标签语义化的理解_web语义化是什么意思

Web语义化,使用语义恰当的标签,可以让页面具有良好的结构,页面元素具有良好的含义,从而让人和机器都能快速理解。语义化的web页面一方面可以让机器在更少的人类干预情况下收集并研究网页的信息,从而可以读懂网页的内容

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!