最佳实践¶
这页面向刚接触本插件的同学,内容基于仓库 examples/ 下的三个独立示例项目:
examples/screenshot/:网页截图与元素截图;examples/template_render/:本地模板渲染与纯文本渲染;examples/remote_browser/:远程浏览器渲染。
如果你是第一次接入,建议按明确的接入顺序推进,而不是一开始就把远程浏览器、模板资源、外部字体和复杂交互全部堆进同一条链路。
从最小可用开始¶
推荐第一步先实现一个最简单命令,只调用一个 API(例如 render_text):
from nonebot import on_command, require
from nonebot.adapters.onebot.v11 import Bot, MessageEvent, MessageSegment
from nonebot_plugin_htmlrender import render_text
require("nonebot_plugin_htmlrender")
cmd = on_command("render_text")
@cmd.handle()
async def _(bot: Bot, event: MessageEvent) -> None:
text = str(event.get_message()).strip() or "Hello, HTMLRender!"
image = await render_text(text)
await cmd.finish(MessageSegment.image(image))
先确保这条链路稳定,再扩展 Markdown、模板、资源解析等能力。
推荐的能力接入顺序¶
参考 examples/template_render/ 与 examples/screenshot/,建议按这个顺序逐步添加:
list_render_backend_statuses:先确认后端状态可读(示例中包装为render_status命令)。render_text:最快拿到第一张图。render_markdown:引入样式和内容结构。get_render_context:需要精细控制页面行为时再用。render_template:适合业务页面和可复用布局。render_template + filters:最后再引入模板过滤器。
这个顺序的好处是:每一步都可独立验证,定位问题时更容易。
目录与资源组织建议¶
模板示例给出了一个对初学者友好的结构:
examples/template_render/plugins/template_render/templates/:模板与 CSS 放一起。examples/template_render/plugins/template_render/__init__.py:命令 handler 与渲染调用入口。examples/screenshot/plugins/screenshot/__init__.py:需要直接操作页面时的get_render_context示例。
实际项目里也建议保持同样思路:
“模板/CSS/工具函数”分目录管理,尽量避免把所有逻辑写在一个 handler 里。
示例验证方式¶
当前示例项目更偏“可复制到 Bot 中运行”的集成示例。若要验证核心行为,请优先跑仓库测试:
涉及真实浏览器行为时,先安装项目本地浏览器,再跑 local profile:
两条很实用的小技巧¶
1) 本地预览产物先落盘¶
调模板时建议先在业务代码里临时把渲染结果写成 png,这对排查样式问题非常有帮助。
确认模板稳定后,再把结果直接发送到聊天消息里。
2) get_render_context 只在必要时使用¶
get_render_context 很强,但也更偏底层。
如果你只是“输入文本/模板 -> 输出图片”,优先用 render_* API。
只有在你需要自己控制 page.goto、page.screenshot 等步骤时,再切到 context 模式。
并发与会话复用¶
- 默认优先复用
Render持有的 runtime 与 session,不要在业务层自己反复重建浏览器 - 高频调用时优先复用默认实例,避免手动在每次请求里显式
startup_render()/shutdown_render() - 真正需要限制并发时,在业务层做任务队列或 semaphore,不要靠“每次都重启浏览器”来规避竞争
长文与长页面截图¶
- 长 Markdown 或长 HTML 页面优先保留
full_page=True - 页面依赖异步资源时,优先用
wait或自定义 page 行为补稳定等待,而不是单纯把 timeout 拉得很大 - 超长页面如果单张图不可读,应在业务层做分页或分段渲染,而不是强行输出一张极长截图
模板、字体与静态资源¶
- 模板目录、CSS、图片、字体尽量放在同一棵静态资源树下
- 本地模式可直接使用
file://资源;远程模式优先走资源解析与 filehost,不要假定远端能直接访问本地路径 - 容器或远端浏览器环境中,CJK 字体和 emoji 字体要显式安装;不要把“本机能显示”当成可部署结论
远程模式的资源边界¶
- 远程浏览器只适合访问它自己网络环境里可达的 HTTP(S) 资源
- 只要模板里引用本地图片、CSS、字体或相对路径资源,就应评估
resolve_resources=True与 filehost - 非必要不要在远程模式下继续使用
file://base URL;优先about:blank或显式 HTTP(S) base URL
接入节奏示例¶
- 先参考
examples/template_render/中的纯文本渲染命令。 - 把它改成你自己的命令名和业务文本。
- 加入
render_markdown命令并验证样式。 - 再接入
render_template,把页面结构沉淀为模板。 - 需要网页截图时参考
examples/screenshot/。 - 最后视需求接入远程 Playwright / filehost,参考
examples/remote_browser/。
做到这一步,你的渲染层通常已经足够稳定,也便于团队继续维护。