一. 图片/视频加载缓慢优化
1. 图片优化
方案 | 实现方式 | 效果 |
---|
格式升级 | 使用 WebP/AVIF 格式(兼容性兜底用 <picture> 标签) | 体积减少 30%-70% |
响应式图片 | <img srcset="small.jpg 480w, large.jpg 1080w" sizes="(max-width: 600px) 480px"> | 按设备尺寸加载适配资源 |
CDN 动态压缩 | 通过 CDN 参数自动转换格式和质量(如 image.jpg?width=800&format=webp ) | 按需动态压缩,减少服务器压力 |
渐进式加载 | 先加载模糊缩略图(Base64 占位),再过渡到清晰图 | 用户即时感知内容存在 |
2. 视频优化
方案 | 实现方式 | 效果 |
---|
延迟加载 | 使用 preload="none" 或 IntersectionObserver 实现视口内自动加载 | 减少初始网络请求压力 |
分段加载 | HLS/DASH 流媒体技术分片传输 | 实现边播边载,提升体验 |
封面图占位 | 用海报帧(poster)替代视频首帧,视频点击后加载 | 节省首屏流量消耗 |
3. 首屏白屏问题根治
二. 防抖、节流
防抖(Debounce)
- 原理:事件触发后,等待固定时间,若期间无新触发,则执行函数;若期间有触发,重新计时。
- 适用场景:输入框搜索建议、窗口大小调整结束后的布局计算、防止重复提交按钮。
- 实现:
function debounce(func, wait, immediate = false) {
let timeout;
return function(...args) {
const context = this;
const later = () => {
timeout = null;
if (!immediate) func.apply(context, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
}
节流(Throttle)
- 原理:固定时间间隔内仅执行一次函数,无视期间的事件触发。
- 适用场景:滚动事件处理、鼠标移动(如拖拽)、游戏中的射击频率控制。
- 实现(结合立即执行与尾部执行):
function throttle(func, wait) {
let timeout, previous = 0;
const later = (context, args) => {
previous = Date.now();
timeout = null;
func.apply(context, args);
};
return function(...args) {
const now = Date.now();
const remaining = wait - (now - previous);
const context = this;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
func.apply(context, args);
} else if (!timeout) {
timeout = setTimeout(() => later(context, args), remaining);
}
};
}
对比与选择
特性 | 防抖(Debounce) | 节流(Throttle) |
---|
执行时机 | 事件停止后执行 | 固定间隔执行 |
适用场景 | 输入停止后搜索、窗口调整结束 | 滚动事件、实时鼠标位置更新 |
核心逻辑 | 重置等待计时器 | 判断时间间隔,控制执行频率 |
函数执行次数 | 只执行最后一次 | 均匀执行 |