页面白屏时间优化
分析页面白屏的原因和优化方案
问题
用户打开页面后,从屏幕空白到显示第一个画面的时间过长,如何分析原因并进行优化?
解答
白屏产生的过程
从输入 URL 到页面显示的完整流程:
- 浏览器查找缓存(浏览器缓存 → 系统缓存 → 路由器缓存)
- DNS 解析获取 IP 地址
- 建立 TCP 连接(三次握手)
- 发送 HTTP 请求
- 服务器处理请求并返回响应
- 浏览器接收 HTML 并开始解析
- 构建 DOM 树和 CSSOM 树
- 生成渲染树并绘制页面
浏览器渲染机制
浏览器下载 HTML 后,首先解析头部代码进行样式表下载,然后构建 DOM 树。当 DOM 树构建完成后,立即开始构造 CSSOM 树。理想情况下两棵树并行构建,完成后生成渲染树并绘制。
需要注意的阻塞情况:
- 内联 JS 代码会阻塞 DOM 树的构建
- CSS 文件未下载完成时,会阻塞 JS 的执行
- JS 执行被阻塞时,HTML 解析也会暂停
优化方案
DNS 解析优化
- 启用 DNS 缓存
- 使用 DNS 预解析:
<link rel="dns-prefetch" href="//example.com"> - 选择稳定可靠的 DNS 服务器
服务端优化
- 使用 Redis 缓存
- 数据库查询优化
- 启用 Gzip 压缩
- 优化服务器响应时间
资源加载优化
- 精简 HTML 代码和结构
- 优化 CSS 文件,移除无用样式
- 将关键 CSS 内联到 HTML 中
- JS 代码放在
</body>前,避免使用内联 JS - 延迟加载首屏外的图片
图片懒加载实现
// 获取屏幕可视区域高度
const viewHeight = document.documentElement.clientHeight;
// 判断元素是否在可视区域
function isInViewport(element) {
const offsetTop = element.offsetTop;
return offsetTop < viewHeight;
}
// 懒加载图片
function lazyLoad() {
const images = document.querySelectorAll('img[data-src]');
images.forEach(img => {
if (isInViewport(img)) {
img.src = img.dataset.src;
img.removeAttribute('data-src');
}
});
}
关键点
- JS 会阻塞 DOM 构建,CSS 会阻塞 JS 执行,需要合理安排资源加载顺序
- 将关键 CSS 内联到 HTML 中可以加快首屏渲染
- 优先加载首屏内容,延迟加载首屏外的图片和资源
- DNS 解析和服务器响应时间是白屏时间的重要组成部分
- 减少 HTML、CSS、JS 文件体积,启用压缩可以缩短下载时间
目录