
1. 这篇文章真正要解决的问题很多开发者的桌面上其实摆着两块甚至三块屏幕但副屏的利用率低得惊人。绝大多数时候副屏只是把桌面壁纸延伸过去偶尔拖一个微信窗口或者放一个永远不看的监控页面。等到真正需要用副屏查资料、对比代码时又发现它在桌面扩展模式下并没有帮上多少忙。换句话说副屏的价值被严重浪费了。痛点在于我们每天高频使用的信息其实非常分散——时间、天气、待办事项、Git 提交状态、服务器负载、周会提醒、股票行情、航班信息。如果把这些信息全部堆在主屏幕上工作区域会被挤压得很难受如果放在副屏上又需要手动打开多个网页或应用切换成本太高最终还是会放弃维护。本文要聊的就是把副屏变成“个人信息终端”的完整方案。这里所说的“信息终端”不是再装一个桌面小组件工具而是通过 Web 技术自己搭建一个常驻副屏的信息聚合面板把零散信息统一展示在一张页面里全天候运行可以开机自启能够自动刷新。这个方案的核心理念很明确副屏应该用来承载“不需要交互但需要持续可见”的信息把主屏释放给真正的深度工作。读完这篇文章你可以获得一套基于 HTML / CSS / JavaScript 的个人信息终端设计方案一个可以跑起来的最小示例包含时间、天气、待办、系统状态等模块把页面变成真正“终端”的运行方案包括浏览器全屏、Electron 封装和开机自启数据源接入的通用思路以及实际部署中的常见问题和安全建议。这篇文章适合正在使用双屏、想提升信息获取效率的开发者也适合对 Dashboard、信息聚合、桌面应用封装感兴趣的初学者。你只需要有基础的 HTML 和 JavaScript 能力不需要掌握复杂的框架就可以跟着完成一版属于自己的信息终端。2. 什么是“个人信息终端”以及为什么用 Web 技术来搭2.1 先给一个清晰的定义“个人信息终端”这个词听起来很抽象但它描述的东西其实很朴素一个常驻屏幕、持续刷新、只展示关键信息的独立设备或界面。它和手机通知栏、桌面小组件的区别在于信息终端通常拥有更大的展示面积并且针对“长时间观看”做了信息密度和视觉节奏的优化。常见的商业化产品有智能镜子、桌面天气站、日历相框但那些设备大多功能固定无法扩展。开发者需要的是一个可以自由定制、按需增加模块的信息终端。而实现这个目标成本最低的方式不是购买硬件而是用好手上已经闲置的副屏。2.2 为什么推荐用 Web 技术实现对比几类技术方案Web 技术的优势很明显方案开发成本可定制性展示效果运行依赖桌面小组件工具如 Rainmeter低中依赖模板生态需要对应系统环境原生桌面应用高高高需要编译和打包Python GUI 框架中中一般需要 Python 运行环境Web 页面 浏览器/Electron低高高仅需要浏览器或 Node.jsWeb 技术栈最关键的三个优势第一前端生态足够成熟。CSS Grid 和 Flexbox 可以很轻松地完成信息密度的布局ECharts 等图表库可以快速接入监控图表任何远程页面都可以通过 iframe 或 fetch 嵌入。第二迭代成本极低。修改一个 CSS 变量刷新浏览器就能看到效果不需要重新编译和打包。对于信息终端这种需要长期打磨视觉细节的项目这个优势非常重要。第三硬件要求低。副屏只需要连接电脑用浏览器就能运行不需要在副屏端安装专用系统也不依赖某个特定品牌的智能硬件。2.3 信息终端应该具备哪些能力从实际使用体验出发一个合格的个人信息终端应该具备四个能力常驻显示页面不能轻易被关闭需要支持全屏运行和开机自启。自动刷新数据不能停留在打开页面那一刻需要定时去拉取最新信息。模块化布局不同模块可以独立维护、灵活增删而不是把代码写成一坨。弱交互设计使用者大多数时间只是“看”偶尔才需要“点”所以信息展示的优先级要高于按钮与菜单。这四个能力恰好都是 Web 技术非常擅长的领域。3. 方案选型从纯浏览器到 Electron 封装在开始写代码之前需要先想清楚一个关键问题这个信息终端最终以什么方式运行在副屏上3.1 方案一浏览器全屏模式这是最轻量的方案。直接用 Chrome 或 Edge 打开页面按 F11 进入全屏或者启动时带上--kiosk参数进入信息亭模式。优点零额外依赖写完 HTML 就能跑浏览器对 CSS 动画、WebSocket、渐变渲染的支持都非常成熟按 F12 可以直接调 DevTools调试非常方便。缺点浏览器顶栏和右键菜单如果不做处理会影响沉浸感如果页面挂在系统 Shell 下面误触可能导致退出全屏浏览器本身的内存占用偏高。浏览器全屏适合开发阶段验证也适合追求零依赖的用户。3.2 方案二Electron 封装如果你希望信息终端像一个真正的桌面应用一样有独立窗口、没有浏览器菜单、可以打包分发那么 Electron 是更合适的选择。优点窗口行为完全可控可以设置无边框、全屏、置顶可以通过 Node.js 能力读取本地系统信息比如 CPU、内存、网络状态可以打包成独立的 .exe / .app / .AppImage 文件分发给其他人使用。缺点打包体积较大内存占用比纯浏览器方案更高开发时需要安装 Node.js 和 Electron 依赖。3.3 方案三本地服务 任意设备访问如果你的副屏本身是一块独立设备比如树莓派、旧平板、或者一台小主机可以让信息终端跑在开发机上然后通过局域网访问。这个方案最灵活但需要额外配置一个本地 HTTP 服务并考虑局域网访问的安全性。从实践角度比较推荐的做法是开发阶段用浏览器直接预览稳定之后用 Electron 打包成应用。这样既能享受浏览器调试的便利又能获得桌面应用的稳定性。4. 环境准备与前置条件本文的示例基于纯前端技术实现工程依赖非常少。以下是推荐环境具体版本请以实际安装为准这里不写死版本号以避免误导。4.1 基础环境操作系统Windows 10 / 11、macOS、主流 Linux 发行版均可主屏和副屏已经正确连接并处于扩展模式浏览器Chrome / Edge / Firefox 任一现代浏览器Node.js仅在使用 Electron 方案时需要建议 LTS 版本。4.2 预留资源一个用于存放项目的目录例如info-terminal如果计划接入天气等第三方数据需要提前准备对应服务的 API Key如果计划显示系统监控数据需要确认系统允许运行本地采集脚本。4.3 创建项目结构建议按下面的目录结构组织项目info-terminal/ ├── index.html # 信息终端主页面 ├── css/ │ └── style.css # 样式文件 ├── js/ │ ├── config.js # 配置文件集中管理 API Key 和刷新间隔 │ ├── widgets.js # 各信息模块的渲染逻辑 │ └── main.js # 入口负责初始化与定时刷新 └── assets/ └── icons/ # 图标资源为什么单独拆一个config.js因为信息终端往往需要频繁调整 API Key、刷新间隔、城市 ID 等参数。把这些配置集中在一个文件里后续维护时不需要到处找散落的硬编码值。5. 核心页面实现HTML 结构与布局设计5.1 页面整体思路信息终端的设计原则是“一眼扫过就能获取关键信息”。所以页面的主体不是密密麻麻的表格而是几个信息块按重要性排列。典型的信息层级可以这么划分第一优先级当前时间、日期、天气——这是所有人每天都会反复看的信息第二优先级待办事项、日程提醒——这些信息需要在一定时间段内保持可见第三优先级Git 状态、系统负载、服务监控——这类信息适合用简短的指示器或图表呈现第四优先级娱乐或氛围信息比如每日一句、壁纸轮播、股票指数。5.2 基础 HTML 骨架!-- 文件路径info-terminal/index.html -- !DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 title个人副屏信息终端/title link relstylesheet hrefcss/style.css /head body main classdashboard !-- 顶部状态栏 -- header classstatus-bar div classstatus-left span idtoday-date/span /div div classstatus-right span idnetwork-status网络检测中.../span /div /header !-- 信息网格 -- section classgrid-container !-- 时间卡片 -- div classcard card-clock div classcard-title当前时间/div div idclock-time classclock-time--:--:--/div div idclock-seconds classclock-seconds/div /div !-- 天气卡片 -- div classcard card-weather div classcard-title天气/div div idweather-info classweather-info加载中.../div /div !-- 待办卡片 -- div classcard card-todo div classcard-title今日待办/div ul idtodo-list classtodo-list li暂无待办事项/li /ul /div !-- 系统信息卡片 -- div classcard card-sys div classcard-title系统状态/div div idsys-info classsys-info加载中.../div /div /section /main script srcjs/config.js/script script srcjs/widgets.js/script script srcjs/main.js/script /body /html这里的布局遵循一个核心原则越重要的信息越靠近视觉中心。时间与天气放在左上方这是因为人的视线习惯从左上角开始扫视。待办事项放在中间区域系统状态放在右侧方便做横向对比。5.3 CSS 布局让信息一目了然CSS 的关键是使用 Grid 布局让不同尺寸的卡片自动排列。以下是一份基础样式可以在其基础上调整颜色和间距。/* 文件路径info-terminal/css/style.css */ :root { --bg-primary: #0f172a; --bg-card: #1e293b; --text-primary: #f1f5f9; --text-secondary: #94a3b8; --accent: #38bdf8; --border-radius: 16px; --gap: 16px; } * { margin: 0; padding: 0; box-sizing: border-box; } body { background-color: var(--bg-primary); color: var(--text-primary); font-family: Segoe UI, PingFang SC, Microsoft YaHei, sans-serif; min-height: 100vh; padding: 24px; } .dashboard { max-width: 1400px; margin: 0 auto; } .status-bar { display: flex; justify-content: space-between; align-items: center; padding: 8px 16px; margin-bottom: 16px; background: var(--bg-card); border-radius: var(--border-radius); color: var(--text-secondary); font-size: 14px; } .grid-container { display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: minmax(160px, auto); gap: var(--gap); } .card { background: var(--bg-card); border-radius: var(--border-radius); padding: 20px; } .card-title { font-size: 14px; color: var(--text-secondary); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 12px; } .clock-time { font-size: 48px; font-weight: 600; font-variant-numeric: tabular-nums; color: var(--accent); } .clock-seconds { font-size: 20px; color: var(--text-secondary); margin-top: 4px; } .weather-info { font-size: 16px; line-height: 1.8; } .todo-list { list-style: none; } .todo-list li { padding: 8px 0; border-bottom: 1px solid rgba(148, 163, 184, 0.2); font-size: 15px; } .sys-info { font-size: 14px; line-height: 2; color: var(--text-secondary); } /* 屏幕适配副屏尺寸较小时自动降为两列 */ media (max-width: 1024px) { .grid-container { grid-template-columns: repeat(2, 1fr); } }这段样式里最值得关注的是grid-template-columns: repeat(4, 1fr)。四列布局非常适合 1920x1080 分辨率的副屏每个卡片够大信息不会拥挤。同时通过媒体查询在分辨率较低的副屏上自动降为两列避免卡片被压缩变形。5.4 JS 数据刷新机制让页面自己“活”起来信息终端区别于普通静态页面的核心在于它需要定时刷新数据。最简单的实现方式是setInterval但更合理的做法是分层处理秒级刷新时钟显示分钟级刷新天气、待办事项文件级别刷新系统监控信息视数据源更新频率而定。下面用一个示例说明如何管理不同的刷新周期。// 文件路径info-terminal/js/main.js import { CONFIG } from ./config.js; import { renderClock, renderWeather, renderTodo, renderSysInfo, initNetworkStatus } from ./widgets.js; function init() { // 启动网络状态检测 initNetworkStatus(); // 先立即渲染一次避免页面白屏 renderClock(); renderWeather(); renderTodo(); renderSysInfo(); // 时钟每秒更新 setInterval(renderClock, 1000); // 天气每 10 分钟更新 setInterval(renderWeather, CONFIG.refreshWeatherMs); // 待办每 5 分钟更新 setInterval(renderTodo, CONFIG.refreshTodoMs); // 系统状态每 5 秒更新 setInterval(renderSysInfo, 5000); } window.addEventListener(DOMContentLoaded, init);严格来说这里用setInterval有一个隐患如果数据请求耗时较长可能出现上一次请求还没结束、下一次请求已经开始的情况。在实际项目中更推荐的做法是用递归setTimeout或者请求完成后重新计时避免请求堆积。本文为了示例清晰先用setInterval表达思路工程化时可以按最佳实践优化。6. 数据接入天气、待办、系统监控的通用方案6.1 配置文件的设计先看一下config.js的示例。它的作用是集中管理所有需要手动调整的参数。// 文件路径info-terminal/js/config.js // 如果使用原生 ES Module在 main.js 中通过 import 引入 export const CONFIG { // 天气配置 weather: { apiKey: your_api_key_here, cityId: 101010100, refreshMs: 10 * 60 * 1000, }, // 待办数据源可以是 JSON 文件也可以是后端接口 todo: { apiUrl: ./data/todo.json, refreshMs: 5 * 60 * 1000, }, // 系统监控需要本地脚本支持 sys: { apiUrl: http://127.0.0.1:8081/api/sys, refreshMs: 5000, } };从安全角度出发特别提醒两点API Key 不要硬编码在页面里。如果这个页面只能在本机访问硬编码的泄露风险相对可控但一旦放在内网甚至公网API Key 就可能被他人获取。更稳妥的方式是通过本地后端代理转发数据请求。不要把高权限服务的凭据写在前端配置里。信息终端是“长时间暴露在视线上”的页面如果被截图、误分享凭据就会泄露。6.2 HTML 页面直接使用配置如果不使用 ES Module可以简化为普通的全局对象script window.CONFIG { weather: { apiKey: your_api_key_here, cityId: 101010100 } }; /script然后在widgets.js中通过window.CONFIG读取配置这种方式对初学者更友好。6.3 天气信息接入天气数据的获取方式很多常见方案是使用和风天气、OpenWeatherMap 等 API。它们的通用链路包括申请 API Key根据城市 ID 或经纬度请求实时天气接口解析 JSON 响应提取温度、天气描述、湿度、风力数据渲染到页面上。代码示例如下// 文件路径info-terminal/js/widgets.js export function renderWeather() { const { apiKey, cityId } window.CONFIG.weather; const url https://你的天气服务地址/api/weather?cityId${cityId}key${apiKey}; fetch(url) .then(res { if (!res.ok) { throw new Error(Weather API request failed); } return res.json(); }) .then(data { const weatherInfo document.getElementById(weather-info); weatherInfo.innerHTML div温度${data.temp} ℃/div div天气${data.text}/div div湿度${data.humidity}%/div div风向${data.windDir} ${data.windScale}级/div ; }) .catch(err { console.error(天气数据加载失败:, err); document.getElementById(weather-info).textContent 天气加载失败; }); }注意不同的天气服务返回字段名不一致字段名需要以实际接口为准。在写代码时建议先打开接口返回的 JSON 确认字段结构再写渲染逻辑。6.4 待办事项接入待办事项的数据来源可以是本地 JSON 文件也可以是一个简单的后端接口。对个人信息终端来说最流行的方式是把待办事项维护在一个 JSON 文件里开发方便、改动即时。// 文件路径info-terminal/js/widgets.js export function renderTodo() { const { apiUrl } window.CONFIG.todo; fetch(apiUrl) .then(res res.json()) .then(data { const todoContainer document.getElementById(todo-list); if (!data.todos || data.todos.length 0) { todoContainer.innerHTML li暂无待办事项/li; return; } todoContainer.innerHTML data.todos .map(item li${item.done ? ✅ : ⬜} ${item.text}/li) .join(); }) .catch(err { console.error(待办加载失败:, err); document.getElementById(todo-list).innerHTML li待办加载失败/li; }); }对应的todo.json示例{ todos: [ { text: 提交周报, done: false }, { text: 检查服务器磁盘, done: true }, { text: 预约周三的会议室, done: false } ] }这里有一个比较实用的设计如果把done字段做成布尔值就可以在页面里通过样式区分已完成和未完成甚至后续可以支持点击切换完成状态把信息终端从“纯展示”升级为“轻交互”。6.5 系统监控信息接入浏览器直接读取系统 CPU、内存数据是受限的最常见的方式是借助本地小脚本暴露一个 HTTP 接口然后页面定时请求这个接口。这里用一个 Python 示例来演示因为 Python 写这类脚本最快捷。# 文件路径info-terminal/server/sys_monitor.py # 依赖pip install flask psutil from flask import Flask, jsonify import psutil app Flask(__name__) app.route(/api/sys, methods[GET]) def sys_info(): cpu_percent psutil.cpu_percent(interval1) memory psutil.virtual_memory() disk psutil.disk_usage(/) return jsonify({ cpu: cpu_percent, memory: { total: memory.total, available: memory.available, percent: memory.percent }, disk: { total: disk.total, used: disk.used, percent: disk.percent }, time: __import__(time).time() }) if __name__ __main__: # 只监听本机回环地址避免局域网内其他设备访问 app.run(host127.0.0.1, port8081)启动这个脚本python sys_monitor.py然后页面端就可以请求http://127.0.0.1:8081/api/sys获取数据。这里需要强调安全边界这个接口默认只绑定127.0.0.1其他设备无法访问这是一个好的默认配置。如果确实需要在其他设备上查看信息也应增加简单的鉴权而不是直接暴露在局域网中。对应的前端渲染逻辑// 文件路径info-terminal/js/widgets.js export function renderSysInfo() { const url window.CONFIG.sys.apiUrl; fetch(url) .then(res res.json()) .then(data { document.getElementById(sys-info).innerHTML divCPU 使用率${data.cpu}%/div div内存使用率${data.memory.percent}%/div div磁盘使用率${data.disk.percent}%/div ; }) .catch(err { console.error(系统信息加载失败:, err); }); }到这里信息终端已经有了三个核心数据源天气、待办、系统状态。接下来要做的是把页面“跑起来”并显示在副屏上。7. 完整运行方案浏览器、Electron 与开机自启7.1 本地启动一个简易 HTTP 服务如果直接用file://协议打开 HTML部分接口的请求会被浏览器跨域策略拦截。最稳妥的方式是在项目根目录启动一个静态文件服务。cd info-terminal # 方式一使用 Python 自带的 HTTP 服务 python -m http.server 8080 # 方式二使用 Node.js 的 npx serve需要 Node.js 环境 npx serve -l 8080启动后访问http://localhost:8080即可看到信息终端页面。如果天气等远程接口允许跨域直接用 file 协议打开通常也能工作但建议还是开启本地服务后续增加数据接口会更方便。7.2 浏览器全屏优化在 Chrome 或 Edge 中打开页面后可以直接按 F11 全屏。为了减少误操作和浏览器痕迹可以在启动浏览器时加入--kiosk参数。Windows 上创建快捷方式时目标可以写为C:\Program Files\Google\Chrome\Application\chrome.exe --kiosk http://localhost:8080macOS 上可以使用对应的 Chrome 可执行文件路径并加上相同参数。需要注意的是--kiosk模式下退出全屏需要按AltF4或使用系统快捷键如果是公共场合的展示屏这是一个有利的特性如果是个人副屏可能反而会带来不便可以去掉该参数改用--start-fullscreen。7.3 Electron 封装成桌面应用如果希望关闭浏览器干扰可以用 Electron 把信息终端封装为桌面应用。以下是最小可运行配置。先在项目根目录初始化 npmnpm init -y npm install --save-dev electron然后创建 Electron 主进程文件// 文件路径info-terminal/electron/main.js const { app, BrowserWindow } require(electron); const path require(path); function createWindow() { const win new BrowserWindow({ width: 1920, height: 1080, frame: false, // 无边框 alwaysOnTop: false, // 副屏通常不需要置顶 webPreferences: { contextIsolation: true, nodeIntegration: false } }); win.loadFile(path.join(__dirname, ../index.html)); // 二选一全屏显示 // win.setFullScreen(true); } app.whenReady().then(() { createWindow(); app.on(activate, () { if (BrowserWindow.getAllWindows().length 0) { createWindow(); } }); }); app.on(window-all-closed, () { if (process.platform ! darwin) { app.quit(); } });解释几个关键配置frame: false会去掉窗口边框让页面完全融入桌面contextIsolation: true和nodeIntegration: false是 Electron 的安全推荐配置避免在页面中直接暴露 Node.js 能力loadFile直接加载本地 HTML不依赖本地 HTTP 服务降低运行复杂度。之后修改package.json把主入口指向 Electron 文件{ name: info-terminal, version: 1.0.0, main: electron/main.js, scripts: { start: electron . } }运行npm start7.4 开机自启信息终端要真正“常驻”还需要在系统启动后自动运行。常见方式有三种使用系统的“启动”文件夹放入快捷方式使用任务计划程序Windows或 LaunchAgentmacOS使用 Electron 的开机自启 API或者第三方工具如pm2-windows-startup。这里最推荐第一种简单、可靠、易回滚。把 Electron 应用的快捷方式放入系统的启动目录即可在登录后自动打开。8. 运行结果与效果验证8.1 启动后的预期表现成功运行后副屏上应该出现左上角显示实时时钟每秒跳动时钟下方或旁边显示最新的天气信息中间区域显示待办事项已完成项和未完成项有明显区分右侧区域显示 CPU、内存、磁盘的使用率每 5 秒刷新一次页面整体为深色背景各卡片圆角统一信息密度适中。8.2 验证各模块是否正常可以按以下步骤验证系统状态打开浏览器控制台确认没有红色报错在 Network 面板中观察天气请求、待办请求、系统监控请求是否返回 200手动修改todo.json中的待办内容刷新页面确认内容更新手动操作电脑比如打开几个大型软件观察 CPU 使用率是否在页面中发生变化如果使用 Electron 封装确认窗口是否无边框、是否能全屏显示。8.3 如何判断页面性能是否达标信息终端是 7x24 小时运行的页面性能不可忽视。可以在浏览器 DevTools 的 Performance 面板中查看 JavaScript 执行时间。如果每个定时任务的执行时间超过 200ms就会明显感觉到页面卡顿。通常纯 DOM 操作的渲染任务执行时间应该在几十毫秒以内。如果发现页面内存不断上涨优先检查是否有不必要的定时器没有清理以及是否在每次渲染时创建了过多无法回收的对象。9. 常见问题与排查思路在实际运行中最容易遇到的问题集中在跨域、API Key、定时器、窗口显示四类。问题现象可能原因排查方式解决方案页面空白控制台报 CORS 错误远程接口不允许浏览器跨域调用查看 Network 面板中的请求状态启动本地 HTTP 服务使用本地后端代理转发请求天气一直显示“加载失败”API Key 错误或接口地址错误在浏览器中直接访问 API URL 测试检查 API Key 是否有效确认城市 ID 是否正确待办事项不更新todo.json被浏览器缓存打开 Network 面板查看响应头在 fetch 请求中增加cache: no-store参数页面运行一段时间后卡顿定时器过多或 DOM 节点重复创建Performance 面板分析执行时间优化渲染逻辑避免不必要的 DOM 重建Electron 窗口无法关闭设置了无边框窗口没有退出按钮检查应用日志增加全局快捷键或托盘菜单用于退出开机自启没有生效快捷方式路径错误或权限不足手动点击快捷方式测试检查启动目录路径或改用任务计划程序刷新频率过高接口被限流定时刷新间隔太短查看接口响应中的限流提示调大刷新间隔增加失败退避策略另外还有一个容易被忽略的问题副屏分辨率与页面布局不匹配。默认repeat(4, 1fr)在 1920 宽度下表现良好但是如果是 2560 宽度的副屏卡片会拉得过宽。这种情况下建议给 Grid 容器加上max-width或者使用repeat(auto-fit, minmax(280px, 1fr))这种自适应列数的方式。10. 最佳实践与工程建议10.1 配置与代码分离信息终端的所有可变参数都应该进入config.js不要把 API Key、刷新间隔、城市 ID 直接写到渲染逻辑中。这样在换城市、换 API 服务商时只需要改一个文件。10.2 优雅处理请求失败信息终端是常驻页面网络抖动不可避免。出现错误时不应该白屏或者抛出一堆红色控制台错误而应该在对应卡片里显示“数据暂时不可用”并保留上一次成功拉取的数据。可以用一个“缓存上一次数据”的变量来实现。let lastData null; function fetchData(url) { return fetch(url) .then(res res.json()) .then(data { lastData data; return data; }) .catch(() lastData); }10.3 刷新频率要克制API 调用频率越高越容易被服务商限流也越浪费资源。时钟可以每秒刷新系统监控可以 5 到 10 秒刷新一次天气和待办 5 到 10 分钟刷新一次即可。刷新不是越快越好而是越匹配信息变化速度越好。10.4 安全边界要画清楚如果信息终端页面上有内网接口地址不能直接分享截图到公网。本地系统信息接口要绑定127.0.0.1不要绑定0.0.0.0。如果通过局域网访问至少要加一层简单的 Token 鉴权。涉及生产服务器监控信息的更要注意访问权限。10.5 为副屏定制视觉风格深色背景可以显著降低长时间观看的疲劳感。信息终端页面中不建议使用大面积高饱和色块而是在关键数据上用强调色做点缀。字体建议使用等宽数字字体如font-variant-numeric: tabular-nums这样时间跳动时数字宽度不会晃来晃去。10.6 预留“关灯模式”如果在办公室使用白天和夜晚的亮度需求不同。可以在页面右上角放一个手动切换按钮或者根据系统时间自动切换暗色和亮色。这个功能不复杂但对使用体验的提升非常明显。10.7 从最小版本开始迭代不建议一开始就想着做一个功能齐全的“信息宇宙”因为模块越多维护成本越高最终的结局往往是放弃。建议先做一个包含时钟、天气、待办的最小版本连续使用一周。确认自己真的会在副屏上查看这些信息后再逐步加入 Git 状态、服务监控、日历、图表等模块。信息终端的核心价值是“持续有用”而不是“功能多”。11. 总结与后续学习方向把副屏从“桌面壁纸显示器”变成“个人信息终端”本质上是重新思考了副屏在生产力工具中的定位它不应该被当作第二块主屏而应该被当作一个常驻的、低交互的信息展示层。用 Web 技术实现这个目标门槛低、自由度高、可扩展性强而且整个过程不需要购买额外硬件非常适合开发者自己动手。这篇文章帮助你完成了从方案选型到页面实现、数据接入、桌面封装、问题排查的完整闭环。你可以先照着示例搭建一个最小版本把它跑在副屏上再去考虑更高阶的玩法。如果你想继续深入下面几个方向值得研究Electron 的窗口管理与多显示器控制用screen模块把应用窗口精准定位到副屏避免每次都要手动拖拽窗口。更丰富的数据源接入接入 Git 提交记录、CI 构建状态、错误监控、RSS 订阅让信息终端成为你的开发助手。交互能力增强给待办事项增加点击勾选功能配合后端 API 实现信息终端的“轻交互”。性能优化学习如何减少 DOM 操作、使用requestAnimationFrame控制动画、合理使用 Web Worker 处理数据让信息终端在低配机器上也能顺滑运行。最后提醒一点无论你准备在这个项目上做得多复杂都建议保留一份“最小可用版本”的备份因为它会是你在折腾高阶功能失败之后最可靠的兜底方案。副屏信息终端的最终目标不是变成一个炫技的大屏幕而是每天早上走到工位前一眼扫过去就能开始高效的一天。