滴滴-社招-2年 · 第 1 轮 · 二面

← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 本轮要点: WebWorker、Canvas 和 SVG 本轮共 10 道题。答案默认折叠,便于先自行作答。 1. 自我介绍,项目介绍 题目要点 略 参考答案 略 2. 为什么选择Vue3+TS而非React 题目要点 略 参考答案 略 3. 你们用的是什么脚手架,脚手架的基本原理了解么 题目要点 脚手架是提升工程效率、统一规范的工具 底层通过 Node.js 实现文件复制、模板注入、命令执行 常用工具:Vue CLI、CRA、Vite、自研 CLI(基于 Plop、Yeoman) 企业通常自研脚手架实现快速初始化、统一配置和组件生成 掌握核心原理(模板渲染、交互、文件操作)有助于二次开发 参考答案 考察点 面试官希望了解你是否具备工程化思维 是否熟悉当前项目所用的脚手架工具及其底层实现原理 是否理解脚手架在项目初始化、规范约定、自动化等方面的作用 是否具备定制或维护脚手架的能力 参考答案 一、常用脚手架工具及我们团队的选择 我们项目主要使用的是: Vue 项目:使用 @vue/cli、vite 或公司自研的内部模板系统 React 项目:早期使用 create-react-app,后续迁移为 Vite + 自定义模板 自研脚手架:基于 Plop.js、Yeoman、Commander 或 create-* 实现,通过 Node.js 实现项目初始化、目录结构生成、依赖安装、git 初始化等功能 二、脚手架的核心功能 初始化项目结构(生成项目目录和基础文件) 注入标准化配置(eslint、prettier、commitlint、husky、tsconfig等) 自动安装依赖(npm/yarn/pnpm install) 选择模板和功能模块(用户选择功能特性,动态生成对应模块) 自定义交互式命令行(CLI)(使用 inquirer 等库实现配置选择) 生成代码片段/组件(如 plop generate component) 三、脚手架的实现原理 脚手架本质上是基于 Node.js 脚本,通过命令行交互完成初始化和代码生成,主要原理包括: ...

July 28, 2025

滴滴-社招-2年 · 第 1 轮 · 一面

← 已是第一轮 · 返回本次面经 · 第 1 轮 → 本轮要点: 生命周期、Vue3 API、响应式原理、v-for、事件循环 本轮共 21 道题。答案默认折叠,便于先自行作答。 1. 为什么使用 而非 题目要点 <header>是HTML5语义化标签,明确头部区域含义 语义化标签有助于SEO和辅助技术识别 提高代码可读性和维护性,减少依赖类名赋予语义 推荐优先使用语义标签代替无语义的<div>+类名组合 参考答案 考察点 理解HTML语义化标签的重要性及作用 掌握语义化标签对SEO和无障碍的影响 了解语义化标签在开发协作和维护中的优势 参考答案 一、语义化标签的核心概念 HTML5引入了如 <header>、<nav>、<article>、<footer> 等语义化标签,明确表达页面结构和内容含义 语义化标签比普通 <div> 搭配类名更具意义,利于浏览器、搜索引擎、辅助设备等理解页面 二、使用 <header> 的优势 明确语义 <header>表示页面或区块的头部区域,包含标题、导航等信息 比 <div class="header"> 直接通过类名赋予语义更标准、易识别 提升可访问性 语义化标签被屏幕阅读器等辅助技术识别,帮助视障用户理解页面结构 <header>使辅助设备快速定位页眉内容,提升用户体验 SEO友好 搜索引擎利用语义标签准确抓取页面结构和重点内容 语义标签利于内容分类和权重判断,可能提高搜索排名 代码规范与维护 语义化标签增强代码自解释性,方便团队协作和代码维护 减少对类名、ID等非结构性属性的依赖,代码更简洁清晰 三、使用场景对比 <header>适合定义页面或区块的头部区域 <div class="header">仅作为普通容器,没有内置语义 两者均可通过CSS样式控制外观,但语义化标签具备结构语义 2. SEO和可访问性有何影响 题目要点 语义化标签提升SEO抓取效率和内容权重分配 结构化页面内容,增强搜索引擎对重点信息的识别能力 语义标签是辅助技术识别页面结构的关键,提升可访问性 有助于残障用户快速导航和理解页面 符合无障碍标准,降低法律和合规风险 参考答案 考察点 理解SEO(搜索引擎优化)对网页结构和内容的重要性 掌握语义化标签对搜索引擎抓取的正面影响 了解可访问性(Accessibility)概念及辅助技术如何利用语义标签 能说明如何通过结构优化提升用户体验及业务价值 参考答案 一、SEO影响 语义化标签助力搜索引擎理解页面结构 ...

