Web图片资源的加载与渲染时机

此文研究页面中的图片资源的加载和渲染时机,使得我们能更好的管理图片资源,避免不必要的流量和提高用户体验。

浏览器的工作流程

要研究图片资源的加载和渲染,我们先要了解浏览器的工作原理。以Webkit引擎的工作流程为例:

从上图可看出,浏览器加载一个HTML页面后进行如下操作:

  • 解析HTML —> 构建DOM树
  • 加载样式 —> 解析样式 —> 构建样式规则树
  • 加载javascript —> 执行javascript代码
  • 把DOM树和样式规则树匹配构建渲染树
  • 计算元素位置进行布局
  • 绘制

从上图我们不能很直观的看出图片资源从什么时候开始加载,下图标出图片加载和渲染的时机:

  • 解析HTML【遇到<img>标签加载图片】 —> 构建DOM树
  • 加载样式 —> 解析样式【遇到背景图片链接不加载】 —> 构建样式规则树
  • 加载javascript —> 执行javascript代码
  • 把DOM树和样式规则树匹配构建渲染树【遍历DOM树时加载对应样式规则上的背景图片】
  • 计算元素位置进行布局
  • 绘制【开始渲染图片】

图片加载与渲染规则

页面中不是所有的<img>标签图片和样式表背景图片都会加载。

display:none

<style>
.img-purple {
    background-image: url(../image/purple.png);
}
</style>
<img src="../image/pink.png" style="display:none">
<div class="img-purple" style="display:none"></div>

图片资源请求如下:

设置了display:none属性的元素,图片不会渲染出来,但会加载。

原理

把DOM树和样式规则树匹配构建渲染树时,只会把可见元素和它对应的样式规则结合一起产出到渲染树,这就意味有不可见元素,当匹配DOM树和样式规则树时,若发现一个元素的对应的样式规则上有display:none,浏览器会认为该元素是不可见的,因此不会把该元素产出到渲染树上。

上面代码中,当解析HTML时会加载<img>标签元素上的图片。

当把DOM树和样式规则树匹配构建渲染树时,遍历DOM树上的元素,发现元素对应的样式规则上有background-image属性时会加载背景图片,但是因为这个元素是不可见元素(对应的样式规则上有diaplay:none),不会把该元素和它对应的样式规则产出到渲染树。

当绘制时因为渲染树上没有该元素,因此不会绘制该元素的背景图片。

<style>
.img-yellow {
    background-image: url(../image/yellow.png);
}
</style>
<div style="display:none">
    <img src="../image/red.png">
    <div class="img-yellow"></div>
</div>

图片资源请求如下:

设置了display:none属性元素的子元素,样式表中的背景图片不会渲染出来,也不会加载;而<img>标签的图片不会渲染出来,但会加载。

原理

正如上面所说的,当匹配DOM树和样式规则树时,若发现元素的对应的样式规则上有display:none,浏览器会认为该元素的子元素是不可见的,因此不会把该元素的子元素产出到渲染树上。

当构建渲染树遇到了设置了display:none属性的不可见元素时,不会继续遍历不可见元素的子元素,因此不会加载该元素中子元素的背景图片。

当绘制时也因为渲染树上没有设置了display:none属性元素,也没有改元素的子元素,因此该元素中子元素的背景图片不会渲染出来。

重复图片

.img-blue {
    background-image: url(../image/blue.png);
}
<div class="img-blue"></div>
<img src="../image/blue.png">
<img src="../image/blue.png">

图片资源请求如下:

页面中多个<img>标签或样式表中的背景图片图片路径是同一个,图片只加载一次。

原理

浏览器请求资源时,都会先判断是否有缓存,若有缓存且未过期则会从缓存中读取,不会再次请求。先加载的图片会存储到浏览器缓存中,后面再次请求同路径图片时会直接读取缓存中的图片。

不存在元素的背景图片

.img-blue {
    background-image: url(../image/blue.png);
}
.img-orange{
    background-image: url(../image/orange.png);
}
<div class="img-orange"></div>

图片资源请求如下:

