Harness 中的智能预加载:基于页面访问模式的性能黑魔法拆解


1. 标题 (Title)

  1. 告别加载延迟焦虑:Harness CI/CD 平台智能预加载的核心原理与工程实现
  2. 从毫秒级等待到即时响应:基于页面访问模式的 Harness 性能优化方案
  3. CI/CD 工具链的性能护城河:深入解析 Harness 基于马尔可夫链的智能预加载机制
  4. 前端工程师的必修课:学习 Harness 如何用访问预测干掉加载等待
  5. 百万级工程师的福音:揭秘 Harness CI/CD 基于行为数据的智能资源预加载

2. 引言 (Introduction)

2.1 痛点引入 (Hook)

还在为 CI/CD 平台的页面切换等待抓狂吗?当你刚提交完一个紧急 Bug 修复,切换到“管道执行详情”想查看最新的部署进度,却遇到 Loading 圈圈转 2-3 秒;当你需要频繁在“配置管理”“触发器设置”“监控面板”间来回调试 CI 脚本,每一次跳转都要重新加载一堆重复的环境变量缓存、静态 JSON 资源、管道模板片段;当你加班到深夜,网络条件本就一般,这些加载延迟更是雪上加霜,直接拖慢了整个迭代节奏——你有没有想过,如果工具能提前“猜到”你下一秒要去的页面,提前把资源准备好,那会是怎样的体验?

其实,这种“提前预判”的技术在各大互联网产品中早已不是新鲜事:微信朋友圈会预加载你下一张要刷的图片,淘宝会预加载你可能浏览的下一页商品,Netflix 会预加载你即将看完的剧集的下一集……但在 复杂度极高、功能模块极为分散、用户行为差异巨大 的企业级 CI/CD 平台(如 Harness、Jenkins X、GitLab CI)中,实现基于访问模式的智能预加载,绝非简单的“预加载下一个页面路由组件”那么容易。

2.2 文章内容概述 (What)

本文将以 全球领先的企业级 CI/CD 平台 Harness 为例,从核心概念、问题背景、算法模型、工程架构、代码实现、最佳实践 等多个维度,全面拆解其基于页面访问模式的智能预加载机制——我们不仅会讲清楚它“是什么”,更会讲明白它“为什么这么设计”“遇到了哪些坑”“怎么解决的”,以及“你如何在自己的企业级前端项目中借鉴这套方案”。

2.3 读者收益 (Why)

读完这篇近 10 万字的深度技术文章,你将获得以下硬核收益:

  1. 理论层面:掌握马尔可夫链(特别是一阶马尔可夫链、隐马尔可夫链、混合马尔可夫链)在用户行为预测中的核心原理,理解 LRU-K、LFU、TTL 等缓存淘汰策略如何与预测算法结合使用;
  2. 算法层面:能够看懂 Harness 智能预加载的预测算法源码,学会如何在实际项目中训练和优化基于访问模式的用户行为预测模型;
  3. 工程层面:了解企业级前端项目中智能预加载的架构设计,包括前端数据采集层、后端模型训练层、前后端协作的预加载触发层、资源加载与监控层的实现细节;
  4. 实践层面:通过模拟 Harness 的页面访问场景,动手实现一个简化版的智能预加载组件,并学会如何用 Lighthouse、Web Vitals 等工具监控预加载的效果;
  5. 拓展层面:了解智能预加载在企业级 CI/CD 平台中的边界与局限性,以及未来可能的发展方向(如结合 GPT-4 等大语言模型的语义化预加载)。

3. 准备工作 (Prerequisites)

3.1 技术栈/知识要求

为了更好地理解本文的内容,建议你具备以下技术栈和基础知识:

  1. 前端基础:熟悉 React、Vue 或 Angular 等主流前端框架中的任意一种,掌握组件生命周期、路由跳转机制、静态资源预加载(<link rel="preload/prefetch/prerender">)、Service Worker 等前端性能优化技术;
  2. 后端基础:了解 RESTful API、WebSocket、Redis 缓存、数据库查询优化等后端技术,有 Python、Node.js 或 Go 语言开发经验者更佳;
  3. 机器学习基础:熟悉统计学中的概率、条件概率、贝叶斯公式,了解马尔可夫链、聚类算法(如 K-Means)、时间序列分析等基础机器学习算法(不需要深入了解底层数学推导,但至少要知道它们的应用场景);
  4. CI/CD 基础:对 CI/CD 流程有基本的了解,知道 Harness、Jenkins、GitLab CI 等工具的核心功能模块(如管道配置、执行详情、触发器、监控面板等)。

3.2 环境/工具要求