July 28, 2025

滴滴-社招-1年 · 第 1 轮 · 三面

← 第 1 轮 · 返回本次面经 · 已是最后一轮 → 本轮共 15 道题。答案默认折叠,便于先自行作答。 1. 介绍一下实习项目的业务背景(这块说了蛮久) 题目要点 略 参考答案 略 2. 假如你是一个项目的负责人,面对一个新需求你会如何判断以及决策 题目要点 业务价值与需求背景明确 / 技术可行性与风险评估 / 资源与时间合理估算 多方案设计与优劣比较 / 风险预判及缓解措施 结合团队和业务做权衡决策 / 明确执行计划与责任 / 持续跟进与复盘优化 沟通协调能力和风险管理能力是关键 决策既考虑短期交付,也兼顾长期维护和团队承受能力 参考答案 考察点 评估候选人对需求分析和项目管理流程的理解 探查其在技术可行性、资源评估、风险管理等方面的判断能力 了解候选人如何在多方利益、时间与质量之间做权衡决策 关注其沟通协调和方案落地的思路 参考答案 一、需求理解与评估 明确需求背景和目标 充分沟通业务方,理解需求的业务价值、核心目标和痛点 判断该需求是新增功能、优化还是技术债清理 技术可行性分析 评估现有系统架构、技术栈对该需求的支持程度 识别技术难点和潜在风险,如性能、安全、兼容性等问题 资源与时间评估 估算开发、测试、上线所需的人力、时间和成本 考虑团队现有工作负载,排期合理性 二、方案设计与风险控制 设计多套实现方案 比较不同方案的优劣,如技术复杂度、扩展性、维护成本 结合业务优先级和技术条件选择最优方案 风险预判与缓解 识别潜在风险点,设计应对措施(如技术预研、灰度发布) 规划阶段性验收,快速反馈,减少偏差 三、决策与执行 结合业务战略和团队实际作出决策 权衡需求价值与资源限制,明确是否优先推动或延期 与产品、设计、测试等多方协作,达成共识 推动方案落地 制定详细开发计划,分解任务,明确负责人和时间节点 跟踪进展,快速解决过程中出现的问题 复盘与优化 需求完成后组织复盘,总结经验,优化流程 3. 功能上线后如何判断这个功能上线前后的影响和优化有多少呢 题目要点 明确功能目标和关键评估指标 / 多渠道数据采集与监控 功能上线前后指标对比 / A/B测试验证功能效果 用户反馈与定性分析辅助判断 定位影响原因,制定优化方案 持续监控、复盘和迭代形成闭环 兼顾数据驱动与用户体验 参考答案 考察点 理解功能上线后效果评估的重要性及方法 掌握多维度数据监控和指标分析手段 能结合业务目标设计合理的评估方案 理解A/B测试、用户行为分析、性能监控等工具的应用 关注持续优化与反馈闭环 参考答案 一、明确评估目标和关键指标(KPI) 结合业务目标确定功能上线的核心衡量指标,如用户活跃度、转化率、留存率、错误率等 设计具体可量化的指标体系,保证评估具备科学性和针对性 二、数据采集与监控 利用埋点、日志采集用户行为数据,覆盖点击、浏览、交互等关键操作 结合前端性能监控(如首屏时间、接口响应时间)与错误监控(JS报错、接口失败) 设置告警机制,实时监测异常情况 三、功能上线前后的对比分析 历史对比:将上线前后的关键指标进行趋势对比,分析变化幅度和方向 同类用户对比:如果可行,采用A/B测试,控制组与实验组对比,确保因果关系明确 用户反馈收集:结合用户调查、客服反馈等定性信息辅助判断 四、分析影响及优化空间 识别指标波动背后的具体原因,如性能瓶颈、交互体验问题等 结合用户反馈发现潜在需求或痛点 制定针对性优化方案,优先解决影响最大的瓶颈 五、持续迭代与复盘 将监控和分析形成常态化流程,确保功能优化闭环 定期复盘评估结果,总结经验教训 结合业务目标调整优化策略,持续提升功能效果 4. 有去了解过用户反馈最多的问题或者诉求最强的问题是什么吗 题目要点 略 ...

