周末晚上的“老王家小馆”座无虚席,后厨只有三个灶眼,十桌客人在催菜。如果你是老板会怎么办?老师傅给出三招:第一,别把菜单上一百道菜全提前烧好——顾客点什么才下锅,这叫现点现做;第二,根据老客的翻牌习惯,把点击率最高的几道菜的食材提前备好——这叫备菜预判;第三,把土豆压成土豆泥粉、高汤浓缩成汤块,杂物间瞬间空出一半——这叫真空包装。把这三招装进浏览器,正是前端性能优化的三大绝技:懒加载、预加载、资源压缩。如果再配一台“顾客满意度仪表盘”(Core Web Vitals),外加一位会用数据预测点餐的 AI 店长,你的网站就能像五星餐厅一样——上菜快、不浪费、回头客多。本文就用这家小馆的后厨故事,带你吃透前端性能优化的全部门道。
理解并落地懒加载、预加载与资源压缩,是前端工程师晋升高级岗位的必修课——它直接决定页面加载速度、用户体验评分与业务转化率,是你在 AI 时代与智能工具协作优化网页时的底层沟通语言。
可视化演示
展示懒加载、预加载与资源压缩三大前端性能优化技术:Intersection Observer按需加载图片、preload/prefetch资源优先级调度、Gzip/Brotli压缩率对比与Core Web Vitals指标。
本节配有交互动效(进入视口后自动加载,约 3KB)。
懒加载可视化 Intersection Observer监测图片进入视口 仅加载可见区域资源,减少初始请求 load = isVisible ? fetch(src) : skip 懒加载可减少50%+初始加载量
性能优化概览
老王家小馆开业一个月,老板发现一个扎心规律:翻台率最高的不是菜最好吃的时段,而是上菜最快的那几天。客人等上十分钟还见不到菜,起身就走,连差评都懒得留。这就是前端世界的铁律——速度本身就是用户体验的一部分。页面加载超过三秒,半数用户会放弃;再多一秒,转化率就掉一截。优化性能,本质上是在优化用户的“等待体验”。
把网站想象成那家后厨:浏览器就是小小的灶台,网络带宽是食材运输通道,HTML/CSS/JS/图片就是一份份食材。我们要做的,不是让后厨更忙,而是让有效内容更快上桌。所谓有效内容,就是用户当前真正看到、真正需要的那部分页面——首屏文字、关键图片、核心功能。围绕这个目标,厨房里诞生了三大招数:懒加载(现点现做)、预加载(备菜预判)、资源压缩(真空包装),再加上一套指标系统来衡量上菜速度是否达标。
性能优化的收益可以凝练成一个比值:用户感知到的价值除以等待时间。等待时间越小,感知价值越大,体验评分越高。
回到小馆:老板给每桌发了一个“上菜计时器”,把等待时间量化。前端也一样,我们有 Core Web Vitals 这套官方“计时器”。记住,性能优化的第一课不是写代码,而是先建立“时间即体验”的直觉。
- 有效内容价值用户当前最需要的页面信息,比如首屏标题、主图、购买按钮。它们价值最高,要先保障。
- 用户等待时间从点击链接到页面完全可用的总耗时,包含网络请求、资源加载、浏览器渲染等环节。
- 比值关系分子大、分母小,性能感知就高。所有优化手段,最终都是围绕这个分数做文章。
图片懒加载
王老板发现,后厨最浪费的环节是“备餐台”——备餐员把一百道菜的半成品全摆上台,每道菜都占地方,可大部分直到打烊都没人点。他决定改规矩:顾客点什么,备餐员才从冷库里取什么。这就是懒加载的核心思想:按需取用,不做无用功。
网页里的图片就是那一盘盘半成品。一个长电商页面可能有上百张商品图,用户首屏只看得见五六张,其余的要滚动好几屏才出现。如果页面一打开就把一百张图全部下载,网络通道瞬间被堵死,首屏反而出不来。懒加载的做法是:图片进入视口(浏览器可视区域)附近时才开始下载,没出现在视口里的图片先按兵不动。
落地懒加载目前有两大法门。一是浏览器原生属性 loading="lazy",给 <img> 标签加上它,浏览器自动判断;二是更精细的 JavaScript 方案——Intersection Observer,它是浏览器提供的“视口哨兵”,专门监听元素与视口的交叉状态,当图片出现在预设范围时触发加载回调。判定逻辑可以写成:
其中 $\rho$ 是图片与视口的相交比例,$\theta$ 是预设阈值。
懒加载省下的流量相当可观。假设一百张图总重 20MB,首屏只用了 2MB,剩余 90% 的流量按需分配。回到小馆,这就是“备餐台终于清爽了,客人翻台率反而上去了”。要注意的是,首屏关键图片(比如主视觉横幅)必须立即加载,把它们也懒加载就本末倒置了——那相当于把招牌菜也藏进冷库,客人来了还得等解冻。
- 相交比例 ρ图片可见部分占其总面积的比例,取值范围 0 到 1。滚动后图片露出一半,ρ 就是 0.5。
- 阈值 θ预先设定的加载触发线,比如 0.1,表示图片露出 10% 就该加载了。
- 条件判定当 ρ > θ 时,加载标记为 1(触发加载);否则为 0(继续等待)。
资源预加载
王老板后来发现,光是“现点现做”还不够快。老主顾老张每周五都点红烧肉,服务员还没开口,后厨已经把肉下锅了。这就是备菜预判:根据经验预测“下一步可能要什么”,提前做好准备。懒加载解决的是“不浪费”,预加载解决的则是“再快一步”。
前端有两个容易混淆的预加载指令:preload 和 prefetch。preload 是“现在就要用到,请优先加载”——比如当前页面必需的字体文件、首屏大图,浏览器会以最高优先级去取;prefetch 是“将来可能用到,有空再取”——比如用户可能点击的下一个页面的资源、滚动到下方才会出现的模块,浏览器会在网络空闲时悄悄拉取。用后厨的话说,preload 是“这桌客人催得急,先上”,prefetch 是“看着像要加菜的客人,先备着”。
判断用哪种,本质是一个预测问题:评估用户下一步行为与所需资源的关联概率:
预加载的度要拿捏好。小馆复盘发现,提前备了 20 道菜,结果当天只卖出去 5 道,剩余食材全浪费了。前端的带宽也是“食材”:preload 滥用会把关键资源的优先级挤下去,prefetch 过量则白白消耗用户流量。正确的姿势是,用数据说话——分析用户行为路径,把预加载用在“翻牌率最高”的那几道菜上。
- 用户行为信号点击、悬停、滚动静止等操作,都是预测下一步动作的线索。
- 启发式预测根据规则或历史规律推断“这个动作大概率走到哪里”,比如首页 → 列表页 → 详情页的典型路径。
- 概率 P预测值越高,越值得提前预取。但预取要克制,备了没人点的菜就是浪费带宽。
资源压缩
王老板的杂物间终于堆满了。他请来一位老师傅,教他用真空封口机处理食材:土豆压成粉、高汤浓缩成块、干货抽真空。同样容积的储物柜,现在能装下三倍的食材。压缩不改变营养,只改变体积——这是资源压缩的哲学。
网页里的 HTML、CSS、JavaScript 都是纯文本,文本中充满大量重复的标签、空格、重复出现的单词。Gzip 就像那台真空封口机:在服务器端把文件压缩成更小的包,浏览器收到后再解压还原。Gzip 基于 DEFLATE 算法,核心思路是用更短的编码替代重复片段——比如“background-color“在 CSS 里出现 80 次,压缩器只记录一次,其余用指针引用。新一代的 Brotli 压缩算法做得更极致,它内置了一个巨大的常用词汇字典,连”class”"div"这类高频词都能直接查表,压缩率通常比 Gzip 再高 15%~20%。
压缩收益用“压缩率”来衡量:
但压缩也不是越高越好——压缩级别像真空机的抽气档位,档位越高压得越扁,但机器也越吃力。服务器端 CPU 会在高压缩级别下飙升,反而拖慢响应。合理的做法是:文本资源按内容类型区分,HTML/CSS/JS 开启 Gzip 或 Brotli,压缩级别设在 5~6;而 JPEG、PNG、视频这类本身已经压缩过的格式,再上真空机只会白费力气——它们就像已经被压成砖的冻干蔬菜,没有多少水分可挤了。
- 原始大小服务器上未压缩的文本资源体积,单位通常为字节。
- 压缩后大小经过 Gzip 或 Brotli 处理后的体积。
- 体积差与比值原始与压缩的差值代表节省的字节数,除以原始体积再乘 100%,得到直观的压缩率。
关键渲染路径优化
小馆后厨的动线曾是一团乱麻:食材从后门进,先穿过洗碗区,再绕过杂物间才到灶台,传菜又要走回前厅正中央。王老板把灶台移到传菜口旁边,食材进门直送备菜台,出菜路径缩短了一半。上菜速度不只看菜做得快不快,更看路径顺不顺——这就是关键渲染路径优化。
浏览器从拿到 HTML 到在屏幕上画出像素,也有一条固定动线,称为关键渲染路径。它包含五步:解析 HTML 构建 DOM 树、解析 CSS 构建 CSSOM 树、两者合并成 Render Tree(渲染树)、计算布局(Layout)、最后绘制合成。路径上任何一步被阻塞,屏幕上就多一片空白。CSS 和 JavaScript 是这条路上最常见的“堵点”:CSS 在构建 CSSOM 时会阻塞渲染;普通 <script> 标签在下载和执行时会阻塞 DOM 解析,就像有人在厨房过道里停下来打电话。
关键路径的总耗时可近似看成各环节耗时之和:
对应小馆动线调整,前端的关键渲染路径优化有三板斧:把关键 CSS 直接内联进 HTML 头部,省去“从仓库取样式”的往返;给非关键的 JavaScript 加 defer 或 async,让它们别堵在 DOM 解析的路上;尽量减少请求数量和资源体积,让每件“食材”进门都不用绕路。路径顺了,首屏自然哗地一下亮出来。
- HTML 解析耗时浏览器读取 HTML 代码、构建 DOM 树的时间,精简标签和注释能略微加速。
- CSS 构建耗时解析样式表、构建 CSSOM 树的时间。关键 CSS 内联进 HTML 可减少一次往返请求。
- JS 执行耗时脚本下载和执行的时间。
defer让脚本在 DOM 解析完成后执行,async让独立脚本并行下载后立即执行,都避免阻塞。 - 绘制合成耗时布局计算与像素绘制的总时间。减少 DOM 层级、避免大型图片重绘,都能降低此值。
性能指标评估
王老板做了个“顾客满意度仪表盘”:多久上菜?喊服务员多久有人应?上菜时桌子有没有晃? 三个问题对应三个可量化的数字,每周复盘,持续改进。前端领域也有一套官方仪表盘,叫 Core Web Vitals,由三项核心指标组成。
第一项是 LCP(Largest Contentful Paint,最大内容绘制),衡量“最大的内容块”(通常是首屏主图或大标题)多久显示出来,好比“主菜多久上桌”,达标线是 2.5 秒以内。第二项是 INP(Interaction to Next Paint,交互到下一帧绘制),衡量用户点击或按键后页面多久给出视觉反馈,好比“喊服务员多久有人应”,达标线是 200 毫秒以内。第三项是 CLS(Cumulative Layout Shift,累积布局偏移),衡量页面元素是否突然跳动,好比“上菜时桌子有没有晃倒杯子”,得分应小于 0.1。三项指标综合起来,构成一个整体体验分:
其中 $\hat{\text{LCP}}$、$\hat{\text{INP}}$、$\hat{\text{CLS}}$ 分别是三项指标按阈值归一化后的 0~1 分。
小馆的仪表盘周报会显示“上菜平均 4 分钟、应声 30 秒、翻桌 0 次”,老板据此调整备菜策略。前端工程师也该养成同样的习惯:每次改动后跑一遍指标,看看懒加载有没有改善 LCP、压缩有没有缩短传输时间、布局有没有引入新的 CLS。没有指标的优化是盲人摸象,有了指标,每一次改动都有据可依。
- LCP 评分映射将实际测量的 LCP 时间(如 3.2 秒)映射为 0~1 的评分,超时越多分越低。
- INP 评分映射将交互响应延迟映射为评分,越流畅越接近 1。
- CLS 评分映射将布局偏移量映射为评分,页面越稳定分越高。
- 取平均三项相加除以 3,得到综合体验分。实际操作中常用工具(如 PageSpeed Insights、Lighthouse)自动计算并给出诊断报告。
AI赋能优化
老王的生意越做越大,仅靠老师傅的经验已经压不准“明天该备什么菜”。他请来一位数据店长,把三个月的外卖订单、天气、节假日、顾客口味全喂给一套模型。模型学会了预测:雨天烧烤类订单上涨 40%、周五下午甜点翻倍。后厨从此按预测备菜,浪费少了,高峰期也不缺货了。当经验判断升级为数据预测,优化就从“人治”进化到“智治”。
前端性能优化正在经历同样的进化。传统的预取靠开发者的经验写死规则,而 AI 赋能的预测预取会收集海量用户行为序列——鼠标轨迹、停留时长、点击习惯——训练一个模型,实时预测“当前用户大概率下一步访问哪个页面、需要哪些资源”,然后自动下发预取指令。预测越准,缓存命中率越高,用户感知到的加载时间就越短。训练这类模型的常用目标函数是带正则化的交叉熵损失:
其中 $y_i$ 是用户真实行为的 one-hot 标签,$\hat{y}_i$ 是模型预测概率,$\lambda$ 控制正则强度。
除了预测预取,AI 还渗透到智能压缩(根据终端网络状况自动选择 Gzip/Brotli 及压缩级别,4G 用户拿到更小的包,WiFi 用户享受更快的解压)和异常监控(自动识别 Core Web Vitals 的异常波动并定位原因)。小馆的数据店长最终让翻台率提升了三成——AI 不是取代后厨,而是让每个决策都建立在数据而非拍脑袋上。对前端工程师而言,理解 AI 优化的底层逻辑,意味着你能更好地与算法团队协作,把“经验判断”升级成“可学习的系统”。
- 真实标签 $y_i$用户实际点击或访问的资源,用 one-hot 编码表示——某个时刻真正发生了哪件事。
- 预测概率 $\hat{y}_i$模型估算的用户访问该资源的概率,像一个不断校准的“备菜权重表”。
- 交叉熵项逐样本累计预测偏差,偏差越大损失越大,训练就是不断把这个值压小。
- 正则项对模型参数 $w$ 施加惩罚,防止它把偶然的噪声当成规律,保证预测在真实场景中依然稳健。
AI 应用场景
电商瀑布流页面的智能懒加载
阶段:数据处理与前端渲染优化
解决的问题:传统电商首页包含数百张商品图,一次性全量加载会导致首屏白屏数秒、流量消耗巨大。AI 结合用户浏览行为与推荐系统,动态决定图片的加载优先级:推荐算法判定“你可能想看的商品”被赋予高优先级,提前进入视口开始加载;其余商品图则交给 Intersection Observer 按滚动位置懒加载,既保首屏速度,又不浪费带宽。
具体案例:某头部电商 App 大促期间,首页采用“AI 排序 + 懒加载”组合策略,商品图按用户偏好预加载前 10 张,其余随滚动懒加载。实测 LCP 从 4.2 秒降至 1.8 秒,流量消耗减少 55%,人均浏览商品数提升 20%。
视频平台的下一集预加载
阶段:用户行为预测与资源预取
解决的问题:用户看完剧集后,传统做法是等用户点击“下一集”才开始缓冲,等待期长达数秒。AI 模型分析用户观看时长、完播率与历史行为,对“80% 概率会看下一集”的用户提前下发 prefetch 指令,下一集视频的首个分片在后台悄悄就绪,点击瞬间即播。
具体案例:视频网站对高留存用户启用 AI 预加载后,连续播放会话的平均续播等待从 3.5 秒降至 0.4 秒,用户次日留存率提升 8 个百分点,同时通过精确的置信度阈值控制,避免为“只看一集就离开”的用户浪费流量。
新闻资讯站的智能文本压缩
阶段:模型推理与网络传输优化
解决的问题:新闻门户以 HTML/JSON 文本为主,传统固定启用 Gzip 无法适配多样化终端。AI 系统根据用户设备类型、网络带宽和请求内容的冗余度,动态选择 Brotli 或 Gzip、动态设定压缩级别:弱网用户获得最高压缩比的 Brotli 资源,强网用户则用低级别压缩减少服务器 CPU 开销。
具体案例:某新闻平台接入自适应压缩系统后,移动端页面平均传输体积下降 62%,弱网下正文加载时间从 6.8 秒缩短到 2.9 秒,服务器 CPU 峰值反而降低 15%,因为不再对所有请求都做“最高档真空包装”。
Python 演示
import zlib class LazyLoader: """模拟浏览器视口懒加载调度""" def __init__(self, viewport_height=800): self.content = [] # [(元素距顶距离, 资源体积)] self.loaded = set() # 已加载元素下标 self.scroll_y = 0 self.viewport_height = viewport_height def add_item(self, position, size): self.content.append((position, size)) def scroll(self, delta): self.scroll_y += delta def update(self): """返回新加载资源数, 模拟 IntersectionObserver 回调""" newly = 0 for i, (pos, size) in enumerate(self.content): if pos < self.scroll_y + self.viewport_height and i not in self.loaded: self.loaded.add(i) newly += 1 return newly def transferred(self): return sum(size for i, (pos, size) in enumerate(self.content) if i in self.loaded) def gzip_report(data): compressed = zlib.compress(data, level=6) return len(data), len(compressed), 1 - len(compressed) / len(data) def main(): # 长页面: 50 张图片, 每张 200KB, 每张间距 400px loader = LazyLoader() for i in range(50): loader.add_item(i * 400, 200 * 1024) # 用户向下滚动 30 次, 每次 200px while loader.scroll_y < 30 * 200: loader.scroll(200) loader.update() eager = sum(size for _, size in loader.content) lazy_total = loader.transferred() print(f"滚动 30 次后, 懒加载传输 {lazy_total / 1024:.0f} KB") print(f"非懒加载全量传输 {eager / 1024:.0f} KB") print(f"节省流量 {(1 - lazy_total / eager) * 100:.1f}%") # Gzip 压缩文本演示 html = b"<html><body>" + b"".join(b"<p>hello frontend performance</p>" for _ in range(10000)) + b"</body></html>" raw, comp, ratio = gzip_report(html) print(f"HTML 原始大小 {raw} B, Gzip 后 {comp} B, 压缩率 {ratio * 100:.1f}%") if __name__ == "__main__": main()
def update(self):模拟 IntersectionObserver 的回调:每次滚动后检查哪些图片落入视口,首次进入的图片加入已加载集合。浏览器里这项工作由 Intersection Observer 在后台异步完成。pos < self.scroll_y + self.viewport_height判定“元素是否可见”的核心条件:元素距页顶的距离小于(当前滚动高度 + 视口高度),说明它已经出现在用户眼前。self.loaded.add(i)用集合记录已加载下标,保证同一图片只加载一次,避免重复请求——对应面试题中“反复进出视口不会重复加载”的答案。lazy_total / 1024:.0f把字节数换算成 KB 并保留整数,方便对比懒加载与全量加载的传输差距。zlib.compress(data, level=6)Python 标准库的 DEFLATE 压缩,等价于服务器开启 Gzip 后对响应体做的事;第六级是“性价比”较高的档位。1 - len(compressed) / len(data)计算压缩率,与正文公式r = (S原始 - S压缩) / S原始完全一致。
常见误区
误区我只要给所有图片都加上 `loading="lazy"`,或者用 Intersection Observer 拦截所有资源,性能就一定会变好。首屏主图也可以懒加载,反正最后都会加载。
正解懒加载只应该作用于当前视口以外、用户未来才可能看到的资源。首屏主视觉、关键标题、核心功能脚本必须立即可用——把它们懒加载等于把招牌菜藏进冷库,客人一坐下就要等“解冻”,首屏体验反而崩坏。后厨的“现点现做”也分对象:招牌菜要提前备好半成品,只有配菜才等客人点了再下锅。
为何常见:初学者只看到了“延迟加载省流量”这一个收益,忽略了“用户第一眼看到的内容优先级最高”这一基本原则。
误区preload 和 prefetch 都是“提前加载资源”,用哪个都行,多加几条总没坏处。
正解两者定位截然相反。preload 是当前页面必须的资源,优先级最高,浏览器会暂停其他任务来抢它;prefetch 是未来可能用的资源,浏览器只在空闲时低优先级去取。把当前页面关键字体用 prefetch 声明,可能导致首屏字体晚到;把未来页面的资源用 preload 强行提前,则会挤占关键资源带宽。这就像后厨的“催菜铃”和“备菜清单”不能互换——催菜铃响了必须立刻上菜,备菜清单只是有空时准备。
为何常见:两者名字都有“pre“前缀,功能都是”提前”,初学者很难立刻分辨使用场景的差异。
误区Brotli 比 Gzip 好,那我就把所有资源都用最高压缩级别处理;图片、视频也再压一遍,能省一点是一点。
正解压缩级别越高,服务器 CPU 消耗越大,响应时间可能变长,反而拖慢整体体验。更关键的是,JPEG/PNG/WebP 这类已压缩格式内部几乎没有冗余可挤,再做 Gzip/Brotli 收益极小甚至体积反向变大。正确做法是:只对 HTML/CSS/JS/JSON 等文本资源开启压缩,级别取 5~6 的性价比档位。真空机也有适用范围——把冻干蔬菜再抽一遍真空,只是浪费电。
为何常见:看到“压缩能减小体积 70%”的案例后,容易把结论外推到所有文件类型,忽略了压缩算法只对高冗余文本有效。
误区我把懒加载、预加载、Gzip 都配好了,性能指标也看过一遍是绿色的,之后就不用再管了。
正解性能是一个持续变化的动态指标:业务新增图片、第三方脚本升级、用户设备换代、网络环境变化,都会让 Core Web Vitals 从绿变红。正确做法是把性能监控纳入日常开发流程,每次发布后跑一遍 PageSpeed Insights,每周查看真实用户数据(RUM)。小馆的满意度仪表盘也是每周复盘,从不敢“调一次就永远不管”。
为何常见:优化是“一次性项目”的惯性思维——觉得配好配置就算完成任务,忘了软件系统永远在演进。
误区图片用懒加载后,搜索引擎爬虫可能抓不到图片,导致 SEO 排名下降,所以企业站不敢用懒加载。
正解搜索引擎(Google 等)的爬虫支持标准懒加载实现,包括 loading="lazy" 和基于 Intersection Observer 的常见方案;规范要求为图片提供 src 兜底或结构化数据,确保爬虫能解析真实地址。只要不把图片路径藏在 JS 变量里且不提供任何兜底,懒加载不会伤害 SEO。这相当于后厨给外送平台报菜名时写清楚每道菜的真实食材,而不是说“等客人点了再说”。
为何常见:早期确实存在爬虫不执行 JS 导致图片漏抓的旧闻,加上对“延迟加载”字面的担忧,让这个过时顾虑流传至今。
面试题
Q1. 下列哪项最符合图片懒加载的核心原理?
- A.把所有代码文件打包压缩成一个文件
- B.等元素进入视口时才加载对应资源← 正确答案
- C.将页面全部图片提前预取到本地缓存
- D.利用 CSS 隐藏不需要展示的图片元素
答案:B。懒加载的关键是“按需加载”——资源进入视口(用户看得到)才发起请求,对应后厨“顾客点了才下锅”。A 是打包压缩,C 是预加载,D 是用 CSS 隐藏,三者都与懒加载的触发时机无关。
Q2. Intersection Observer 在前端性能优化中的作用是?
- A.专门监听用户键盘输入事件的对象
- B.高效检测元素与浏览器视口的交叉状态← 正确答案
- C.用于修改页面全局字体样式的浏览器接口
- D.发起网络请求获取远程 JSON 数据的工具
答案:B。Intersection Observer 是浏览器提供的“视口哨兵”,异步监听元素是否进入可视区域,性能远优于传统的 scroll 事件监听。它不负责输入事件、样式修改或网络请求,专司“看见没看见”这一件事。
Q3. preload 与 prefetch 的主要区别是什么?
- A.preload 等待页面加载完毕后才开始执行
- B.prefetch 的下载优先级通常高于 preload
- C.preload 服务于当前页面必需资源,prefetch 备战未来资源← 正确答案
- D.两个指令描述的是完全相同的加载行为
答案:C。preload 告诉浏览器“这个资源本页马上要,请立即高优加载”;prefetch 则说“未来某个页面可能用,空闲时再取”。优先级上 preload 高于 prefetch。这就好比后厨的“催菜铃”和“备菜清单”,用途完全不同。
Q4. 以下哪些做法有助于减少关键渲染路径上的阻塞?
- A.将关键 CSS 内联到 HTML 文件头部← 正确答案
- B.给 script 标签添加 defer 属性延迟执行← 正确答案
- C.把 CSS 放 body 末尾延迟样式解析
- D.用大图作为页面背景增强视觉冲击
答案:AB。关键渲染路径要求 CSS 尽快构建 CSSOM,所以关键 CSS 宜内联、不宜放 body 末尾(C 错);defer 让脚本在 DOM 解析完成后执行,避免阻塞(B 对);大图背景会显著拖慢 LCP 并增加布局负担(D 错)。后厨动线讲究“食材进门直送灶台”,A、B 正是缩短动线的做法。
Q5. 关于 Gzip 与 Brotli 压缩算法,下列判断正确的是?
- A.二者是互斥的同一种压缩算法
- B.Brotli 的压缩率通常优于 Gzip← 正确答案
- C.Gzip 的压缩率恒高于 Brotli
- D.两者都无法有效压缩文本类资源
答案:B。Gzip 基于 DEFLATE,Brotli 是新一代算法,内置常用词汇字典,对 HTML/CSS/JS 这类文本通常比 Gzip 再小 15%~20%。二者各有适用场景,绝非互斥或恒定优劣,也都擅长压缩文本资源。
Q6. 关于 Core Web Vitals 三项指标,下列说法正确的是?
- A.LCP 度量最大内容块的绘制时间← 正确答案
- B.INP 度量交互到下一帧的响应延迟← 正确答案
- C.CLS 度量页面元素的累积布局偏移← 正确答案
- D.移动端用户无需关注这三项指标
答案:ABC。LCP(最大内容绘制)衡量首屏主菜多久上桌,INP(交互到下一帧绘制)衡量喊服务员多久有回应,CLS(累积布局偏移)衡量上菜时桌子稳不稳。三项指标在桌面端与移动端都同等重要,D 明显错误。
Q7. 某文本文件原始 200KB,经 Brotli 压缩后剩 40KB,其压缩率是?
- A.压缩率 20%, 表示压缩后是原始的 20%
- B.压缩率 80%, 表示减少了 80% 的体积← 正确答案
- C.压缩率 500%, 表示体积扩大了 5 倍
- D.压缩率 40%, 表示压缩后占原始的四成
答案:B。压缩率 r = (S原始 − S压缩) / S原始 × 100% = (200 − 40) / 200 = 80%,表示节省了 80% 的体积,剩下载体仅 20%。A 把“剩余占比”当压缩率,C 搞反了方向,D 把数值安成了压缩后比例。
Q8. 懒加载场景下,某图片反复滚动进出视口,会发生什么?
- A.浏览器会重复发起多份相同的图片请求
- B.加载器会用已加载集合去重,只加载一次← 正确答案
- C.页面会因循环触发条件而直接崩溃
- D.图片将因为抖动判定而永远无法加载
答案:B。成熟的懒加载实现都会记录已加载资源的标识(如 loaded 集合),首次进入视口触发加载后即标记,后续反复进出只更新观察状态,不再重复请求。这就像后厨记录了“红烧肉已下锅”,客人反复催几次也不会做第二份。
Q9. 关于资源压缩的正确实践,以下哪些描述成立?
- A.对 HTML 文本资源启用 Gzip 或 Brotli 压缩← 正确答案
- B.对 JPEG 图片再一次做 Gzip 压缩以减小体积
- C.压缩级别设置过高会显著增加服务器 CPU 负担← 正确答案
- D.无损压缩算法会明显降低图片的视觉清晰度
答案:AC。文本资源冗余高、压缩收益大,A 对;JPEG 内部已是有损压缩格式,再压近乎无收益甚至变大,B 错;压缩级别越高 CPU 开销越大,可能拖慢服务器响应,C 对;Gzip/Brotli 属于无损压缩,解压后内容原样还原,不影响清晰度,D 错。
Q10. 图片懒加载带来的最直接收益是什么?
- A.减少首屏请求数量与流量消耗← 正确答案
- B.自动提升图片的画面清晰度
- C.修复图片加载完成后的布局错乱
- D.让服务器预先缓存所有图片文件
答案:A。懒加载把视口外的图片请求推迟,首屏只下载可见资源,请求数和流量同步下降,这正是“现点现做”省食材的效果。清晰度取决于图片源文件,布局错乱要靠占位尺寸解决,服务器缓存是另一套机制,均与懒加载无直接关系。