跳到主要内容

图像和多媒体✅

图片优化策略?

答案

图片优化是提升网站性能和用户体验的关键策略,主要从格式选择、压缩处理、加载策略和现代技术四个维度进行。

图片格式选择

格式压缩算法透明度文件大小浏览器支持适用场景
JPEG有损压缩不支持全部照片、复杂图像
PNG无损压缩支持全部图标、简单图形
WebP有损/无损支持最小现代浏览器通用替代方案
AVIF先进压缩支持极小部分浏览器未来标准

压缩与构建优化

// Webpack 图片优化配置
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif|webp)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192, // < 8KB 转 base64
name: '[name].[contenthash].[ext]',
outputPath: 'images/'
}
},
{
loader: 'image-webpack-loader',
options: {
mozjpeg: { quality: 80, progressive: true },
pngquant: { quality: [0.65, 0.8] },
webp: { quality: 75 }
}
}
]
}
]
}
}

现代加载策略

<!-- 1. 响应式图片 -->
<picture>
<source media="(min-width: 1200px)" srcset="large.webp" type="image/webp">
<source media="(min-width: 768px)" srcset="medium.webp" type="image/webp">
<img src="small.jpg" alt="响应式图片" loading="lazy">
</picture>

<!-- 2. 懒加载 -->
<img class="lazy" data-src="image.jpg" alt="懒加载图片">

<!-- 3. 预加载关键图片 -->
<link rel="preload" as="image" href="hero-image.jpg">

JavaScript 实现懒加载

// Intersection Observer 懒加载
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target
img.src = img.dataset.src
img.classList.remove('lazy')
observer.unobserve(img)
}
})
})

document.querySelectorAll('.lazy').forEach(img => {
imageObserver.observe(img)
})

// 渐进式加载
function progressiveLoad (placeholder, highRes) {
const img = new Image()
img.onload = () => {
placeholder.src = highRes
placeholder.classList.add('loaded')
}
img.src = highRes
}

现代优化技术

/* CSS 优化 */
.image-container {
/* 内容可见性优化 */
content-visibility: auto;
contain-intrinsic-size: 300px 200px;
}

.lazy-image {
/* 平滑过渡效果 */
opacity: 0;
transition: opacity 0.3s;
}

.lazy-image.loaded {
opacity: 1;
}

/* 响应式图片优化 */
.responsive-image {
width: 100%;
height: auto;
object-fit: cover;
}

实际开发建议

  • 格式优先级 WebP > JPEG > PNG,提供 fallback
  • 尺寸控制 根据显示尺寸提供合适的图片大小
  • CDN 加速 使用 CDN 分发图片资源
  • 缓存策略 设置合理的缓存头,启用浏览器缓存
  • 监控优化 使用 Core Web Vitals 监控图片加载性能
提示

优化顺序:选择合适格式 > 压缩处理 > 懒加载实现 > 响应式适配 > 性能监控

延伸阅读

图片懒加载原理?

答案

图片懒加载是一种性能优化技术,通过延迟加载视口外的图片来减少初始页面加载时间和带宽消耗。

核心原理

懒加载的核心思想是将图片的真实URL存储在自定义属性中(如 data-src),当图片进入或即将进入视口时,再将URL赋值给 src 属性触发加载。

实现方式对比

方式优势劣势适用场景
Intersection Observer性能优异,异步处理兼容性稍差(IE不支持)现代浏览器项目
滚动监听兼容性好频繁触发影响性能需要兼容老浏览器
原生 loading="lazy"零代码实现兼容性有限,功能简单简单场景快速实现

Intersection Observer 实现

// 现代化的懒加载实现
class LazyImageLoader {
constructor (options = {}) {
this.options = {
rootMargin: '50px',
threshold: 0.1,
...options
}
this.observer = this.createObserver()
}

createObserver () {
return new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
this.loadImage(entry.target)
this.observer.unobserve(entry.target)
}
})
}, this.options)
}

loadImage (img) {
const src = img.dataset.src
if (src) {
img.src = src
img.classList.remove('lazy')
img.classList.add('loaded')
}
}

observe (selector = '.lazy') {
document.querySelectorAll(selector).forEach(img => {
this.observer.observe(img)
})
}
}

// 使用示例
const lazyLoader = new LazyImageLoader({
rootMargin: '100px' // 提前100px加载
})
lazyLoader.observe()

滚动监听实现(兼容性方案)

// 防抖优化的滚动监听
function createLazyLoader () {
let timeout

function checkImages () {
const images = document.querySelectorAll('.lazy')
const windowHeight = window.innerHeight
const scrollTop = window.pageYOffset

images.forEach(img => {
const rect = img.getBoundingClientRect()
// 提前200px开始加载
if (rect.top <= windowHeight + 200) {
img.src = img.dataset.src
img.classList.remove('lazy')
}
})
}

function handleScroll () {
if (timeout) clearTimeout(timeout)
timeout = setTimeout(checkImages, 100)
}

window.addEventListener('scroll', handleScroll)
checkImages() // 初始检查
}

createLazyLoader()

HTML 结构优化

<!-- 占位符优化,避免布局抖动 -->
<div class="image-wrapper" style="aspect-ratio: 16/9;">
<img
class="lazy"
data-src="high-quality.jpg"
src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1 1'%3E%3C/svg%3E"
alt="图片描述"
loading="lazy"
>
</div>

<!-- 渐进式加载 -->
<img
class="lazy progressive"
data-src="full-resolution.jpg"
src="low-quality-placeholder.jpg"
alt="渐进式加载图片"
>

CSS 增强效果

.lazy {
opacity: 0;
transition: opacity 0.3s;
}

.lazy.loaded {
opacity: 1;
}

/* 加载动画效果 */
.image-wrapper {
position: relative;
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
background-size: 200% 100%;
animation: loading 1.5s infinite;
}

@keyframes loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}

性能优化建议

  • 预加载距离 设置合理的 rootMargin 值,平衡用户体验和性能
  • 图片优化 结合响应式图片和现代格式(WebP、AVIF)
  • 占位符设计 使用固定宽高比避免布局抖动
  • 错误处理 添加图片加载失败的降级方案
提示

推荐使用 Intersection Observer API,它在主线程之外异步执行,不会阻塞页面渲染,性能更优。

延伸阅读

48%