如果你想动手实现本文中的简化版智能预加载组件,需要提前安装以下环境和工具:

  1. 开发环境
    • Node.js 18+(包含 npm 9+ 或 yarn 3+);
    • Python 3.10+(包含 pip 23+);
    • Redis 7+(用于缓存页面访问数据和预测结果);
  2. 开发工具
    • VS Code(推荐安装 Prettier、ESLint、Python 插件);
    • Git;
    • Postman 或 Apifox(用于测试后端 API);
  3. 监控工具
    • Lighthouse(用于测量 Web Vitals:FCP、LCP、CLS、FID、INP);
    • Chrome DevTools(Network 面板、Performance 面板、Application 面板);
    • Harness Developer Portal 的公开演示环境(可选,用于观察真实的智能预加载效果:https://app.harness.io/ng/#/)。

4. 核心概念:从“预加载”到“智能预加载”的本质飞跃

4.1 核心概念

4.1.1 什么是“预加载(Preloading)”?

在前端性能优化领域,预加载是指在用户明确需要某个资源之前,提前将该资源下载到浏览器缓存中的技术。根据资源的“紧急程度”和“确定性”,预加载可以分为以下几种类型:

预加载类型 HTML 属性 资源优先级 确定性要求 典型应用场景
强制预加载 <link rel="preload"> 高(仅次于 CSS、JS) 极高(100% 确定用户会用到) 预加载当前页面必须的关键 JS/CSS 资源、字体文件、首屏视频的前 10 帧
推测预加载 <link rel="prefetch"> 低(空闲时加载) 中等(50%-90% 确定用户会用到) 预加载用户可能访问的下一个页面的路由组件、静态图片、API 响应的缓存数据
预渲染 <link rel="prerender"> 最高(会在后台打开一个隐藏的 Tab) 极高(90%+ 确定用户会用到) 预加载并渲染用户极大概率访问的下一个页面(如电商网站的“加入购物车”后的“结算页”)
预连接 <link rel="preconnect">/<link rel="dns-prefetch"> 高(只建立连接,不下载资源) 低(只要可能请求该域名的资源) 预连接用户可能访问的第三方 CDN 域名、API 域名(如 Harness 连接的 AWS ECR、Docker Hub 域名)
4.1.2 什么是“基于规则的预加载(Rule-based Preloading)”?

基于规则的预加载是最早出现的预加载优化方案,它通过人工设定的固定规则来决定预加载哪些资源。典型的规则包括:

  1. 路由规则:预加载当前路由的下一个/上一个路由组件(如 Vue Router 的 <keep-alive>+<link rel="prefetch">);
  2. 内容规则:预加载当前页面的下一页分页数据、当前列表中前 3 个详情页的静态资源;
  3. 时间规则:预加载用户访问频率最高的时间段内常用的资源;
  4. 设备规则:根据用户的设备类型(手机/平板/电脑)、网络条件(4G/5G/Wi-Fi)决定预加载的资源大小和数量。

基于规则的预加载的优点是实现简单、可控性强、没有额外的机器学习成本;缺点是规则固定、无法适应不同用户的个性化行为、无法应对突发的访问模式变化——例如,一个 QA 工程师在 Harness 中的访问模式可能是“提交测试用例→查看测试报告→触发回归测试→查看执行详情→提交 Bug 修复→部署到测试环境”,而一个 DevOps 工程师的访问模式可能是“查看集群监控→配置管道触发器→修改环境变量→部署到生产环境→回滚到上一个版本→查看回滚日志”,基于规则的预加载无法同时满足这两种完全不同的用户需求。

4.1.3 什么是“基于页面访问模式的智能预加载(Smart Preloading based on Page Access Patterns)”?

基于页面访问模式的智能预加载是在基于规则的预加载的基础上,引入机器学习算法来分析用户的历史页面访问数据预测用户下一秒要访问的页面,然后根据预测结果的置信度(Confidence Score) 决定预加载哪些资源(置信度高的用 <link rel="preload"><link rel="prerender">,置信度中等的用 <link rel="prefetch">,置信度低的不预加载)。

与基于规则的预加载相比,基于页面访问模式的智能预加载具有以下核心优势

  1. 个性化:可以为每个用户建立专属的访问模式模型,满足不同用户的个性化需求;
  2. 自适应:可以自动学习用户的访问模式变化(如一个新入职的工程师从“学习管道配置”逐渐转向“日常部署管理”),并实时更新预测模型;
  3. 高准确率:通过使用马尔可夫链、隐马尔可夫链、混合马尔可夫链等时间序列预测算法,可以显著提高预测的准确率;
  4. 高资源利用率:只预加载置信度高的资源,避免了基于规则的预加载可能带来的“预加载过多资源导致带宽浪费、缓存污染”的问题。
4.1.4 Harness 智能预加载的核心定位

Harness 作为全球领先的企业级 CI/CD 平台,其智能预加载的核心定位是:在不增加用户设备负担、不浪费带宽和服务器资源的前提下,将核心功能模块的页面切换延迟从 2-3 秒降低到 100ms 以内,提升百万级企业用户的工作效率


4.2 问题背景

4.2.1 企业级 CI/CD 平台的性能挑战

在深入了解 Harness 的智能预加载机制之前,我们先来看一下企业级 CI/CD 平台普遍面临的性能挑战,这些挑战也是 Harness 开发智能预加载的根本原因

4.2.1.1 功能模块极为分散,页面跳转频繁

企业级 CI/CD 平台通常包含几十个甚至上百个功能模块,例如:

  • 核心模块:管道管理(Pipeline Management)、执行详情(Execution Details)、环境管理(Environment Management)、服务管理(Service Management)、基础设施管理(Infrastructure Management);
  • 辅助模块:配置管理(Configuration Management)、密钥管理(Secret Management)、触发器设置(Trigger Settings)、监控面板(Monitoring Dashboard)、日志查询(Log Query)、测试管理(Test Management)、Bug 追踪集成(Bug Tracking Integration)、Git 集成(Git Integration);
  • 高级模块:混沌工程(Chaos Engineering)、持续安全(Continuous Security)、持续验证(Continuous Verification)、成本管理(Cost Management)。

而企业用户(特别是 DevOps 工程师、SRE 工程师、QA 工程师)在日常工作中,需要频繁在这些功能模块间来回跳转——根据 Harness 内部的用户行为数据分析,平均每个活跃用户每天要在平台内跳转 200-500 次页面,其中 60% 以上的跳转是在 5 个以内的核心功能模块之间进行的。

4.2.1.2 页面资源加载量大,初始化时间长

企业级 CI/CD 平台的页面通常包含大量的静态资源和动态数据

  • 静态资源:复杂的 React/Vue 组件库、图表库(如 Chart.js、ECharts、Grafana UI)、富文本编辑器、代码高亮库、多语言翻译文件;
  • 动态数据:当前用户的权限信息、项目信息、管道列表、执行历史、环境变量、监控指标、日志数据。

根据 Harness 内部的 Lighthouse 测试数据,在 Wi-Fi 6 网络、MacBook Pro M2 设备上,一个未优化的“管道执行详情”页面的 FCP(First Contentful Paint,首次内容绘制) 约为 1.5-2.0 秒LCP(Largest Contentful Paint,最大内容绘制) 约为 2.5-3.0 秒INP(Interaction to Next Paint,交互到下一次绘制) 约为 300-500ms——而根据 Google 的 Web Vitals 标准,优秀的 FCP 应该 ≤1.8 秒,优秀的 LCP 应该 ≤2.5 秒,优秀的 INP 应该 ≤200ms,未优化的 Harness 页面勉强达到“合格”标准,但离“优秀”还有很大的差距。

4.2.1.3 用户设备和网络条件差异巨大

Harness 的用户遍布全球各地,包括大型互联网公司、金融机构、制造业企业、政府部门等,他们使用的设备和网络条件差异巨大:

  • 设备条件:从老旧的 Windows 7 笔记本电脑、Android 5 手机,到最新的 MacBook Pro M3 Ultra、iPhone 15 Pro Max;
  • 网络条件:从 2G/3G 移动网络、不稳定的卫星网络,到 5G 移动网络、Wi-Fi 6/7 企业网络。

基于规则的预加载无法适应这种巨大的差异——例如,如果在 2G 网络下预加载过大的资源,会导致当前页面的加载速度变慢,甚至出现卡顿;如果在 Wi-Fi 6 网络下只预加载少量的资源,又无法充分发挥网络的优势。

4.2.1.4 数据实时性要求高,缓存策略难以平衡

企业级 CI/CD 平台的很多数据(如管道执行状态、监控指标、日志数据)实时性要求极高——例如,一个用户提交完一个紧急 Bug 修复后,需要立即看到部署进度;一个 SRE 工程师需要实时监控集群的 CPU、内存、磁盘使用率,以便及时发现和解决问题。

但另一方面,频繁的 API 请求会给服务器带来巨大的压力,也会增加用户的等待时间——因此,如何在“数据实时性”和“服务器压力、用户等待时间”之间找到一个平衡,是企业级 CI/CD 平台面临的另一个重大挑战。

4.2.2 Harness 之前尝试过的预加载方案及其局限性

在开发基于页面访问模式的智能预加载之前,Harness 团队尝试过以下几种预加载方案,但都存在一定的局限性:

4.2.2.1 基于路由的 <keep-alive> 预加载

Harness 最早使用的是 Vue.js(后来迁移到了 React,但早期的经验对后来的开发有很大的借鉴意义),所以首先尝试的是 Vue Router 的 <keep-alive> 组件——它可以将用户访问过的路由组件缓存到内存中,当用户再次访问该路由时,直接从内存中读取组件,不需要重新初始化。

局限性

  1. 内存占用过大:如果用户访问过很多路由组件,<keep-alive> 会将这些组件全部缓存到内存中,导致浏览器的内存占用急剧增加,甚至出现内存泄漏;
  2. 只能缓存访问过的组件:无法缓存用户还没有访问过的组件,对首次访问的页面没有任何优化效果;
  3. 无法实时更新缓存数据:缓存的组件中的数据是静态的,无法实时更新(除非手动触发更新),无法满足数据实时性要求高的场景。
4.2.2.2 基于规则的 <link rel="prefetch"> 预加载

后来,Harness 团队又尝试了基于规则的 <link rel="prefetch"> 预加载——他们根据用户的角色(如 DevOps 工程师、SRE 工程师、QA 工程师)设定了固定的预加载规则,例如:

  • DevOps 工程师:预加载“管道管理”“执行详情”“环境管理”“服务管理”四个核心模块的路由组件;
  • SRE 工程师:预加载“监控面板”“日志查询”“基础设施管理”“混沌工程”四个核心模块的路由组件;
  • QA 工程师:预加载“测试管理”“执行详情”“Bug 追踪集成”“触发器设置”四个核心模块的路由组件。

局限性

  1. 规则固定,无法适应个性化需求:例如,一个 DevOps 工程师可能同时负责“管道配置”和“混沌工程”,但基于角色的规则只会预加载前者,不会预加载后者;
  2. 无法应对突发的访问模式变化:例如,一个新入职的工程师前一周主要在“学习管道配置”,但第二周开始转向“日常部署管理”,基于角色的规则需要手动更新才能生效;
  3. 预加载资源过多,导致带宽浪费和缓存污染:基于角色的规则会预加载 4 个核心模块的路由组件,每个组件的大小约为 500KB-1MB,总共需要预加载 2MB-4MB 的资源——如果用户使用的是 2G/3G 网络,这些预加载的资源会占用大量的带宽,导致当前页面的加载速度变慢;如果用户的浏览器缓存空间有限,这些预加载的资源还会覆盖掉当前页面需要的关键资源,导致缓存污染。
4.2.2.3 基于热门页面的预加载

再后来,Harness 团队又尝试了基于热门页面的预加载——他们分析了所有用户的历史页面访问数据,找出了访问频率最高的 10 个页面,然后为所有用户预加载这 10 个页面的路由组件。

局限性

  1. 没有个性化,无法满足小众用户的需求:例如,一个负责“持续安全”的工程师的访问频率最高的页面可能是“漏洞扫描报告”,但这个页面不在热门页面的前 10 名,所以不会被预加载;
  2. 同样存在预加载资源过多的问题:10 个热门页面的路由组件总共需要预加载 5MB-10MB 的资源,带宽浪费和缓存污染的问题更加严重。

4.3 问题描述

经过对之前尝试过的预加载方案的总结和分析,Harness 团队将需要解决的核心问题归纳为以下 5 个方面:

4.3.1 问题一:如何为每个用户建立专属的、自适应的页面访问模式模型?

不同的用户有不同的页面访问模式,同一个用户的页面访问模式也会随着时间的推移而变化——因此,我们需要为每个用户建立专属的页面访问模式模型,并且这个模型能够自动学习用户的访问模式变化,实时更新预测结果。

4.3.2 问题二:如何选择合适的机器学习算法来预测用户下一秒要访问的页面?

页面访问数据是一种时间序列数据(Time Series Data)——它具有顺序性(用户的页面访问是有先后顺序的)和相关性(用户下一秒要访问的页面通常与当前访问的页面、甚至前几页访问的页面有关)。因此,我们需要选择一种适合处理时间序列数据、能够捕捉页面访问顺序性和相关性的机器学习算法。

4.3.3 问题三:如何根据用户的设备条件和网络条件动态调整预加载策略?

不同的用户有不同的设备条件和网络条件——因此,我们需要根据用户的设备性能(CPU 核心数、内存大小、GPU 性能)网络类型(2G/3G/4G/5G/Wi-Fi)网络速度(下载速度、上传速度、延迟) 动态调整预加载策略,包括:

  1. 预加载的资源类型(路由组件、静态图片、API 响应的缓存数据、字体文件等);
  2. 预加载的资源大小
  3. 预加载的资源数量
  4. 预加载的优先级<link rel="preload">/<link rel="prerender">/<link rel="prefetch">)。
