Design and Implementation of an H5 Page Experience Checkpoint Service
The article describes how to build an H5 page Experience Checkpoint service that automatically runs headless‑browser scripts to detect critical (P0) and potential (P1) UX issues—such as large media, privacy leaks, or slow APIs—by integrating data providers, page inspectors, and reporters into an existing inspection system, exposing a task‑creation API, and delivering detailed HTML reports via Feishu.
The article presents the development practice of an "Experience Checkpoint" service for H5 pages, aiming to detect user‑experience issues before a page goes live. It starts with the background that user experience is a key metric for the front‑end platform of the company, and existing post‑deployment monitoring leaves a "blind spot".
Two levels of experience problems are defined: P0 (critical, e.g., huge media resources or privacy leaks) and P1 (potential, e.g., API response time > 300 ms). The service quantifies these problems by establishing metrics, writing automated scripts that run in a headless browser, collecting performance data, and generating reports.
The core of the solution is the integration of the checkpoint service into the existing inspection system. The inspection system is built around three base classes:
DataProviderBase : fetches page URL lists on a schedule.
PageInspectorBase : opens pages, injects scripts, and monitors requests/responses.
DataReporterBase : builds reports, uploads static HTML, and notifies via Feishu.
Concrete subclasses are created for each scenario. Below is a minimal inspector implementation:
export class DataProvider extends DataProviderBase {
// Custom page list logic
async fetchData(args) {
return await axios.get('https://xxx.xxx').then(res => res.data.urlList)
}
// Run every 15 minutes
async schedule() {
return [{ cron: '*/15 * * * *', args: {} }]
}
}
class PageInspector extends PageInspectorBase {
// Map resource type to check method
checkResponseMethodsMap = new Map([['image', this.checkImageResponse]])
// Resource‑type detection
async onResponse(response, reporter, data) {
const resourceType = response.request().resourceType()
const checkMethod = this.checkResponseMethodsMap.get(resourceType)
await checkMethod(response, reporter, data)
}
// Example: image resource check
async checkImageResponse(response, reporter, data) {
// ...
if (imageCdnList.includes(url)) {
reporter.add({ errorType: "图片类型错误.非cdn资源" })
}
}
// Runtime detection when page opens
async onPageOpen(page, reporter, data) {
const htmlText = await page.evaluate('window.document.documentElement.innerHTML')
const phoneRegex = /\b((?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[35678]\d{2}|4(?:0\d|1[0-2]|9\d))|9[189]\d{2}|66\d{2})\d{6})\b/g
let match, collect = []
while ((match = phoneRegex.exec(htmlText)) !== null) {
collect.push(`手机号码:${match[1]}`)
}
collect.forEach(v => reporter.add({ errorMessage: `敏感信息:${v}` }))
}
}An API endpoint is added to allow external callers to create detection tasks:
app.post('/xxx.xxx', async (req, res) => {
const urls = req.body?.urls
const callBack = req.body?.callBack
const transData = req.body?.transData
newApp.createJob(urls.map(url => ({ url, pos: { callBack, transData } })),
jobId => { res.json({ taskId: jobId }) })
})After a detection job finishes, the reporter generates a detailed HTML report (using an EJS template) and posts the result back to the caller:
axios.post(callBack, {
data: {
msg: "本次检测报告如下:xxxxx",
transData: `透传的数据如下:${transData}`
}
})The article also discusses the use of Redis and Bull for asynchronous task management, the decoupling of the checkpoint service from its callers, and the possibility of extending the system with a lightweight registration center. Finally, it emphasizes that studying the inspection system’s source code is essential for effective customization and that the shared experience can help developers improve their design and coding skills.
DeWu Technology
A platform for sharing and discussing tech knowledge, guiding you toward the cloud of technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.