July 28, 2025

滴滴-社招-1年 · 第 1 轮 · 二面

← 第 1 轮 · 返回本次面经 · 第 1 轮 → 本轮要点: 浏览器渲染过程 本轮共 11 道题。答案默认折叠,便于先自行作答。 1. 简单介绍一下你上一段实习中觉得做的比较好的项目 题目要点 略 参考答案 略 2. 想知道你们的项目大概是什么样的结构,你在开发的时候会从什么地方下手 题目要点 理解项目结构和流程是高效开发的基础 先从入口和路由入手,理清全局数据和功能模块 注重调试和测试,减少开发盲点 合理利用团队协作工具提升开发效率 持续学习和总结,快速适应项目迭代 参考答案 考察点 理解典型前端项目的整体结构及模块划分 掌握从项目启动到开发流程的系统思路 能清晰描述如何快速定位入口及关键代码区域 展示合理的开发习惯与代码管理思路 体现对团队协作和版本控制的认知 参考答案 一、典型前端项目结构说明 目录结构 src/:项目源码,包含页面(Page)、组件(Component)、样式(Styles)、工具函数(Utils)、状态管理(Store)等 public/ 或 static/:静态资源,如图片、字体、favicon 等 build/ 或 scripts/:构建相关脚本和配置 config/:环境配置文件,如开发、测试、生产环境参数 tests/:单元测试和集成测试代码 配置文件如 package.json, .babelrc, webpack.config.js 或 vite.config.js 关键文件 入口文件(如 src/main.js、src/index.js)负责挂载应用 路由配置文件定义页面导航 状态管理文件(如 Vuex、Redux)管理全局状态 公共组件库及工具函数模块 API 接口封装层,统一管理后端请求 二、开发时的切入点及流程 理解业务和需求 先明确当前任务目标和业务逻辑 查阅需求文档、设计稿和接口文档 定位项目入口 从入口文件入手,理清项目启动流程 理解路由配置,确定目标页面 代码结构梳理 理解页面层与组件层的关系 查找关键组件和功能模块的实现 查看状态管理和数据流 ...

July 28, 2025

滴滴-社招-1年 · 第 1 轮 · 一面

← 已是第一轮 · 返回本次面经 · 第 1 轮 → 本轮要点: 响应式原理、Webpack与Vite、https、浏览器渲染过程、浏览器的缓存机制 本轮共 19 道题。答案默认折叠,便于先自行作答。 1. 介绍一下简历中的组件库项目 题目要点 略 参考答案 略 2. 聊聊 vite 和 webpack 的区别 题库原题:聊聊 vite 和 webpack 的区别 题目要点 Webpack:成熟的模块打包工具,功能强大但配置复杂,适合需要高度定制和复杂构建需求的项目。 Vite:现代化的开发工具,提供快速的开发体验和优化的生产构建,适合追求开发效率和现代化特性的项目。 选择 Vite 还是 Webpack 取决于项目的需求和开发团队的偏好。如果重点是开发体验和快速反馈,Vite 是一个很好的选择。如果需要高度定制化和广泛的插件支持,Webpack 可能更适合。 参考答案 Vite 和 Webpack 都是前端打包工具,它们的作用类似,但实现方式和使用方法有所不同。以下是它们之间的一些区别: 构建速度:Vite 的构建速度比 Webpack 更快,因为 Vite 在开发环境下使用了浏览器原生的 ES 模块加载,而不是像 Webpack 一样使用打包后的文件进行模块加载。在 Vite 中,每个模块都可以独立地进行编译和缓存,这意味着它只需要重新编译修改过的模块,而不是整个应用程序。这使得 Vite 开发起来更加高效。 配置复杂度:Vite 的配置相对更简单,因为它无需进行大量的配置,只需指定一些基本的选项就可以开始开发。Webpack 的配置更加复杂,需要针对具体项目进行不同的配置,且需要理解各种插件、Loader 等概念。 生态环境:Webpack 的生态环境更加成熟,在社区中拥有广泛的支持和丰富的插件库。而 Vite 尚处于发展阶段,尽管其已经获得了很多关注,但其生态系统仍然不太完善。 功能特性:Webpack 是一个功能更加全面的打包工具,支持各种 Loader 和插件,可以处理多种类型的文件和资源。而 Vite 的设计初衷是专注于开发环境下的快速构建,因此其对一些高级特性的支持相对较少。 综上所述,Vite 更适合用于开发环境下的快速构建,而 Webpack 则更适合用于生产环境下的复杂应用程序的打包处理。选择使用哪种工具需要根据具体项目需求进行评估。 ...

