38.图片(<img>)在网页渲染过程中的处理流程
HTML 解析 → 2. 发起图片请求 → 3. 布局计算 → 4. 绘制与合成 → 5. 渐进式渲染
解析 HTML:
浏览器解析 HTML 时遇到 <img>
标签,立即触发图片资源的下载请求(除非被延迟加载策略阻止)。
若未设置 src 属性(如通过 JavaScript 动态赋值),则不会发起请求。
资源优先级:
图片请求的优先级通常低于关键资源(如 CSS、JS),但高于非关键脚本。
例外:首屏关键图片(如 <img loading="eager">
)可能被提升优先级。
图片下载与解码 网络请求:
浏览器根据 src 属性发起 HTTP 请求,遵循缓存策略(Cache-Control、ETag 等)。
若使用 srcset 或 <picture>
,浏览器根据设备特性(如 DPR、视口宽度)选择最佳图片源。
流式处理:
图片数据以流式接收,浏览器边下载边解码(部分格式如 JPEG 支持渐进式解码)。
解码线程:解码操作通常在 独立线程 中进行,避免阻塞主线程。
解码完成:
图片转换为 GPU 可处理的位图(Bitmap),存储在内存中,等待渲染。
布局(Layout/Reflow) 尺寸计算:
若 <img>
未设置 width/height 属性,浏览器需等待图片下载完成后才能确定其固有尺寸,导致布局抖动(Layout Shift)。
优化实践:始终显式设置 width 和 height(或通过 CSS 固定宽高),预留占位空间。
布局更新:
图片尺寸确定后,触发 重排(Reflow),更新渲染树(Render Tree)中的布局信息。
绘制(Paint)与合成(Composite) 绘制阶段:
将图片作为 纹理(Texture) 绘制到对应的图层(Layer)上。
若图片位于独立合成层(如应用了 transform: translateZ(0)),可避免整个页面重绘。
合成阶段:
合成线程将各图层分块(Tiling)并栅格化(Rasterize),最终由 GPU 合成输出到屏幕。
图片作为纹理直接参与合成,无需重复栅格化(若未发生尺寸变化)。
渐进式渲染(Progressive Rendering) 渐进式图片(如 JPEG):
边下载边显示低分辨率预览,逐步增强画质,提升用户体验。
懒加载(Lazy Load):
使用 loading="lazy" 或 Intersection Observer API 延迟加载非视口图片,减少首屏资源负载。