不存在元素的背景图片不会加载。

原理

不存在的元素不会产出到DOM树上,构建渲染树过程中遍历DOM树时无法遍历不存在的元素,因此不会加载图片,也不会产出到渲染树上。当解析渲染树时无法解析不存在的元素,不存在的元素自然也不会渲染。

伪类的背景图片

.img-green {
    background-image: url(../image/green.png);
}
.img-green:hover{
    background-image: url(../image/red.png);
}
<div class="img-green"></div>

触发hover前的图片资源请求如下:

触发hover后的图片资源请求如下:

当触发伪类的时候,伪类样式上的背景图片才会加载。

原理

触发hover前,构建渲染树过程中,遍历DOM树时,该元素匹配的样式规则是无hover状态选择器.img-green的样式,因此加载无hover状态选择器.img-green的样式上green.png图片。该元素是可见元素,因此会被产出到渲染树上,绘制时渲染的也是green.png

触发hover后,因为.img-green:hover的优先级比较高,构建新的渲染树过程中,该元素匹配的是有hover状态选择器,因此加载有hover状态选择器.img-green:hover的样式上的red.png图片。该元素是可见元素,因此会被产出到渲染树上,绘制时渲染的也是red.png

应用

占位图

当使用样式表中的背景图片作为占位符时,要把背景图片转为base64格式。这是因为背景图片加载的顺序在<img>标签后面,背景图片可能会在<img>标签图片加载完成后才开始加载,达不到想要的效果。

预加载

很多场景里图片是在改变或触发状态后才显示出来的,例如点击一个Tab后,一个设置display:none隐藏的父元素变为显示,这个父元素里的子元素图片会在父元素显示后才开始加载;又如当鼠标hover到图标后,改变图标图片,图片会在hover上去后才开始加载,导致出现闪一下这种不友好的体验。

在这种场景下,我们就需要把图片预加载,预加载有很多种方式:

  1. 若是小图标,可以合并成雪碧图,在改变状态前就把所有图标都一起加载了。
  2. 使用上文讲到的,设置了display:none属性的元素,图片不会渲染出来,但会加载。把要预加载的图片加到设置了display:none的元素背景图或<img>标签里。
  3. 在javascript创建img对象,把图片url设置到img对象的src属性里。

欢迎关注:Leechikit
原文链接:segmentfault.com

到此本文结束,欢迎提问和指正。
写原创文章不易,若本文对你有帮助,请点赞、推荐和关注作者支持。

原文地址:https://www.cnblogs.com/baimeishaoxia/p/12221924.html

时间: 2024-12-15 22:08:44

Web图片资源的加载与渲染时机的相关文章

web图片资源加载与渲染时机笔记