July 28, 2025

抓包工具

抓包的原理 什么是抓包? 抓包就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,通过抓包可以: 分析网络问题 业务分析 分析网络信息流通量 网络大数据金融风险控制 探测企图入侵网络的攻击 探测由内部和外部的用户滥用网络资源 探测网络入侵后的影响 监测链接互联网宽频流量 监测网络使用流量(包括内部用户,外部用户和系统) 监测互联网和用户电脑的安全状态 渗透与欺骗 … 回顾下计算机网络知识,数据在网络上是以很小的帧的单位传输的,帧通过特定的称为网络驱动程序的程序进行成型,然后通过网卡发送到网线上,通过网线到达目的机器,在目的机器的一端执行相反的过程。接收端机器的以太网捕获到这些帧,并告诉操作系统帧已到达,然后对其进行存储。在这个传输和接收的过程,就可以使用抓包工具(Sniffers)进行抓包,作为前端开发者,通常是抓取应用层的 HTTP/HTTPS 的包。 HTTP/HTTPS 抓包原理 HTTP/HTTPS 是应用层使用的通信协议,常见的应用层体系结构是客户端-服务器体系。 对运行在不同端系统上的客户端程序和服务端程序是如何互相通信的么?实际上,在操作系统上的术语中,进行通信的实际上是进程而不是程序,一个进程可以被认为是运行在端系统中的一个程序。 在 web 应用程序中,一个客户浏览器进程与一台服务器进程进行会话交换报文。 浏览器进程需要知道接收进程的主机地址,以及定义在目的主机中的接收进程的标识符,也就是目的端口。 多数应用程序由通信进程对组成,每对中的两个进程互相发送报文。进程通过一个称为套接字的软件接口向网络发送报文和从网络接收报文。 进程可以类比一座房子,而它的套接字可以是它的门,套接字是应用层与运输层之间的端口。 知道了两个进程的通信流程,我们要怎么抓包呢?举一个生活中的例子,小明暗恋小雯,于是他写了一封情书,但他有点害羞,找了小雯的好朋友小花帮忙传递情书。这个时候,小花可以负责小雯与小明之间的情书传递,作为中间人,她可以偷偷查看他们的情书内容。 思路就是设置一个中间人进程负责抓包,每次目标进程之间的会话都先与中间人进程通信,再进行转发。 HTTP 抓包原理 在 http 标准中,没有对通信端身份验证的标准。对于服务器来说,它接收的 HTTP 请求报文只要格式符合规范,就发送响应报文。 对于客户端来说也是如此,它无法校验服务器的身份,比如它连接的 http://www.jecyu.com 的主机,但由于中间节点的存在,最终连接的可能是 http://www.jerry.com 的主机。 因此,对于 HTTP 抓包,无需做过多的处理,只需要让中间人负责转发客户端和服务端的数据包。 HTTPS 抓包原理 HTTP 是明文传输,容易受到中间人攻击,不安全。 HTTPS 语义仍然是 HTTP,只不过是在 HTTP 协议栈中 http 与 tcp 之间插入安全层 SSL/TSL。 安全层采用对称加密的方式加密传输数据和非对称加密的方式来传输对称密钥,解决 http 数据没有加密、无法验证身份、数据容易纂改三个核心问题。 HTTP + 加密 + 认证 + 完整性保护 = HTTPS ...

July 28, 2025

浏览器渲染过程中的网络层面

