构建极致体验的原生 JS 单页应用
在现代 Web 开发中,React、Vue 和 Angular 等重型框架几乎主导了市场。然而,在追求极致性能、免构建流程的轻量级博客、文档站或 wiki 场景下,使用原生 JavaScript 构建单页应用 (SPA) 反而能带来惊人的效果。
本文将深入分析如何不借助第三方构建工具,仅用原生 HTML、Vanilla CSS 和现代 ES Modules,构建一个丝滑、响应式且功能完备的单页博客应用。
为什么选择原生 JavaScript?
- 零构建步骤 (Zero Build Steps):直接在浏览器中运行,无需 Webpack、Vite 或 Babel。修改完代码刷新浏览器即可,部署时只需静态托管,毫无心智负担。
- 极速载入 (Fewer Bytes):没有数十 KB 的框架 runtime。首屏加载只需传输极少的原生代码,配合浏览器的强缓存,速度达到极致。
- 彻底掌控:没有隐式的渲染机制(如 React 的 Fiber 或 Vue 的响应式收集),你能够精确掌握每一次 DOM 更新和重排的时机。
核心技术实现:哈希路由器 (Hash Router)
在 SPA 中,我们需要在不刷新整个页面的前提下改变 URL 并更新视图。在原生 JS 中,利用浏览器的 hashchange 事件是实现这一功能最安全、兼容性最好的方法。
下面是一个优雅的单页路由器实现:
// js/router.js
export class Router {
constructor(routes) {
this.routes = routes;
window.addEventListener('hashchange', () => this.resolve());
window.addEventListener('load', () => this.resolve());
}
resolve() {
const hash = window.location.hash || '#/';
const path = hash.replace(/^#/, '');
const matchedRoute = this.routes.find(route => {
// 简单匹配路由模式
return route.path === path;
});
if (matchedRoute && matchedRoute.action) {
matchedRoute.action();
} else {
console.warn('404 Route not found:', path);
}
}
}
CSS 变量的魔力
使用 CSS 变量,我们可以在运行时动态改变整个站点的视觉系统。例如,仅需数行代码即可实现令人赞叹的深色/浅色模式切换:
:root {
--bg-primary: #ffffff;
--text-primary: #1e293b;
}
[data-theme="dark"] {
--bg-primary: #0f172a;
--text-primary: #f8fafc;
}
body {
background-color: var(--bg-primary);
color: var(--text-primary);
transition: background-color 0.25s, color 0.25s;
}
然后在 JavaScript 中进行切换:
// 切换暗黑模式
const toggleTheme = () => {
const current = document.documentElement.getAttribute('data-theme');
const next = current === 'dark' ? 'light' : 'dark';
document.documentElement.setAttribute('data-theme', next);
};
性能表现对比
以下是原生 Vanilla 架构与传统现代框架构建包在博客文档场景下的对比:
| 指标 (Metrics) | Vanilla JS SPA | React App (Next.js) | Gatsby 静态站 |
|---|---|---|---|
| 首包大小 (JS Bundle) | ~12 KB | ~180 KB | ~220 KB |
| Lighthouse 性能得分 | 100 / 100 | 82 / 100 | 91 / 100 |
| 部署依赖 | 纯静态托管 | Node 服务 / 编译构建 | 编译构建 |
提示: 并不是说大型框架不好,而是在特定的场景(如自用博客、知识库)下,原生 Vanilla CSS 和 JS 能把简单美学和极客效率发挥到极致。