搭建自動化 Web 頁面性能檢測系統(tǒng) —— AI 篇

我們是袋鼠云數(shù)棧 UED 團(tuán)隊,致力于打造優(yōu)秀的一站式數(shù)據(jù)中臺產(chǎn)品。我們始終保持工匠精神,探索前端道路,為社區(qū)積累并傳播經(jīng)驗價值。

本文作者:琉易

這一篇是系列文章:

搭建自動化 Web 頁面性能檢測系統(tǒng) —— 設(shè)計篇

搭建自動化 Web 頁面性能檢測系統(tǒng) —— 實(shí)現(xiàn)篇

搭建自動化 Web 頁面性能檢測系統(tǒng) —— 部署篇

頁面性能對于用戶體驗、用戶留存有著重要影響,當(dāng)頁面加載時間過長時,往往會伴隨著一部分用戶的流失,也會帶來一些用戶差評。性能的優(yōu)劣往往是同類產(chǎn)品中勝出的影響因素,也是一個網(wǎng)站口碑的重要評判標(biāo)準(zhǔn)。

系統(tǒng)架構(gòu)圖(簡略)

本篇重點(diǎn)講解 AI 分析模塊的設(shè)計與實(shí)踐。

file

AI 分析模塊的設(shè)計與實(shí)現(xiàn)

輸入與輸出

  • 輸入:Lighthouse 檢查產(chǎn)生的 JSON 數(shù)據(jù)
    • 由于每次檢測產(chǎn)生的 JSON 數(shù)據(jù)較大,一般有 350KB ~ 500KB,而大模型往往是根據(jù)輸入 Tokens 進(jìn)行計費(fèi),且并不是單純的按量計費(fèi),類似于生活中常見的階梯計費(fèi);另外模型支持的輸入也有限,一般為 32k Tokens 或 64k Tokens。所以我們將 JSON 數(shù)據(jù)傳輸給大模型前需要進(jìn)行精簡。
    • 保留檢測結(jié)果中的關(guān)鍵數(shù)據(jù),如:環(huán)境數(shù)據(jù)(environment)、每一項檢測指標(biāo)的詳細(xì)結(jié)果(audits)、檢測時的配置參數(shù)(configSettings)、匯總各類指標(biāo)的最終得分(categories)。
  • 輸出:自然語言優(yōu)化建議列表
    • 如:建議將圖片資源啟用 lazy-load
    • 如:減小某個圖片文件的大小以減少傳輸時間

核心組成

  • JSON 清洗與摘要
  • Prompt 定義
  • openai 接口集成
  • 流式處理

Prompt 設(shè)計要點(diǎn)

構(gòu)建一個高質(zhì)量的 Prompt 是成功的關(guān)鍵,以下是一個例子:

你是一個網(wǎng)頁性能優(yōu)化專家。我將提供一個通過 Google Lighthouse 生成的 JSON 報告,請你根據(jù)報告中的內(nèi)容:
1. 每個關(guān)鍵指標(biāo)給出兩三條優(yōu)化建議,需要結(jié)合 json 中的實(shí)際數(shù)據(jù)進(jìn)行舉例。
2. 回答的內(nèi)容使用 markdown 格式。
3. 專業(yè)名詞需要使用中文。

實(shí)際測試中 Kimi 的 moonshot-v1-auto 模型回答更快,百煉平臺的模型輸入輸出 Tokens 限制更寬泛,但是輸出速度略慢;百煉平臺的免費(fèi)額度更多,OpenAI 費(fèi)用較高且部署后會有訪問的問題。

關(guān)鍵技術(shù)點(diǎn)

Lighthouse 報告數(shù)據(jù)結(jié)構(gòu)解析

JSON 數(shù)據(jù)清洗與摘要是大模型調(diào)用能否成功的關(guān)鍵,清洗后的結(jié)果是 Prompt 的數(shù)據(jù)來源,如果內(nèi)容較多可能會超出模型輸入 Tokens 的限制從而導(dǎo)致調(diào)用失敗。

  • audits 中會包含各種指標(biāo)近百種,我們可以刪除一些內(nèi)容較多但對分析用處不大的數(shù)據(jù),如:offscreen-images、screenshot-thumbnails 等。
  • Lighthouse 生成的 JSON 數(shù)據(jù)會直接保存瀑布圖等圖片的 Base64 格式數(shù)據(jù),這些圖片數(shù)據(jù)占用 Tokens 明顯。

經(jīng)過清洗,盡量將輸入的 Tokens 控制在 100k 以內(nèi)。