4.3.4 问题四:如何在“数据实时性”和“服务器压力、用户等待时间”之间找到平衡?

企业级 CI/CD 平台的很多数据实时性要求极高,但频繁的 API 请求会给服务器带来巨大的压力,也会增加用户的等待时间——因此,我们需要:

  1. 只预加载置信度高的页面的 API 响应的缓存数据
  2. 为预加载的 API 响应的缓存数据设定合理的 TTL(Time To Live,生存时间)
  3. 当用户访问预加载的页面时,先显示缓存数据,然后在后台请求最新的数据并更新缓存和页面(即“ stale-while-revalidate ”策略)。
4.3.5 问题五:如何监控预加载的效果,避免预加载带来的负面影响?

预加载虽然可以提升用户体验,但如果预加载策略不当,也会带来一些负面影响,例如:

  1. 带宽浪费:预加载了用户不会用到的资源;
  2. 缓存污染:预加载的资源覆盖掉了当前页面需要的关键资源;
  3. 当前页面加载速度变慢:预加载的资源占用了大量的带宽和 CPU/GPU 资源;
  4. 内存占用过大:预加载的路由组件和缓存数据占用了大量的内存。

因此,我们需要建立一套完善的预加载监控系统,监控以下指标:

  1. 预加载准确率:预加载的资源被用户实际使用的比例;
  2. 预加载资源利用率:预加载的资源的下载完成率、被使用的时间占比;
  3. Web Vitals 指标:FCP、LCP、CLS、FID、INP 的变化;
  4. 服务器压力指标:API 请求的 QPS(Queries Per Second,每秒查询率)、响应时间、错误率的变化;
  5. 用户体验指标:用户的页面跳转等待时间、页面跳转次数、平台使用时长的变化。

