- Published on
从负一步开始的性能优化
- Authors
- Name
- hpoenixf
引言
两年前,我写过一篇关于性能优化的文章,其中提到性能优化要先对页面性能进行记录,并按照页面访问的整个流程分步骤进行优化。
如今,两年过去了,我在阿里学习到了一些新的优化方法,对性能优化也有了更多的思考。性能优化的时机其实可以更早,从用户即将访问页面的那一刻就可以开始优化。以下是按照时间顺序整理的性能优化方法:页面访问前、页面加载中、页面运行时。
页面访问前的性能优化
推送资源:
- 将 JS、图片、多媒体文件等页面资源预先推送到客户端/浏览器。
预加载:
- prefetch:预加载可能使用的资源。
- preload:优先加载必要的资源。
- prerender:预渲染整个页面。
提前打开 WebView 容器:
- WebView 容器的加载需要时间,可以提前加载容器以节省时间。
预请求 AJAX:
- 提前获取下个页面所需的 AJAX 数据,并缓存到
localStorage
。
- 提前获取下个页面所需的 AJAX 数据,并缓存到
页面加载过程中的性能优化
查询强缓存
- 使用 Service Worker:拦截请求,缓存资源。
- 配置强缓存:使用 Cache-Control 和 ETag。
DNS 解析优化
- 域名收敛:减少 DNS 查询次数。
- 使用 HTTPDNS:避免运营商劫持。
- DNS 预解析:
<link rel="dns-prefetch" href="https://domain.com">
加速资源下载
- 使用 CDN:加速资源加载,减少网络延迟。
- 开启 HTTP/2:支持多路复用。
- Keep-Alive:保持长连接。
- 域名发散:突破并发请求限制。
代码打包与优化
- 使用雪碧图:减少 HTTP 请求。
- 小图片使用 Base64:免去额外的请求。
服务器响应优化
- 减少重定向:使用 301 或 302。
- 强制 HTTPS:使用 HSTS。
- 启用 Gzip 或 Brotli:压缩传输资源。
- 使用更高效的格式:如 WebP。
HTML 解析与渲染
- JS 加载优化:
- 将
<script>
放在底部。 - 使用
defer
或async
加载 JS。
- 将
- CSS 优化:
- 减少选择器嵌套。
- 优化关键 CSS。
- 减少 DOM 操作:
- 减少嵌套层级和 DOM 数量。
- 避免频繁重绘重排。
白屏优化
- 骨架屏:在页面加载完成前展示占位内容。
- 服务器渲染:使用 SSR 提前生成 HTML。
数据接口优化
- 本地缓存:将时效性不强的数据缓存到
localStorage
。 - 提前请求接口:通过 URL 参数或配置文件实现。
页面运行时的性能优化
帧率监控
- 使用
requestAnimationFrame
(RAF)记录 FPS,监控页面流畅度。
启用 GPU 加速
- 构建合成层:
- 使用
will-change
优化如opacity
和transform
的动画。 - 使用
transform: translateZ(0)
开启 GPU 加速。
- 使用
- 减少重绘和重排:
- 避免频繁操作样式和 DOM。
- 使用
class
代替直接操作style
。 - 批量操作脱离文档流的元素。
滚动优化
- 虚拟滚动:使用虚拟列表优化无限加载。
- 事件优化:
- 滚动监听使用节流/防抖。
- 使用事件代理减少绑定的监听器。
动画优化
- 使用虚拟 DOM:减少真实 DOM 的操作。
- RAF 替代定时器:用
requestAnimationFrame
实现流畅动画。
资源加载优化
- 针对低性能设备进行降级处理:
- GPU 嗅探:使用 WebGL 检测 GPU 型号。
- UA 分析:通过 User-Agent 获取设备信息。
- 分辨率适配:根据设备分辨率提供不同的体验。
总结
按时间顺序划分的性能优化策略
- 页面访问前:通过资源推送、预加载和预请求降低加载时间。
- 页面加载中:从 DNS 优化到资源压缩,全方位提升页面加载速度。
- 页面运行时:关注动画、滚动优化和事件管理,保证页面的流畅交互。
性能优化的核心
性能优化贯穿于整个开发周期,从用户尚未访问页面时就开始,到页面运行时的细节调优。通过结合前沿技术和合理的策略,可以显著提升用户体验。
性能优化是一个持续的过程,期待与大家交流更多实践经验。