流式輸出

openai 是一個 npm 包,通過這個 npm 包可以快速的對接各種大模型的 API 調(diào)用服務(wù)。

// 流式輸出
const stream = await client.chat.completions.create({
    model: 'moonshot-v1-auto',
    messages: [
        {
            role: 'system',
            content: `你是一個網(wǎng)頁性能優(yōu)化專家。我將提供一個通過 Google Lighthouse 生成的 JSON 報告,請你根據(jù)報告中的內(nèi)容:
1. 每個關(guān)鍵指標(biāo)給出兩三條優(yōu)化建議,需要結(jié)合 json 中的實(shí)際數(shù)據(jù)進(jìn)行舉例。
2. 回答的內(nèi)容使用 markdown 格式。
3. 專業(yè)名詞需要使用中文。`,
        },
        { role: 'user', content: jsonData },
    ],
    temperature: 0.3,
    stream: true,
});

// 當(dāng)啟用流式輸出模式(stream=True),SDK 返回的內(nèi)容也發(fā)生了變化,我們不再直接訪問返回值中的 choice
// 而是通過 for 循環(huán)逐個訪問返回值中每個單獨(dú)的塊(chunk)
for await (const chunk of stream) {
    if (abortSignal?.aborted) {
        console.log(`${taskIdLogStr}任務(wù)中止, kimi chat`);
        break;
    }

    // 在這里,每個 chunk 的結(jié)構(gòu)都與之前的 completion 相似,但 message 字段被替換成了 delta 字段
    const delta = chunk.choices[0].delta;
    if (delta.content) {
        onData(delta.content);
    }
}
@ApiOperation({ summary: '分析檢測結(jié)果' })
    @HttpCode(HttpStatus.OK)
    @Post('reportChat')
    @RawResponse()
    async reportChat(@Body() query: ReportChatReqDto, @Res() res: Response) {
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');
    res.flushHeaders();

    const abortController = new AbortController();

    // ?? 監(jiān)聽客戶端斷開連接(如 Abort)
    res.on('close', () => {
        abortController.abort();
    });

    try {
        await this.AIService.reportChat(
            query,
            (content: string) => {
                res.write(`data: ${JSON.stringify({ content })}\n\n`);
            },
            abortController.signal
        );
        res.write(`data: [DONE]\n\n`);
    } catch (error) {
        res.write(`data: [ERROR] ${error.message || 'stream error'}\n\n`);
        abortController.abort();
    } finally {
        res.end();
    }
}

非流式輸出

// 非流式輸出
const completion = await client.chat.completions.create({
    model: 'moonshot-v1-auto',
    messages: [
        {
            role: 'system',
            content: `你是一個網(wǎng)頁性能評分分析專家。我將提供一個產(chǎn)品的性能評分?jǐn)?shù)據(jù),幫我分析得分趨勢和較大的得分變化?;卮鸬膬?nèi)容不要帶格式符號,尤其是 **。`,
        },
        { role: 'user', content: jsonData },
    ],
    temperature: 0.3,
});

return completion.choices[0].message.content;

實(shí)現(xiàn)的功能點(diǎn)

檢測報告的智能分析與建議

由于保存的是 html 文件,我們可以通過正則將 html 文件中的 JSON 數(shù)據(jù)提取出來,用于后續(xù)的清洗與分析。

file

結(jié)合清洗后的 JSON 數(shù)據(jù)給出優(yōu)化建議。

file

數(shù)據(jù)周報的趨勢分析

將過去一周的分?jǐn)?shù)給到大模型,由大模型分析解讀得分的變化趨勢。

file
file

后續(xù)規(guī)劃

  • JSON 數(shù)據(jù)清洗更精確,確定好哪些是關(guān)鍵性能指標(biāo)
  • 將 Lighthouse 的具體評分規(guī)則同步給大模型
  • 優(yōu)化 Prompt,更換更合適的大模型
  • 結(jié)合埋點(diǎn)數(shù)據(jù)
    • 分析頁面性能與用戶停留時長的關(guān)系
    • 分析用戶跳出率與頁面性能的關(guān)系
    • 結(jié)合采集到的埋點(diǎn)數(shù)據(jù)分析頁面性能對業(yè)務(wù)指標(biāo)的影響

最后

歡迎關(guān)注【袋鼠云數(shù)棧UED團(tuán)隊】~
袋鼠云數(shù)棧 UED 團(tuán)隊持續(xù)為廣大開發(fā)者分享技術(shù)成果,相繼參與開源了歡迎 star

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容