前端图片 img 深度解析

7 阅读4分钟

前端开发里,图片加载看似简单实则藏着大学问。选对加载方式不仅能提升页面性能,还能优化用户体验,今天就来聊聊 img 标签和 new Image 该怎么选。

浏览器加载图片的核心逻辑

img 标签

img 标签插入 DOM 后,浏览器会立刻启动资源请求。它自带很多实用特性,不用额外写复杂代码就能实现优化。

可以通过 alt 属性支持无障碍访问,让辅助工具能识别图片内容。配合 srcset 和 sizes 属性,浏览器能根据屏幕尺寸自动选择合适分辨率的图片,兼顾清晰和性能。加上 loading="lazy" 能让非首屏图片滚动到视口再加载,减少初始请求压力。decoding="async" 则能让图片在浏览器空闲时异步解码,避免阻塞页面渲染。

给首屏关键图加 fetchpriority="high",能提示浏览器优先加载,降低最大内容绘制时间。同时显式声明 width 和 height,或者用 aspect-ratio 样式预留占位,能有效避免布局偏移。如果需要兼容不同图片格式,用 picture 标签搭配多个 source 元素,再加上 img 标签兜底,就能实现现代格式优先、老旧格式兼容的效果。

new Image

new Image 创建的是独立的图片元素,默认不会发起网络请求,只有设置了 src 或 srcset 后才会开始加载。因为没插入 DOM,浏览器会给它分配较低的网络优先级,不会和关键资源争抢带宽。

开发者可以利用这个特性做预加载,等图片加载完成并解码后,再插入 DOM,这样能减少渲染时的布局抖动。而且通过 new Image 加载的图片会进入浏览器缓存,后续其他地方使用相同资源时,能直接复用缓存,提升加载速度。

什么时候该用 new Image

  1. 需要精准控制加载时机时,比如把非首屏图片的下载放在首屏稳定后,用 requestIdleCallback 或 setTimeout 延迟触发,让关键资源优先加载。
const onIdle = (fn) =>
  window.requestIdleCallback ? requestIdleCallback(fn) : setTimeout(fn, 0);

onIdle(() => {
  const img = new Image();
  img.src = "/next-section/banner.avif";
});
  1. 提前加载并解码,再插入 DOM。先通过 width、height 或 aspect-ratio 预留布局位置,避免布局偏移,加载解码完成后再替换容器内容,让插入过程更丝滑。
  2. 缓存预热场景,比如列表跳转详情、缩略图放大、轮播图下一张等。提前预加载图片,用户触发操作时能瞬间显示,减少等待感。
  3. 需要精细错误处理时,通过捕获加载错误,直接使用备用图片,避免页面出现破损图片的情况。

什么时候优先用 img 标签

  1. 首屏关键图片,尤其是影响最大内容绘制的图片,直接用 img 标签写在 DOM 里,让浏览器以最高优先级加载,不用依赖 JS 执行,避免拖慢首屏渲染。
  2. 图片需要语义支持或 SEO 优化时,img 标签的 alt 属性、配合 figure 和 figcaption 的语义包装,能让搜索引擎更好地识别图片内容,也能满足无障碍访问需求。
  3. 非首屏图片数量较多时,用 img 标签的原生懒加载属性,配合异步解码,就能高效控制加载时机,不用额外编写复杂的预加载逻辑。
  4. 担心 JS 执行失败或延迟的场景,纯 img 标签能确保图片正常渲染,还可以搭配 noscript 标签做兜底,避免页面出现空白。

总结

img 标签的优势是自带语义和无障碍支持,浏览器能自动优化加载优先级,配置简单直接,适合大多数直接展示的图片场景,尤其是首屏关键内容和需要 SEO 的图片。

new Image 更适合需要手动控制加载时机、预加载缓存、精细处理加载状态的场景,能帮助开发者优化非关键图片的加载体验,避免影响核心内容的渲染。

实际开发中可以根据图片的重要性、加载时机和功能需求灵活选择,必要时二者结合使用,既能保证首屏性能,又能优化后续交互的图片加载体验。

海云前端丨前端开发丨简历面试辅导丨求职陪跑