我在这个周末搭建了一个网站跟踪器——以下是我的收获
Source: Dev.to
问题
我需要一个工具,能够:
- 追踪我访问最多的站点
- 实时监控站点状态(上线/下线)
- 按项目/客户组织站点
- 显示使用模式和分析数据
- 完全本地化(无云服务、无需账号)
现有的解决方案要么过于复杂,要么需要注册,或者缺少我所需的功能。
解决方案:SiteOps
SiteOps 是一个 vanilla JavaScript 网络应用,完全在浏览器中运行。所有数据都保存在 localStorage 中——无需后端、数据库或账户。
- Live Demo:
- Source Code:
技术栈
- Vanilla HTML / CSS / JavaScript – 无框架,无构建过程
- Chart.js – 分析可视化
- localStorage – 客户端数据持久化
- PWA‑ready – 可作为 Web 应用安装
关键特性
1. 实时状态监控
每个网站卡片都会显示实时状态(在线/离线)以及可视化指示器。
async function checkWebsiteStatus(url) {
try {
const proxyUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(url)}`;
const response = await fetch(proxyUrl, {
method: 'GET',
signal: controller.signal
});
return response.ok ? 'online' : 'offline';
} catch (error) {
return 'offline';
}
}
2. 访问跟踪与分析
记录每一次访问的时间戳、设备类型和访问模式。
function visitWebsite(url) {
const website = this.websites.find(w => w.url === url);
if (website) {
website.visits = (website.visits || 0) + 1;
website.lastVisited = new Date().toISOString();
// 跟踪设备类型
website.visitHistory.push({
timestamp: new Date().toISOString(),
deviceType: this.getDeviceType(),
hour: new Date().getHours()
});
this.saveWebsites();
}
window.open(url, '_blank');
}
3. 综合分析仪表盘
使用 Chart.js 可视化:
- 30 天的访问趋势
- 分类细分
- 设备使用情况(桌面 / 移动 / 平板)
- 最受访问的网站
- 高峰使用时段和日期
4. 本地优先架构
所有数据均保存在 localStorage 中。
function saveWebsites() {
localStorage.setItem('websiteTracker', JSON.stringify(this.websites));
}
function loadWebsites() {
const stored = localStorage.getItem('websiteTracker');
return stored ? JSON.parse(stored) : [];
}
挑战与经验
挑战 1:状态检查的 CORS
Problem: Direct fetches are blocked by CORS.
Solution: Use the allorigins.win proxy.
const proxyUrl = `https://api.allorigins.win/get?url=${encodeURIComponent(url)}`;
Learning: Browser security is strict for good reasons; client‑side monitoring requires work‑arounds.
挑战 2:无框架的响应式设计
Problem: Building a complex, responsive dashboard with pure CSS.
Solution: CSS Grid with repeat(auto-fit, minmax()).
.websites-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
gap: 20px;
}
Learning: Modern CSS Grid handles most layouts without a framework.
挑战 3:数据持久化
Problem: Ensuring data survives browser restarts.
Solution: Save to localStorage after every action and provide export/import for backup.
Learning: localStorage is reliable but limited (~5‑10 MB). For larger datasets, IndexedDB is preferable.
挑战 4:实时 UI 更新
Problem: Updating the UI without a page refresh.
Solution: Event‑driven architecture with manual DOM updates.
function renderWebsites() {
const filtered = this.getFilteredWebsites();
grid.innerHTML = filtered.map(website => this.createWebsiteCard(website)).join('');
}
Learning: Vanilla JS can handle complex UIs, but state management becomes harder as the app grows.
设计决策
为什么选择原生 JavaScript?
- 简洁性: 无需构建过程,无依赖
- 性能: 加载速度快,包体积最小
- 学习: 加深对基础的理解
- 可移植性: 在任何支持 HTML/CSS/JS 的环境中都能运行
为什么使用 localStorage?
- 隐私: 数据永不离开浏览器
- 简洁性: 不需要后端基础设施
- 速度: 即时保存/加载
- 离线: 首次加载后无需互联网即可使用
为什么选择 Chart.js?
- 易于集成: CDN,无需构建步骤
- 良好默认设置: 开箱即用的专业外观
- 灵活性: 需要时可自定义
让它与众不同的特性
- 5‑Star Rating System – 为快速参考对网站进行评分
- Keyboard Shortcuts – 为高级用户设计(Ctrl + N、Ctrl + F 等)
- Export / Import – 将数据备份为 JSON
- Device Tracking – 桌面 / 移动 / 平板 使用统计
- Return‑Visit Rate – 对重复访问进行分析
- Glassmorphism UI – 现代、简洁的设计
我会做的不同之处
- IndexedDB – 用于更大的数据集和更好的性能
- Service Worker – 真正的离线功能和缓存
- WebSockets – 实时推送更新用于状态监控
实时状态更新(如果我添加了后端)
- Testing – 为核心功能添加单元测试
- TypeScript – 提升代码可维护性
试一试
访问 live demo 并:
- 添加几个网站
- 访问它们几次
- 查看分析仪表板
- 导出你的数据
所有数据都保存在你的浏览器中——完全私密且本地存储。
开源
SiteOps 是开源的,可在 GitHub 获取。欢迎贡献!
最后思考
- Vanilla JS 可以构建复杂的应用
localStorage对于本地优先的应用非常强大- 良好的用户体验比框架更重要
- 有时最好的解决方案就是最简单的那个
如果你在跟踪多个网站,试试 SiteOps 吧。如果你有反馈或建议,我很乐意听取!
Tags: #javascript #webdev #productivity #opensource #pwa #localstorage #analytics #webdevelopment