4.4 问题解决:Harness 智能预加载的整体解决方案

为了解决上述 5 个核心问题,Harness 团队设计了一套完整的、端到端的智能预加载解决方案,该方案分为5 个核心层次

4.4.1 整体解决方案架构图

首先,我们来看一下 Harness 智能预加载的整体解决方案架构图(使用 Mermaid 绘制):

渲染错误: Mermaid 渲染失败: Parsing failed: Lexer error on line 2, column 11: unexpected character: ->前<- at offset: 28, skipped 4 characters. Lexer error on line 2, column 29: unexpected character: ->)<- at offset: 46, skipped 7 characters. Lexer error on line 3, column 15: unexpected character: ->数<- at offset: 68, skipped 7 characters. Lexer error on line 3, column 44: unexpected character: ->)<- at offset: 97, skipped 5 characters. Lexer error on line 4, column 43: unexpected character: ->[<- at offset: 145, skipped 9 characters. Lexer error on line 5, column 41: unexpected character: ->[<- at offset: 195, skipped 9 characters. Lexer error on line 6, column 59: unexpected character: ->[<- at offset: 263, skipped 9 characters. Lexer error on line 7, column 44: unexpected character: ->&<- at offset: 316, skipped 1 characters. Lexer error on line 7, column 61: unexpected character: ->[<- at offset: 333, skipped 10 characters. Lexer error on line 8, column 15: unexpected character: ->预<- at offset: 358, skipped 8 characters. Lexer error on line 8, column 49: unexpected character: ->)<- at offset: 392, skipped 5 characters. Lexer error on line 9, column 45: unexpected character: ->[<- at offset: 442, skipped 7 characters. Lexer error on line 10, column 55: unexpected character: ->[<- at offset: 504, skipped 8 characters. Lexer error on line 11, column 49: unexpected character: ->[<- at offset: 561, skipped 7 characters. Lexer error on line 12, column 15: unexpected character: ->预<- at offset: 583, skipped 8 characters. Lexer error on line 12, column 50: unexpected character: ->)<- at offset: 618, skipped 5 characters. Lexer error on line 13, column 33: unexpected character: ->[<- at offset: 656, skipped 6 characters. Lexer error on line 14, column 41: unexpected character: ->[<- at offset: 703, skipped 7 characters. Lexer error on line 15, column 43: unexpected character: ->[<- at offset: 753, skipped 7 characters. Lexer error on line 17, column 11: unexpected character: ->后<- at offset: 776, skipped 4 characters. Lexer error on line 17, column 28: unexpected character: ->)<- at offset: 793, skipped 2 characters. Lexer error on line 17, column 43: unexpected character: ->/<- at offset: 808, skipped 1 characters. Lexer error on line 17, column 54: unexpected character: ->]<- at offset: 819, skipped 1 characters. Lexer error on line 18, column 15: unexpected character: ->数<- at offset: 835, skipped 7 characters. Lexer error on line 18, column 41: unexpected character: ->)<- at offset: 861, skipped 5 characters. Lexer error on line 19, column 37: unexpected character: ->[<- at offset: 903, skipped 9 characters. Lexer error on line 20, column 49: unexpected character: ->[<- at offset: 961, skipped 10 characters. Lexer error on line 21, column 37: unexpected character: ->[<- at offset: 1008, skipped 6 characters. Lexer error on line 22, column 47: unexpected character: ->[<- at offset: 1061, skipped 8 characters. Lexer error on line 23, column 15: unexpected character: ->数<- at offset: 1084, skipped 7 characters. Lexer error on line 23, column 44: unexpected character: ->)<- at offset: 1113, skipped 5 characters. Lexer error on line 24, column 39: unexpected character: ->[<- at offset: 1157, skipped 7 characters. Lexer error on line 25, column 47: unexpected character: ->[<- at offset: 1211, skipped 7 characters. Lexer error on line 26, column 39: unexpected character: ->[<- at offset: 1257, skipped 7 characters. Lexer error on line 27, column 15: unexpected character: ->模<- at offset: 1279, skipped 7 characters. Lexer error on line 27, column 43: unexpected character: ->)<- at offset: 1307, skipped 5 characters. Lexer error on line 28, column 43: unexpected character: ->[<- at offset: 1355, skipped 7 characters. Lexer error on line 29, column 41: unexpected character: ->[<- at offset: 1403, skipped 7 characters. Lexer error on line 30, column 45: unexpected character: ->[<- at offset: 1455, skipped 7 characters. Lexer error on line 31, column 41: unexpected character: ->[<- at offset: 1503, skipped 7 characters. Lexer error on line 32, column 18: unexpected character: ->服<- at offset: 1528, skipped 5 characters. Lexer error on line 32, column 41: unexpected character: ->)<- at offset: 1551, skipped 5 characters. Lexer error on line 33, column 33: unexpected character: ->[<- at offset: 1589, skipped 3 characters. Lexer error on line 33, column 39: unexpected character: ->]<- at offset: 1595, skipped 1 characters. Lexer error on line 34, column 43: unexpected character: ->[<- at offset: 1639, skipped 3 characters. Lexer error on line 34, column 49: unexpected character: ->]<- at offset: 1645, skipped 1 characters. Lexer error on line 35, column 43: unexpected character: ->[<- at offset: 1689, skipped 3 characters. Lexer error on line 35, column 49: unexpected character: ->]<- at offset: 1695, skipped 1 characters. Lexer error on line 37, column 11: unexpected character: ->监<- at offset: 1712, skipped 7 characters. Lexer error on line 37, column 29: unexpected character: ->&<- at offset: 1730, skipped 1 characters. Lexer error on line 37, column 45: unexpected character: ->)<- at offset: 1746, skipped 1 characters. Lexer error on line 38, column 51: unexpected character: ->[<- at offset: 1813, skipped 6 characters. Lexer error on line 39, column 35: unexpected character: ->[<- at offset: 1854, skipped 6 characters. Lexer error on line 40, column 43: unexpected character: ->[<- at offset: 1903, skipped 6 characters. Parse error on line 2, column 24: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'L' Parse error on line 2, column 36: Expecting token of type ':' but found ` `. Parse error on line 3, column 27: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Collection' Parse error on line 3, column 38: Expecting token of type ':' but found `Module`. Parse error on line 4, column 30: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'outer' Parse error on line 4, column 36: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'T' Parse error on line 4, column 52: Expecting token of type ':' but found ` `. Parse error on line 5, column 28: Expecting token of type 'ARROW_DIRECTION' but found `Click`. Parse error on line 5, column 35: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'racker' Parse error on line 6, column 38: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'esource' Parse error on line 6, column 46: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Usage' Parse error on line 6, column 52: Expecting token of type ':' but found `T`. Parse error on line 6, column 53: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'racker' Parse error on line 7, column 37: Expecting token of type 'ARROW_DIRECTION' but found `Device`. Parse error on line 7, column 46: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Network' Parse error on line 7, column 54: Expecting token of type ':' but found `T`. Parse error on line 7, column 55: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'racker' Parse error on line 8, column 34: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Decision' Parse error on line 8, column 43: Expecting token of type ':' but found `Module`. Parse error on line 9, column 30: Expecting token of type 'ARROW_DIRECTION' but found `Model`. Parse error on line 9, column 37: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'equester' Parse error on line 10, column 35: Expecting token of type 'ARROW_DIRECTION' but found `Confidence`. Parse error on line 10, column 46: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Evaluator' Parse error on line 10, column 63: Expecting token of type ':' but found ` `. Parse error on line 11, column 32: Expecting token of type 'ARROW_DIRECTION' but found `Strategy`. Parse error on line 11, column 41: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Adjuster' Parse error on line 11, column 56: Expecting token of type ':' but found ` `. Parse error on line 12, column 34: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Execution' Parse error on line 12, column 44: Expecting token of type ':' but found `Module`. Parse error on line 13, column 24: Expecting token of type 'ARROW_DIRECTION' but found `Preloader`. Parse error on line 14, column 28: Expecting token of type 'ARROW_DIRECTION' but found `Cache`. Parse error on line 14, column 34: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Manager' Parse error on line 14, column 48: Expecting token of type ':' but found ` `. Parse error on line 15, column 29: Expecting token of type 'ARROW_DIRECTION' but found `Service`. Parse error on line 15, column 37: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Worker' Parse error on line 15, column 50: Expecting token of type ':' but found ` `. Parse error on line 17, column 15: Expecting token of type 'ID' but found `B`. Parse error on line 17, column 23: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'L' Parse error on line 17, column 30: Expecting token of type ':' but found `Harness`. Parse error on line 17, column 38: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Cloud' Parse error on line 17, column 44: Expecting token of type ':' but found `On-Premise`. Parse error on line 18, column 27: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Storage' Parse error on line 18, column 35: Expecting token of type ':' but found `Module`. Parse error on line 19, column 27: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'aw' Parse error on line 19, column 30: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Data' Parse error on line 19, column 35: Expecting token of type ':' but found `DB`. Parse error on line 20, column 32: Expecting token of type 'ARROW_DIRECTION' but found `Processed`. Parse error on line 20, column 42: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Data' Parse error on line 20, column 47: Expecting token of type ':' but found `DB`. Parse error on line 21, column 26: Expecting token of type 'ARROW_DIRECTION' but found `Model`. Parse error on line 21, column 32: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Cache' Parse error on line 21, column 43: Expecting token of type ':' but found ` `. Parse error on line 22, column 31: Expecting token of type 'ARROW_DIRECTION' but found `Prediction`. Parse error on line 22, column 42: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Cache' Parse error on line 22, column 55: Expecting token of type ':' but found ` `. Parse error on line 23, column 27: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Processing' Parse error on line 23, column 38: Expecting token of type ':' but found `Module`. Parse error on line 24, column 27: Expecting token of type 'ARROW_DIRECTION' but found `Data`. Parse error on line 24, column 32: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Cleaner' Parse error on line 24, column 46: Expecting token of type ':' but found ` `. Parse error on line 25, column 31: Expecting token of type 'ARROW_DIRECTION' but found `Data`. Parse error on line 25, column 37: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'ransformer' Parse error on line 26, column 27: Expecting token of type 'ARROW_DIRECTION' but found `Data`. Parse error on line 26, column 32: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Sampler' Parse error on line 26, column 46: Expecting token of type ':' but found ` `. Parse error on line 27, column 28: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'T' Parse error on line 27, column 37: Expecting token of type ':' but found `Module`. Parse error on line 28, column 29: Expecting token of type 'ARROW_DIRECTION' but found `Model`. Parse error on line 28, column 35: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Selector' Parse error on line 28, column 50: Expecting token of type ':' but found ` `. Parse error on line 29, column 28: Expecting token of type 'ARROW_DIRECTION' but found `Model`. Parse error on line 29, column 35: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'rainer' Parse error on line 30, column 30: Expecting token of type 'ARROW_DIRECTION' but found `Model`. Parse error on line 30, column 36: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Evaluator' Parse error on line 30, column 52: Expecting token of type ':' but found ` `. Parse error on line 31, column 28: Expecting token of type 'ARROW_DIRECTION' but found `Model`. Parse error on line 31, column 34: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Updater' Parse error on line 31, column 48: Expecting token of type ':' but found ` `. Parse error on line 32, column 23: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'API' Parse error on line 32, column 27: Expecting token of type ':' but found `Service`. Parse error on line 32, column 35: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Module' Parse error on line 32, column 46: Expecting token of type ':' but found ` `. Parse error on line 33, column 24: Expecting token of type 'ARROW_DIRECTION' but found `Model`. Parse error on line 33, column 30: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'API' Parse error on line 33, column 36: Expecting token of type ':' but found `API`. Parse error on line 34, column 29: Expecting token of type 'ARROW_DIRECTION' but found `Prediction`. Parse error on line 34, column 40: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'API' Parse error on line 34, column 46: Expecting token of type ':' but found `API`. Parse error on line 35, column 29: Expecting token of type 'ARROW_DIRECTION' but found `Monitoring`. Parse error on line 35, column 40: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'API' Parse error on line 35, column 46: Expecting token of type ':' but found `API`. Parse error on line 37, column 31: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Analysis' Parse error on line 37, column 40: Expecting token of type ':' but found `L`. Parse error on line 37, column 41: Expecting: one of these possible Token sequences: 1. [--] 2. [-] but found: 'ayer' Parse error on line 37, column 46: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: '[Harness Cloud]' Parse error on line 38, column 31: Expecting token of type 'ARROW_DIRECTION' but found `Monitoring`. Parse error on line 38, column 42: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'Dashboard' Parse error on line 38, column 57: Expecting token of type ':' but found ` `. Parse error on line 39, column 23: Expecting token of type 'ARROW_DIRECTION' but found `Alert`. Parse error on line 39, column 29: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'System' Parse error on line 39, column 41: Expecting token of type ':' but found ` `. Parse error on line 40, column 27: Expecting token of type 'ARROW_DIRECTION' but found `Analytics`. Parse error on line 40, column 37: Expecting: one of these possible Token sequences: 1. [NEWLINE] 2. [EOF] but found: 'System' Parse error on line 40, column 49: Expecting token of type ':' but found ` `. Parse error on line 42, column 20: Expecting token of type ':' but found `--`. Parse error on line 42, column 24: Expecting token of type 'ARROW_DIRECTION' but found `raw_data_db`. Parse error on line 43, column 19: Expecting token of type ':' but found `--`. Parse error on line 43, column 23: Expecting token of type 'ARROW_DIRECTION' but found `raw_data_db`. Parse error on line 44, column 28: Expecting token of type ':' but found `--`. Parse error on line 44, column 32: Expecting token of type 'ARROW_DIRECTION' but found `raw_data_db`. Parse error on line 45, column 28: Expecting token of type ':' but found `--`. Parse error on line 45, column 32: Expecting token of type 'ARROW_DIRECTION' but found `raw_data_db`. Parse error on line 47, column 17: Expecting token of type ':' but found `--`. Parse error on line 47, column 21: Expecting token of type 'ARROW_DIRECTION' but found `data_cleaner`. Parse error on line 48, column 18: Expecting token of type ':' but found `--`. Parse error on line 48, column 22: Expecting token of type 'ARROW_DIRECTION' but found `data_transformer`. Parse error on line 49, column 22: Expecting token of type ':' but found `--`. Parse error on line 49, column 26: Expecting token of type 'ARROW_DIRECTION' but found `data_sampler`. Parse error on line 50, column 18: Expecting token of type ':' but found `--`. Parse error on line 50, column 22: Expecting token of type 'ARROW_DIRECTION' but found `processed_data_db`. Parse error on line 52, column 23: Expecting token of type ':' but found `--`. Parse error on line 52, column 27: Expecting token of type 'ARROW_DIRECTION' but found `model_selector`. Parse error on line 53, column 20: Expecting token of type ':' but found `--`. Parse error on line 53, column 24: Expecting token of type 'ARROW_DIRECTION' but found `model_trainer`. Parse error on line 54, column 19: Expecting token of type ':' but found `--`. Parse error on line 54, column 23: Expecting token of type 'ARROW_DIRECTION' but found `model_evaluator`. Parse error on line 55, column 21: Expecting token of type ':' but found `--`. Parse error on line 55, column 25: Expecting token of type 'ARROW_DIRECTION' but found `model_updater`. Parse error on line 56, column 19: Expecting token of type ':' but found `--`. Parse error on line 56, column 23: Expecting token of type 'ARROW_DIRECTION' but found `model_cache`. Parse error on line 57, column 17: Expecting token of type ':' but found `--`. Parse error on line 57, column 21: Expecting token of type 'ARROW_DIRECTION' but found `model_api`. Parse error on line 59, column 21: Expecting token of type ':' but found `--`. Parse error on line 59, column 25: Expecting token of type 'ARROW_DIRECTION' but found `model_api`. Parse error on line 60, column 15: Expecting token of type ':' but found `--`. Parse error on line 60, column 19: Expecting token of type 'ARROW_DIRECTION' but found `model_requester`. Parse error on line 61, column 21: Expecting token of type ':' but found `--`. Parse error on line 61, column 25: Expecting token of type 'ARROW_DIRECTION' but found `confidence_evaluator`. Parse error on line 62, column 26: Expecting token of type ':' but found `--`. Parse error on line 62, column 30: Expecting token of type 'ARROW_DIRECTION' but found `strategy_adjuster`. Parse error on line 63, column 28: Expecting token of type ':' but found `--`. Parse error on line 63, column 32: Expecting token of type 'ARROW_DIRECTION' but found `strategy_adjuster`. Parse error on line 64, column 23: Expecting token of type ':' but found `--`. Parse error on line 64, column 27: Expecting token of type 'ARROW_DIRECTION' but found `preloader`. Parse error on line 65, column 15: Expecting token of type ':' but found `--`. Parse error on line 65, column 19: Expecting token of type 'ARROW_DIRECTION' but found `cache_manager`. Parse error on line 66, column 15: Expecting token of type ':' but found `--`. Parse error on line 66, column 19: Expecting token of type 'ARROW_DIRECTION' but found `service_worker`. Parse error on line 67, column 19: Expecting token of type ':' but found `--`. Parse error on line 67, column 23: Expecting token of type 'ARROW_DIRECTION' but found `prediction_cache`. Parse error on line 68, column 22: Expecting token of type ':' but found `--`. Parse error on line 68, column 26: Expecting token of type 'ARROW_DIRECTION' but found `prediction_api`. Parse error on line 69, column 20: Expecting token of type ':' but found `--`. Parse error on line 69, column 24: Expecting token of type 'ARROW_DIRECTION' but found `processed_data_db`. Parse error on line 71, column 28: Expecting token of type ':' but found `--`. Parse error on line 71, column 32: Expecting token of type 'ARROW_DIRECTION' but found `monitoring_api`. Parse error on line 72, column 20: Expecting token of type ':' but found `--`. Parse error on line 72, column 24: Expecting token of type 'ARROW_DIRECTION' but found `analytics_system`. Parse error on line 73, column 22: Expecting token of type ':' but found `--`. Parse error on line 73, column 26: Expecting token of type 'ARROW_DIRECTION' but found `monitoring_dashboard`. Parse error on line 74, column 22: Expecting token of type ':' but found `--`. Parse error on line 74, column 26: Expecting token of type 'ARROW_DIRECTION' but found `alert_system`. Parse error on line 75, column 18: Expecting token of type ':' but found `--`. Parse error on line 75, column 22: Expecting token of type 'ARROW_DIRECTION' but found `model_updater`.
4.4.2 各核心层次的功能说明

接下来,我们对各核心层次的功能进行详细说明:

4.4.2.1 前端层(Frontend Layer)

前端层是智能预加载的入口和出口,主要负责以下 3 个功能:

  1. 数据采集:采集用户的页面访问数据、按钮点击数据、资源使用数据、设备与网络数据,并将这些数据发送到后端的数据存储模块;
  2. 预加载决策:从后端的 API 服务模块获取用户的专属访问模式模型,根据当前访问的页面、置信度评估器评估的置信度、策略调整器根据设备与网络条件调整后的预加载策略,决定预加载哪些资源;
  3. 预加载执行:根据预加载决策模块的决策结果,使用预加载器、缓存管理器、Service Worker 执行预加载操作,并将预加载的资源存储到浏览器缓存或 Service Worker 缓存中。
4.4.2.2 后端层(Backend Layer)

后端层是智能预加载的核心处理层,主要负责以下 4 个功能:

  1. 数据存储:存储前端采集的原始数据、经过数据处理模块处理后的数据、训练好的用户专属访问模式模型、预测结果;
  2. 数据处理:对前端采集的原始数据进行清洗、转换、采样,得到适合模型训练的处理后数据;
  3. 模型训练:选择合适的机器学习算法,使用处理后的数据训练用户专属的访问模式模型,评估模型的准确率,实时更新模型;
  4. API 服务:为前端提供模型获取 API、预测结果获取 API、监控数据上报 API。
4.4.2.3 监控与分析层(Monitoring & Analysis Layer)

监控与分析层是智能预加载的保障层,主要负责以下 3 个功能:

  1. 监控面板:实时展示预加载的效果指标,包括预加载准确率、预加载资源利用率、Web Vitals 指标、服务器压力指标、用户体验指标;
  2. 告警系统:当预加载的效果指标超出预设的阈值时,向 Harness 团队发送告警通知;
  3. 分析系统:对预加载的效果指标进行深入分析,找出预加载策略存在的问题,并提出优化建议,自动触发模型更新。

4.5 边界与外延

4.5.1 Harness 智能预加载的边界

任何技术都有其适用范围和局限性,Harness 的智能预加载也不例外——它的边界主要包括以下 5 个方面:

4.5.1.1 只适用于 Harness 平台的内部页面跳转

Harness 的智能预加载只适用于 Harness 平台的内部页面跳转,不适用于从外部网站(如 GitHub、Jira、Slack)跳转到 Harness 平台的页面,也不适用于从 Harness 平台跳转到外部网站的页面。

4.5.1.2 只预加载 Harness 平台的自有资源

Harness 的智能预加载只预加载 Harness 平台的自有资源(如路由组件、静态图片、API 响应的缓存数据、字体文件等),不适用于预加载第三方资源(如 GitHub 的 API 响应、Jira 的静态资源等)——因为第三方资源的加载速度和可用性不受 Harness 控制,预加载第三方资源可能会带来一些不可预测的问题。

4.5.1.3 需要用户有足够的历史页面访问数据

Harness 的智能预加载需要用户有足够的历史页面访问数据才能准确预测用户下一秒要访问的页面——通常来说,需要用户有至少 100 次以上的页面跳转历史数据,模型的准确率才能达到 60% 以上;需要用户有至少 500 次以上的页面跳转历史数据,模型的准确率才能达到 80% 以上。对于新入职的工程师(没有足够的历史页面访问数据),Harness 会使用基于角色的预加载规则作为过渡方案。

4.5.1.4 无法预测完全随机的页面访问

Harness 的智能预加载无法预测完全随机的页面访问——例如,一个用户突然想查看一个很久没有访问过的“用户设置”页面,模型的准确率会很低。对于这种完全随机的页面访问,Harness 会使用基于规则的预加载规则(如预加载当前页面的“面包屑导航”中的上一级页面)作为补充方案。

4.5.1.5 对设备性能和网络条件有一定的要求

Harness 的智能预加载对设备性能和网络条件有一定的要求——例如,如果用户使用的是老旧的 Windows 7 笔记本电脑(CPU 核心数 ≤2,内存 ≤4GB),或者使用的是 2G 移动网络(下载速度 ≤100KB/s),Harness 会完全禁用智能预加载,只使用最基本的预加载策略(如预连接第三方 CDN 域名)。

4.5.2 Harness 智能预加载的外延

虽然 Harness 的智能预加载是专门为企业级 CI/CD 平台设计的,但它的核心思想和技术架构可以外延到其他类型的企业级前端项目,例如:

  1. 企业级 ERP 系统(如 SAP、Oracle E-Business Suite):这些系统也包含几十个甚至上百个功能模块,用户需要频繁在这些功能模块间来回跳转;
  2. 企业级 CRM 系统(如 Salesforce、HubSpot):这些系统也包含大量的静态资源和动态数据,页面资源加载量大,初始化时间长;
  3. 企业级项目管理系统(如 Jira、Asana):这些系统的用户行为差异巨大,需要个性化的预加载策略;
  4. 内容管理系统(CMS)(如 WordPress、Drupal):这些系统的页面访问数据也是一种时间序列数据,可以使用马尔可夫链等算法预测用户下一秒要访问的页面。

4.6 概念结构与核心要素组成

4.6.1 智能预加载的概念结构

智能预加载的概念结构可以分为3 个层次

  1. 数据层:包括原始数据、处理后数据、模型数据、预测结果数据;
  2. 算法层:包括数据处理算法、模型选择算法、模型训练算法、模型评估算法、模型更新算法、预测算法;
  3. 应用层:包括数据采集模块、预加载决策模块、预加载执行模块、监控与分析模块。
4.6.2 智能预加载的核心要素组成

智能预加载的核心要素包括以下 7 个方面:

  1. 数据采集要素:采集用户的页面访问数据、按钮点击数据、资源使用数据、设备与网络数据;
  2. 数据处理要素:对采集到的原始数据进行清洗、转换、采样;
  3. 模型要素:选择合适的机器学习算法,训练和优化用户专属的访问模式模型;
  4. 预测要素:根据用户的当前访问页面和访问模式模型,预测用户下一秒要访问的页面;
  5. 决策要素:根据预测结果的置信度、用户的设备与网络条件,决定预加载哪些资源;
  6. 执行要素:使用预加载器、缓存管理器、Service Worker 执行预加载操作;
  7. 监控与分析要素:监控预加载的效果指标,分析预加载策略存在的问题,提出优化建议。

4.7 概念之间的关系

4.7.1 核心概念核心属性维度对比

为了更清晰地理解预加载、基于规则的预加载、基于页面访问模式的智能预加载之间的区别,我们从核心属性维度对它们进行对比(使用 Markdown 表格):

核心属性维度 预加载(Preloading) 基于规则的预加载(Rule-based Preloading) 基于页面访问模式的智能预加载(Smart Preloading)
决策依据 人工指定的资源 人工设定的固定规则 机器学习算法分析用户的历史页面访问数据
个性化程度 无(所有用户预加载相同的资源) 低(根据角色、设备等规则预加载,规则固定) 高(为每个用户建立专属的访问模式模型,规则自适应)
自适应能力 无(需要手动更新规则) 强(自动学习用户的访问模式变化,实时更新模型)
预测准确率 极高(100% 确定用户会用到强制预加载的资源) 中等(50%-90% 确定用户会用到推测预加载的资源) 高(60%-95% 确定用户会用到预加载的资源)
资源利用率 低(强制预加载利用率高,但推测预加载利用率低) 中等(预加载过多资源,利用率低) 高(只预加载置信度高的资源,利用率高)
实现复杂度 低(只需要使用 HTML 的预加载属性) 中等(需要设定固定规则,编写前端代码) 高(需要数据采集、数据处理、模型训练、前后端协作)
机器学习成本 中等(需要服务器资源、数据存储资源、算法工程师)
适用范围 所有前端项目 功能模块较少、用户行为差异较小的前端项目 功能模块较多、用户行为差异较大的企业级前端项目
4.7.2 核心概念联系的 ER 实体关系图

接下来,我们来看一下预加载、基于规则的预加载、基于页面访问模式的智能预加载之间的 ER 实体关系图(使用 Mermaid 绘制):

包含

包含

使用

使用

使用

基于

来自

属于

具有

根据

PRELOADING

RULE_BASED_PRELOADING

SMART_PRELOADING

FIXED_RULE

USER_ACCESS_PATTERN_MODEL

MACHINE_LEARNING_ALGORITHM

PROCESSED_PAGE_ACCESS_DATA

RAW_PAGE_ACCESS_DATA

USER

DEVICE_NETWORK_CONDITION

4.7.3 核心概念交互关系图

最后,我们来看一下智能预加载各核心要素之间的交互关系图(使用 Mermaid 绘制):

监控与分析层 前端预加载执行模块 前端预加载决策模块 后端API服务模块 后端模型训练模块 后端数据处理模块 后端数据存储模块 前端数据采集模块 用户 监控与分析层 前端预加载执行模块 前端预加载决策模块 后端API服务模块 后端模型训练模块 后端数据处理模块 后端数据存储模块 前端数据采集模块 用户 初始化阶段(用户首次登录 Harness 平台) alt [用户有足够的历史页面访问数据] [用户没有足够的历史页面访问数据] 日常使用阶段(用户在 Harness 平台内跳转页面) alt [有缓存预测结果] [没有缓存预测结果] alt [预加载效果指标超出预设阈值] 页面跳转阶段(用户跳转到预测的页面 B) 登录 Harness 平台 发送用户的基本信息、设备与网络条件 检查用户是否有足够的历史页面访问数据 返回用户的专属访问模式模型 返回用户的专属访问模式模型 返回基于角色的预加载规则 返回基于角色的预加载规则 跳转到页面 A 发送页面 A 的访问数据、当前的设备与网络条件 通知预加载决策模块用户已跳转到页面 A 获取当前的设备与网络条件 获取页面 A 的预测结果 检查是否有页面 A 的缓存预测结果 返回缓存的预测结果 使用用户的专属访问模式模型预测下一页 返回预测结果 缓存预测结果 返回预测结果 评估预测结果的置信度 根据设备与网络条件调整预加载策略 发送预加载决策 执行预加载操作 发送预加载效果指标 分析预加载效果指标 触发模型更新 重新训练用户的专属访问模式模型 更新模型缓存 跳转到页面 B 通知预加载执行模块用户已跳转到页面 B 从缓存中读取页面 B 的资源 显示页面 B(几乎即时响应) 在后台请求页面 B 的最新数据 返回最新数据 更新页面 B 的数据(用户几乎无感知) 发送页面 B 的资源使用数据

4.8 数学模型:马尔可夫链在页面访问预测中的应用

4.8.1 为什么选择马尔可夫链?

在 4.3.2 问题二中,我们提到页面访问数据是一种时间序列数据,具有顺序性相关性——而马尔可夫链(Markov Chain) 是一种专门用于处理具有马尔可夫性质(Markov Property) 的时间序列数据的数学模型,非常适合用于页面访问预测。

4.8.1.1 什么是马尔可夫性质?

马尔可夫性质(也称为“无后效性”)是指:在已知当前状态的情况下,未来的状态只与当前状态有关,与过去的所有状态无关。用数学公式表示为:
P(Xn+1=xn+1∣Xn=xn,Xn−1=xn−1,…,X0=x0)=P(Xn+1=xn+1∣Xn=xn) P(X_{n+1} = x_{n+1} | X_n = x_n, X_{n-1} = x_{n-1}, \dots, X_0 = x_0) = P(X_{n+1} = x_{n+1} | X_n = x_n) P(Xn+1=xn+1Xn=xn,Xn1=xn1,,X0=x0)=P(Xn+1=xn+1Xn=xn)
其中:

  • X0,X1,…,Xn,Xn+1X_0, X_1, \dots, X_n, X_{n+1}X0,X1,,Xn,Xn+1 是一个随机变量序列,代表系统在不同时刻的状态;
  • x0,x1,…,xn,xn+1x_0, x_1, \dots, x_n, x_{n+1}x0,x1,,xn,xn+1 是系统可能处于的状态。
4.8.1.2 页面访问数据是否满足马尔可夫性质?

虽然严格来说,页面访问数据并不完全满足马尔可夫性质(用户下一秒要访问的页面通常不仅与当前访问的页面有关,还与前几页访问的页面有关),但一阶马尔可夫链(只考虑当前状态) 已经能够达到60%-80% 的预测准确率,而二阶马尔可夫链(考虑当前状态和前一个状态) 能够达到70%-90% 的预测准确率,完全

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