一、梳理主干流程 知识体系中,最重要的是骨架,脉络。有了骨架后,才方便填充细节。所以,先梳理下主干流程: 浏览器接收url并开启一个新进程(这一部分可以展开浏览器的进程与线程的关系) 浏览器解析输入的 URL,提取出其中的协议、域名和路径等信息。(这部分涉及URL组成部分) 浏览器向 DNS 服务器发送请求,DNS服务器通过 多层查询 将该 域名 解析为对应的 IP地址 ,然后将请求发送到该IP地址上,与 服务器 建立连接和交换数据。(这部分涉及DNS查询) 浏览器与服务器建立 TCP 连接。(这部分涉及TCP三次握手/四次挥手/5层网络协议) 浏览器向服务器发送 HTTP 请求,包含请求头和请求体。(4,5,6,7包含http头部、响应码、报文结构、cookie等知识) 服务器接收并处理请求,并返回响应数据,包含状态码、响应头和响应体。 浏览器接收到响应数据,解析响应头和响应体,并根据状态码判断是否成功。 如果响应成功,浏览器接收到http数据包后的解析流程(这部分涉及到html - 词法分析,解析成DOM树,解析CSS生成CSSOM树(样式树),合并生成render渲染树(样式计算)。然后layout布局,分层,调用GPU绘制等,最后将绘制的结果合成最终的页面图像,显示在屏幕上。这个过程会发生回流和重绘)。 连接结束 -> 断开TCP连接 四次挥手 梳理出主干骨架,然后就需要往骨架上填充细节内容。 接下来重点介绍“浏览器渲染过程中的网络层面”。 二、浏览器接收url并开启一个新进程 这部分内容开始之前我们需要先通过一张图对 进程 和 线程 的关系有一个初步的了解。 1. 浏览器是多进程的 浏览器是多进程的,有一个主进程,每打开一个tab页面都会新开一个进程(某些情况下多个tab会合并进程)。 注意:在这里浏览器应该也有自己的优化机制,有时候打开多个tab页后,比如打开多个空白标签页。可以在Chrome任务管理器中看到,进程被合并了。 进程可能包括主进程,插件进程,GPU,tab页(浏览器内核)等等。 Browser进程:浏览器的主进程(负责协调、主控),只有一个。 第三方插件进程:每种类型的插件对应一个进程,仅当使用该插件时才创建。 GPU进程:最多一个,用于3D绘制等。 浏览器渲染进程(浏览器内核)(内部是多线程的):默认每个Tab页面一个进程,互不影响。作用是页面渲染,脚本执行,事件处理等。(浏览器有时候会优化,如多个空白页合并成一个进程) 强化记忆:在浏览器中打开一个网页相当于新起了一个进程(进程内有自己的多线程) 下图以 chrome浏览器 为例。我们可以自己通过Chrome的更多工具 =》 任务管理器 自行验证查看,可以看到chrome的任务管理器中有多个进程(分别是每一个Tab页面有一个独立的进程,以及一个主进程) 然后能看到每个进程的内存资源信息以及cpu占有率。 2. 浏览器内核是多线程的 每一个tab页面可以看作是浏览器内核的一个进程,然后这个进程是多线程的,它有几大类子线程 GUI渲染线程:负责渲染浏览器界面,解析HTML,CSS,构建DOM树和RenderObject树,布局和绘制等。GUI渲染线程与JS引擎线程是互斥的。 JS引擎线程:也叫 JS 内核,负责解析执行 JS 脚本程序的主线程,例如 V8 引擎。JS引擎一直等待着任务队列中任务的到来,然后加以处理,一个Tab页(renderer进程)中无论什么时候都只有一个JS线程在运行JS程序。 事件触发线程:属于浏览器内核线程,主要用于控制事件,例如鼠标、键盘等,当事件被触发时,就会把事件的处理函数推进事件队列,等待 JS 引擎线程执行。 定时器触发线程:主要控制 setInterval和 setTimeout,用来计时,计时完毕后,则把定时器的处理函数推进事件队列中,等待 JS 引擎线程。 异步http请求线程:通过XMLHttpRequest连接后,通过浏览器新开的一个线程,监控readyState状态变更时,如果设置了该状态的回调函数,则将该状态的处理函数推进事件队列中,等待JS引擎线程执行。 ...

July 28, 2025

网络性能优化

