Astro初体验
初体验的问题
作为一个前端新手,我决定用 Astro 框架重构个人博客。听说它的静态生成能力和 Partial Hydration 特性可以让网站又快又省资源,这对我这种追求极简的写作者来说简直完美。本地开发时一切顺利,热更新响应迅速,Markdown 渲染流畅。但当我部署到 Vercel 后,用户反馈点击文章链接需要等待 3-5 秒才能看到内容。整个跳转给我的感觉就是卡卡的 —— 明明用了静态站点生成,为什么会有这个诡异的延迟?
打开 Network 面板重新加载页面,发现:
HTML 文件加载仅需 100ms,但主内容渲染延迟了 2.3s;页面加载时触发了多个;Hydration 事件客户端 ;JS 体积达到 420KB…
然后我大概就知道问题在哪里了。
简单地说你可以理解为,本来一次点击,浏览器从A页面跳转到B页面,无论是A页面的消失还是B页面的逐步呈现,这个过程都没有被忽略。Astro的部分渲染,在B页面被完全加载出来之前都停留在A页面,他需要等待B页面的不同内容加载之后刷新视图,呈现B页面的内容。
另外我发现这个特行可以让你实现类似Android里的共享元素的炫酷效果。
我意识到问题可能与 Astro 的核心特性有关:
1. 过度使用客户端组件
在文章页模板中,我为了实现 “阅读进度条” 功能,错误地使用了client:load指令:
<!-- 错误示范 --> <ReadingProgress client:load />
这导致整个组件在页面加载时立即执行 Hydration,阻塞了主线程。
2. 动态路由的 Hydration 策略
我的文章路由采用动态参数[slug].astro,默认配置下:
// astro.config.mjs(原配置) export default defineConfig({ experimental: { islands: false } });
这导致 Astro 在客户端重新渲染整个页面,而非仅更新必要部分。
3. 资源加载未优化
未压缩的图片平均大小 300KB;未启用 Gzip;第三方字体文件阻塞渲染。
这里图片我是引用的第三方图库,虽然没有加preload,但是速度其实还算可以。不过多张图片引用也会影响速度。
尤其要说一下这个字体,我最开始测试的,google fonts的访问速度怎么会比loli.net要快这么多?难道是国内也有服务器?
后来我发现了问题。
google fonts引用的css,是切割好的字体文件。也就是这个css可以理解为是一个目录,里面有分好包的实际字体文件(目前常用方法),然后这个css会分批引用实际字体文件。给👴🏻整无语了。一整个页面就在那里等它这个字体加载。
系统性优化方案
经过调试,我逐步实施了以下解决方案:
1. 组件 Hydration 策略优化
<!-- 正确写法:仅当滚动到可见区域时Hydrate --> <ReadingProgress client:visible /> <!-- 完全静态组件 --> <ArticleMeta server />
2. 配置调整
3. 资源加载优化
使用astro-imagetools自动压缩图片。其实直接添加懒加载就可以了。
4. 给所有二进制文件添加preload
优化后数据
- 优化后:首字节时间(TTFB)从 800ms 降至 120ms
- 最大内容渲染时间(LCP)从 2.8s 降至 700ms
- 客户端 JS 体积减少至 180KB(js问题不大)
最后
静态站点生成不等于自动高性能
前端性能优化需要系统性思维
Astro 的强大在于合理利用其特性,而非盲目使用
现在,我的博客不仅加载速度提升了,Lighthouse 98 XD。
更重要的是,我学会了如何通过 Chrome DevTools 和 Astro 内置工具进行性能分析。如果你也遇到类似问题,可以参考一下我上面的方案。(避雷Google fonts)