TodoList应用:SPA应用首屏性能优化实践

hello,大家好,我是唐叔,今天想介绍的是 SPA - 单页应用的首屏性能问题优化的一些实践,也是我理解的 SPA 应用最大的技术难点吧。

SPA 的优势很明显:一次加载,无缝交互,适合多端复用。但代价也很大------首屏需要加载所有资源,一旦代码庞大,白屏时间就会变长。这就是我们常说的"首屏性能问题"。

下面就以唐叔最近一直在开发的 TodoList 应用为例,分享几种优化手段。

优化方式 1:骨架屏

严格说,骨架屏并不是优化性能,而是优化用户体验。

在数据加载完成前,先展示一个灰色的"页面轮廓",避免用户面对白屏。

第一步,前端 html 页面,在 HTML 中预留骨架屏结构,具体可以基于你原本页面的框架去处理:

第二步,在编写 JS 初始化操作时,先显示骨架屏,然后加载数据,加载完数据再隐藏骨架屏。

大体编码是这样的:

javascript 复制代码
class App {
	   // 初始化应用
    async init() {
        try {
	          // 显示加载状态
		 Utils.setLoading(true);
            // 加载数据
        } catch (error) {
            // 异常报错
        } finally {
            // 隐藏加载状态
            Utils.setLoading(false);

            // 隐藏骨架屏
            const skeletonScreen = document.getElementById('skeleton-screen');
            if (skeletonScreen) {
                skeletonScreen.style.display = 'none';
            }
        }
    }
}

document.addEventListener('DOMContentLoaded', () => {
    // 显示骨架屏
    const skeletonScreen = document.getElementById('skeleton-screen');
    if (skeletonScreen) {
        skeletonScreen.style.display = 'flex';
    }

    // 延迟初始化,确保所有资源加载完成
    setTimeout(() => {
        app.init();
    }, 100);
});

额外建议:现在的开发更多是"思路驱动实现",你可以用 AI 快速生成骨架屏代码,前提是你清楚它的原理。

优化方式 2:前端缓存

缓存虽然对首次加载无效,但对二次打开提升巨大。

常见前端存储方式主要有下述几类:

存储方式 容量 持久性 异步/同步 数据结构 同源限制
Cookie ~4KB 可设置 同步 字符串 是
localStorage 5-10MB 永久 同步 字符串 是
sessionStorage 5-10MB 会话级 同步 字符串 是
IndexedDB >250MB 永久 异步 结构化 是
Cache API 不定 永久 异步 Request/Response 是
FileSystem 不定 永久 异步 文件 是

在 TodoList 中,我们使用 localStorage 存储用户偏好(如主题、语言)。如果你开发的是轻量化应用,完全可以用 IndexedDB 作为整个应用的数据存储层。

💡 不过要补充说明的是,上述各类存储方式,可能存在浏览器兼容性问题 。像 TodoList 用的后端是 pywebview,开启 localStorage 通过配置 private_mode。

优化方式 3:路由懒加载

SPA 首屏并不需要加载所有页面模块时,可以把部分组件延迟到用户访问时再加载。

在 TodoList 移动端中,我正在做将「左侧抽屉弹窗」改为懒加载,等用户点击时再加载对应数据,减少首屏负担。

优化方式 N:其他策略

上述几种方式,是目前 TodoList 应用主用的优化方式,当然还有其他的方式,这里以我了解到的做展开介绍,当前不是专业前端可能了解的不多,其他同学知道的其他方式也可以在评论区补充说明。

  • 静态资源懒加载

    和路由懒加载类似,类似图片等高占用体积的资源,可以考虑使用这种方式,不过像 TodoList 应用,前端和后端都是写在一个包里面的,没有纯粹的后端服务,貌似用不了。

    html 复制代码
    <img src="placeholder.jpg" data-src="real-image.jpg" loading="lazy" />
  • Gzip 压缩

    现代构建工具(如 Webpack、Vite)会自动生成压缩后的代码包,服务端开启 Gzip 后即可生效,显著减少传输体积。不过 TodoList 是纯 HTML/CSS/JS 页面,估计还真的不好用这种方式。


以上是 TodoList 项目中正在实践的首屏优化策略。作为本专栏的开篇,希望能帮你少踩一些坑,也欢迎大家在评论区补充你常用的优化方式。

相关推荐
前进前进前进26 分钟前
TRAE 全链路实战:做了一个警示牌一键生成器:纯 Canvas、单文件、零依赖
前端
小万7421 小时前
God‘s Eye View 深度解析:15 路公开信号 + CesiumJS 的浏览器级 OSINT 控制台,60 帧渲染的“真实间谍卫星模拟器”
前端
IT星宿2 小时前
浏览器标签页全是一个图标:我用名字哈希生成 favicon,让每个项目都有身份标识
前端
OpsEye2 小时前
大模型账单对账难:不同厂商 Token 统计口径差异怎么处理
javascript·ai编程
全栈项目管理程序猿2 小时前
ArcGIS JS 基础教程(32):体元系列 - VoxelSlice 体元切片
前端·javascript
拖孩4 小时前
AI 帮我写的小程序「厨菜记」上线满月了,挣了两百块!!!
前端·后端·微信小程序
用户360055579004 小时前
Kestrel_VLLM - 13 · 为什么排除 MoE FFN Tiling 与 Tensor Core
前端
Hilaku4 小时前
AI 流式输出都用 SSE,什么时候必须换 WebSocket?
前端·javascript·程序员
奇牙coding4 小时前
Codex CLI 升级后多文件编辑静默失效:config.yaml 枚举变更排查与修复指南
java·前端·javascript·ai
小羊没烦恼!4 小时前
Ajax与JSON的一些总结
android·java·前端·数据库·mysql·算法·okhttp