浏览器在加载页面时,大量的性能瓶颈集中在资源的请求、传输、解析与执行上。因此,网络层的性能优化主要目标是:减少请求次数、降低资源大小、缩短首屏时间、提升加载体验。 一、请求数量优化 1. 合理拆分和合并资源 按需加载(lazy loading / dynamic import):不一次加载所有模块,只加载当前页面/功能所需资源。 资源合并(资源打包):减少请求数量,如合并多个 CSS/JS 文件(现代工具也支持 HTTP2 下保留拆分)。 服务端渲染/预渲染:减轻首屏资源请求压力。 2. 使用缓存避免重复请求 使用浏览器缓存控制(Cache-Control、ETag、Last-Modified); 对于不变资源,设置强缓存(immutable); 对接口返回数据做缓存(前端缓存策略或 HTTP 层缓存); 本地缓存,如 IndexedDB / LocalStorage 存储接口数据。 二、资源体积优化 1. 压缩与代码优化 启用 Gzip / Brotli 压缩静态资源(HTML、CSS、JS); 压缩图像(WebP、AVIF)、字体、视频等媒体资源; 减少 polyfill 体积(如使用 core-js 按需引入); 移除无用代码(Tree Shaking、CSS Purge、babel-plugin-transform-remove-console); 2. 精简传输内容 请求接口时使用精简字段、分页、后端裁剪; GraphQL 可按需返回字段,减少冗余数据传输; 降低 Cookie 和请求头大小,避免请求体负担。 三、加载顺序与优先级优化 1. 关键资源优先加载 使用 preload、prefetch、dns-prefetch 等 <link> 标签提示浏览器提前加载; 使用 Webpack 的资源预加载配置控制打包 chunk 优先级; 首屏资源内联(inline critical CSS)避免阻塞渲染。 2. 非关键资源延后加载 图片懒加载(loading="lazy"、IntersectionObserver); JS 异步加载(<script async|defer>); 第三方 SDK、监控等可延迟初始化。 四、协议与传输层优化 1. 使用 HTTP/2 或 HTTP/3 多路复用,减少 TCP 连接数,提高并发请求效率; 头部压缩与服务器推送(HTTP/2 Push); HTTP/3 基于 QUIC,有更快的连接建立速度与更少的丢包重传。 2. 减少不必要的重定向 避免链式跳转; 减少使用 302/301 等中间状态跳转,优化首次加载路径。 五、安全策略与跨域优化 合理设置 CORS,减少 preflight 请求; 使用同源策略时避免冗余 OPTIONS 请求; 减少跨域请求带来的额外开销(如 DNS、TLS 握手等)。 六、CDN 与资源分发优化 使用 CDN 加速静态资源访问,减少物理距离造成的 RTT; 使用全局 CDN 覆盖,支持边缘缓存与智能调度; 配合版本号和 Hash 控制缓存刷新策略。 七、服务端协同优化 接口合并:多个小请求可由后端合并为一次大请求返回; 接口压缩与限流:避免无用数据占带宽; 优化接口响应结构与字段粒度; 为前端提供异步批量资源接口(如配置/字典项/用户信息等合并加载); 八、实际指标与监控优化点 首字节时间(TTFB)优化; 首屏渲染时间(FCP、LCP)优化; 页面总加载时间(Fully Loaded)优化; 网络错误率(如资源 404、接口失败率)监控; 使用 Performance API、Web Vitals、Lighthouse 工具分析网络瓶颈。 要点总结 网络优化的本质是:更快、更少、更智能地请求资源; 从请求数量、资源大小、传输协议、加载优先级、缓存策略、CDN 分发等多个维度同时入手; 优化不是单一操作,而是持续评估、定位瓶颈、迭代调整的过程; 实际开发中建议结合 Chrome DevTools、Lighthouse、Performance API 等工具进行精细化分析与验证。 常见考点 前端“网络层面的性能优化”是高频面试考点,涵盖了从资源加载、缓存、连接管理,到协议选择等多个方向。面试时往往从“用户输入 URL 到页面加载”这条链路入手,考查在网络传输环节提升页面性能的能力。 ...

July 28, 2025

http2.0 服务端推送