浏览器的工作流程就不说了,网上有很多资料. 1.首先,页面中不是所有的<img>标签图片和样式表中的背景图片都会加载 2.当给一个元素设置了display:none属性(此元素为<img>或有背景图的其他元素),图片不会渲染出来,但是会加载. 3.设置了display:none属性的元素的子元素,样式表中的背景图片既不会渲染出来,也不会进行加载,而<img>标签的图片不会渲染,但会加载. 4.重复图片,浏览器只加载一次(熟悉浏览器特性的人都知道,浏览器在请求资源时,会先

css基础篇(一)——浏览器加载和渲染网页

1.介绍 虽然这篇是css笔记,但是做为web开发,天天和浏览器打交道,有必要先理理我目前了解的浏览器加载和渲染页面的过程. 2.页面加载和渲染流程 如图:(该篇重点是css,所以该图重点说明css渲染) 1.重建DOM树:渲染引擎开始解析html文档,转换树中的标签到DOM节点 2.构建渲染树:解析css,根据css选择器找到节点的样式,创建另外一个树———渲染树 3.布局渲染树:从根节点开始,计算出每一个元素的大小和位置 4.绘制渲染树:遍历渲染树将每个节点都绘制出来 整个流程简易描述:用户

浏览器渲染的工作流程和图片加载与渲染规则

1 浏览器渲染的工作流程 浏览器的工作原理.以Webkit引擎的工作流程为例,浏览器加载一个HTML页面后进行如下操作 解析HTML[遇到<img>标签加载图片] -> 构建DOM树 加载样式 -> 解析样式[遇到背景图片链接不加载] -> 构建样式规则树 加载javascript -> 执行javascript代码 把DOM树和样式规则树匹配构建渲染树[加载渲染树上的背景图片] 计算元素位置进行布局 绘制[开始渲染图片] 2 图片加载与渲染规则  页面中不是所有的&l

浏览器加载和渲染HTML的过程(标准定义的过程以及现代浏览器的优化)

先看一下标准定义的浏览器渲染过程(网上找的): 浏览器打开网页的过程 用户第一次访问网址,浏览器向服务器发出请求,服务器返回html文件: 浏览器开始载入html代码,发现 head 标签内有一个 link 标签引用外部CSS或JS文件: 浏览器又发出CSS及JS文件的请求,服务器返回这个CSS,JS文件: 浏览器继续载入html中 body 部分的代码,并且CSS,JS文件已经拿到手了,可以开始渲染页面了: 浏览器在代码中发现一个 img 标签引用了一张图片,向服务器发出请求.此时浏览器不会等

浏览器页面加载解析渲染机制(一)

mark一下zhq[2]. 前言:首先这个标题对我来说有不甚了解,这里引用了一些好的技文内容,分享一下我的一些理解,如果有说错的望评论里狠狠打脸,以共勉之. 一:为什么要了解浏览器渲染页面和加载页面机制,主要还是性能的优化. 了解浏览器如何进行加载,我们可以在引用外部样式文件,外部js时,将他们放到合适的位置,使浏览器以最快的速度将文件加载完毕. 了解浏览器如何进行解析,我们可以在构建DOM结构,组织css选择器时,选择最优的写法,提高浏览器的解析速率. 了解浏览器如何进行渲染,明白渲染的过程,

浏览器加载、渲染机制

问题:为什么有些网站打开的时候会加载会很慢,而且是整个页面同时显示的,而有些网站是从顶到下逐步显示出来的? 想写出一个最佳实践的页面,可以从浏览器的加载.解析.渲染来开始了解. 了解浏览器如何进行加载,我们可以在引用外部样式文件,外部js时,将他们放到合适的位置,使浏览器以最快的速度将文件加载完毕. 了解浏览器如何进行解析,我们可以在构建DOM结构,组织css选择器时,选择最优的写法,提高浏览器的解析速率. 了解浏览器如何进行渲染,明白渲染的过程,我们在设置元素属性,编写js文件时,可以减少"重

tomcat web.xml启动加载类

tomcat web.xml启动加载类 2010-03-30 22:31suitieming | 分类:JAVA相关 | 浏览3870次 我写了一个程序配在tomcat上 想启动tomcat的时候自动运行这个类 怎么配置XML文件类名Test 分享到: 2010-03-31 01:57提问者采纳 答题闯关,过关即送礼!快来参加~ 把你需要启动时自动运行的类做成一个Servlet,然后在web.xml做如下配置:  <servlet>   <servlet-name>StartupL

Web前台直接加载GIS格式数据分析

本文以Flex直接加载Shp.DWG和MDB为例. 首先看一份现估测数据: 1)  加载Shp文件,目前直接由前台Flex代码完成: 图1 在ArcCatalog里面的Shp文件 图2 直接在前台加载后的Shp文件 结果显示: Shp文件 大小 加载时间 Shp1 50kb 约3s Shp2 750kb 约10s 分析:未用后台开发,直接使用前台Flex对SHP开放数据加载,省去通讯时间,速度快捷,速度与客户端配置成正比. 说明:直接加载使用了LibertyGIS.swc组件. 2)  加载Dw

java web项目启动加载顺序

web.xml加载过程(步骤):       1.启动WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> 和 <context-param></context-param> 2.紧接着,容器创建一个ServletContext(上下文),这个WEB项目所有部分都将共享这个上下文. 3.容器将<context-param></context-param>转