HTTP/2.0 的 服务端推送(Server Push) 是它相较于 HTTP/1.x 引入的一项重要功能,旨在优化网页加载性能,尤其是首次加载时资源依赖的获取效率。 一、什么是服务端推送? HTTP/2 Server Push 允许服务器主动将资源“推送”给客户端,而不是等待客户端明确请求。这在某些场景下可以预加载依赖资源、减少请求延迟,提升页面的首屏加载速度。 例如: 客户端请求了 HTML 页面,服务器可以在返回 HTML 的同时,主动推送页面所需的 CSS/JS 资源。 二、服务端推送的工作原理 流程概览: 浏览器发送主资源请求(如 HTML); 服务器识别该请求需要哪些依赖资源(如 CSS、JS); 服务器将这些资源 打包为 PUSH_PROMISE 帧 发送给客户端,声明它即将发送的资源; 客户端接收到 PUSH_PROMISE 后,会缓存该资源的响应; 当浏览器稍后真正需要这个资源时,不会再发起真实请求,而是从缓存中获取推送的内容; 避免了请求的 RTT 往返延迟。 技术细节: PUSH_PROMISE 是 HTTP/2 中新增的帧类型,用于声明服务器准备推送的资源; 所有推送的资源都绑定到一个主请求流(主页面),不能独立存在; 客户端可选择 拒绝(RST_STREAM) 不想要的推送资源; 推送资源会根据缓存策略存储在浏览器的缓存中,不一定立即使用。 三、实际示例(Nginx + Link Header) 在使用 Nginx 部署 HTTP/2 服务时,可以通过 Link 响应头启用 Server Push: location = /index.html { http2_push /style.css; http2_push /main.js; } 或者使用 Link 响应头方式: ...

July 28, 2025

http2.0/http3.0

前言 HTTP/2 相比于 HTTP/1,可以说是大幅度提高了网页的性能,只需要升级到该协议就可以减少很多之前需要做的性能优化工作,当然兼容问题以及如何优雅降级应该是国内还不普遍使用的原因之一。 虽然 HTTP/2 提高了网页的性能,但是并不代表它已经是完美的了,HTTP/3 就是为了解决 HTTP/2 所存在的一些问题而被推出来的。 一、HTTP 协议 HTTP 协议是 HyperText Transfer Protocol(超文本传输协议)的缩写,它是互联网上应用最为广泛的一种网络协议。所有的 WWW 文件都必须遵守这个标准。伴随着计算机网络和浏览器的诞生,HTTP1.0 也随之而来,处于计算机网络中的应用层,HTTP 是建立在 TCP 协议之上,所以HTTP 协议的瓶颈及其优化技巧都是基于 TCP 协议本身的特性,例如 tcp 建立连接的 3 次握手和断开连接的 4 次挥手以及每次建立连接带来的 RTT 延迟时间。 二、HTTP/1.x 的缺陷 连接无法复用:连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对大量小文件请求影响较大(没有达到最大窗口请求就被终止)。 HTTP/1.0 传输数据时,每次都需要重新建立连接,增加延迟。 HTTP/1.1 虽然加入 keep-alive 可以复用一部分连接,但域名分片等情况下仍然需要建立多个 connection,耗费资源,给服务器带来性能压力。 Head-Of-Line Blocking(HOLB):导致带宽无法被充分利用,以及后续健康请求被阻塞。HOLB是指一系列包(package)因为第一个包被阻塞;当页面中需要请求很多资源的时候,HOLB(队头阻塞)会导致在达到最大请求数量时,剩余的资源需要等待其他资源请求完成后才能发起请求。 HTTP 1.0:下个请求必须在前一个请求返回后才能发出,request-response对按序发生。显然,如果某个请求长时间没有返回,那么接下来的请求就全部阻塞了。 HTTP 1.1:尝试使用 pipeling 来解决,即浏览器可以一次性发出多个请求(同个域名,同一条 TCP 链接)。但 pipeling 要求返回是按序的,那么前一个请求如果很耗时(比如处理大图片),那么后面的请求即使服务器已经处理完,仍会等待前面的请求处理完才开始按序返回。所以,pipeling 只部分解决了 HOLB。 如上图所示,红色圈出来的请求就因域名链接数已超过限制,而被挂起等待了一段时间。 协议开销大: HTTP1.x 在使用时,header 里携带的内容过大,在一定程度上增加了传输的成本,并且每次请求 header 基本不怎么变化,尤其在移动端增加用户流量。 安全因素:HTTP1.x 在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性 三、SPDY 协议 因为 HTTP/1.x 的问题,我们会引入雪碧图、将小图内联、使用多个域名等等的方式来提高性能。不过这些优化都绕开了协议,直到 2009 年,谷歌公开了自行研发的 SPDY 协议,主要解决 HTTP/1.1 效率不高的问题。谷歌推出 SPDY,才算是正式改造 HTTP 协议本身。降低延迟,压缩 header 等等,SPDY 的实践证明了这些优化的效果,也最终带来 HTTP/2 的诞生。 ...

July 28, 2025