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

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

浏览器的工作流程

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

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

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

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

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

图片加载与渲染规则

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

display:none


  1. <style> 
  2.  
  3. .img-purple { 
  4.  
  5.     background-image: url(../image/purple.png); 
  6.  
  7.  
  8. </style> 
  9.  
  10. <img src="../image/pink.png" style="display:none"> 
  11.  
  12. <div class="img-purple" style="display:none"></div>  

图片资源请求如下:

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

原理

把DOM树和样式规则树匹配构建渲染树时,会把可渲染元素上的所有属性(如display:none属性和background-image属性)结合一起产出到渲染树。

当解析渲染树时会加载<img>标签元素上的图片,发现元素上有background-image属性时会加载背景图片。

当绘制时发现元素上有display:none属性,则不计算该元素位置,也不会绘制该元素。


  1. <style> 
  2.  
  3. .img-yellow { 
  4.  
  5.     background-image: url(../image/yellow.png); 
  6.  
  7.  
  8. </style> 
  9.  
  10. <div style="display:none"> 
  11.  
  12.     <img src="../image/red.png"> 
  13.  
  14.     <div class="img-yellow"></div> 
  15.  
  16. </div>  

图片资源请求如下:

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

原理

正如上面所说的,构建渲染树时,只会把可渲染元素产出到渲染树,这就意味有不可渲染元素,当匹配DOM树和样式规则树时,若发现一个元素的属性上有display:none,浏览器会认为该元素的子元素是不可渲染的,因此不会把该元素的子元素产出到渲染树上。

当解析渲染树时渲染树上没有设置了display:none属性元素的子元素,因此不会加载该元素中子元素的背景图片。

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

重复图片


  1. .img-blue { 
  2.  
  3.     background-image: url(../image/blue.png); 
  4.  
  5.  
  6. <div class="img-blue"></div> 
  7.  
  8. <img src="../image/blue.png"> 
  9.  
  10. <img src="../image/blue.png">  

图片资源请求如下:

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

原理

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

不存在元素的背景图片


  1. .img-blue { 
  2.  
  3.     background-image: url(../image/blue.png); 
  4.  
  5.  
  6. .img-orange{ 
  7.  
  8.     background-image: url(../image/orange.png); 
  9.  
  10. }  

图片资源请求如下:

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

原理

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

伪类的背景图片


  1. .img-green { 
  2.  
  3.     background-image: url(../image/green.png); 
  4.  
  5.  
  6. .img-green:hover{ 
  7.  
  8.     background-image: url(../image/red.png); 
  9.  

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

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

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

原理

触发hover前,DOM树与样式规则树匹配的是无hover状态选择器.img-green的样式,因此渲染树上background-image属性的值是url(../image/green.png),解析渲染树时加载的是green.png,绘制时渲染的也是green.png。

触发hover后,因为.img-green:hover的优先级比较高,因此DOM树与样式规则树匹配的是有hover状态选择器.img-green:hover的样式,渲染树上background-image属性的值是url(../image/red.png),解析渲染树时加载的是red.png,绘制时渲染的也是red.png。

应用

占位图

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

预加载

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

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

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

作者:佚名

来源:51CTO

时间: 2024-08-11 08:45:46

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

spring mvc-我用springMVC写了一个web项目,加载到tomcat8上后启动出现此异常,请懂得的来帮忙看下

问题描述 我用springMVC写了一个web项目,加载到tomcat8上后启动出现此异常,请懂得的来帮忙看下 异常信息如下: 严重: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/spring_mvc]] at or

请问如果在通过web页面,加载pdf并且实现页面上对pdf进行注解和签名并且能实现保存

问题描述 请问如果在通过web页面,加载pdf并且实现页面上对pdf进行注解和签名并且能实现保存 请问如果在通过web页面,加载pdf并且实现页面上对pdf进行注解和签名并且能实现保存

手机app web页开始加载 正常 然后跳到其他页在按返回键回到原页面 js功能失效

问题描述 手机app web页开始加载 正常 然后跳到其他页在按返回键回到原页面 js功能失效 手机app web页开始加载 正常 然后跳到其他页在按返回键回到原页面 js功能失效 我估计是js出错了但是那里出错我不知道里面 有没有大神给点线索

web.xml可以加载ibatis的总配置文件吗

问题描述 今天想单独在web.xml引入SqlMapConfig.xml配置文件,怎么引入啊,不想用spring的import引入,也不想代码式引入,各位兄弟大家好,可以引入吗,恳请有识之士帮忙下,谢谢哈 解决方案 先请教一下楼主为什么要这样做呢?web.xml都是加载serlvet ,监听器,过滤器等这些与WEB工程有关的配置,而mybatis的配置文件是由mybatis框架本身的配置,与web项目无关,所以个人感觉根本没有配置到web.xml必要,也不可能,楼主的思路不对,我建议应该抓紧时间

JavaWeb中web.xml初始化加载顺序

需求说明 做项目时,为了省事,起初把初始化的配置都放在每个类中 static加载,初始化配置一多,就想把它给整理一下,这里使用servlet中的init方法初始化. web.xml说明 首先了解下web.xml中元素的加载顺序: 启动web项目后,web容器首先回去找web.xml文件,读取这个文件 容器会创建一个 ServletContext ( servlet 上下文),整个 web 项目的所有部分都将共享这个上下文 容器将 转换为键值对,并交给 servletContext 容器创建 中的

wro4j 1.4.6发布 Web应用程序加载优化工具

wro4j 是一个用于分析和优化Java Web应用程序页面http://www.aliyun.com/zixun/aggregation/12000.html">加载时间的工具.它可以帮助您保持静态资源(JavaScript 和 CSS)的管理,使用一个简单的过滤器来合并和减小它们的运行时间,使用Maven插件减小建立时间,并具有多种功能用于处理与Web资源. wro4j 1.4.6该版本更新多个新功能和错误修正.最显着的变化是迁移到rhino-1.7R3,内存/性能改进,基于Ruby引

浏览器加载、渲染和解析过程黑箱简析_javascript技巧

用 Fiddler 监控,在 IE6 下,资源下载顺序为: 很明显,下载顺序从上到下,文档流中先出现的资源先下载.在 IE8, Safari, Chrome 等浏览器下也类似. Firefox 对下载顺序做了优化:Firefox 会将 js, css 提前下载,而将图片等资源延迟到后面下载. 对于渲染,利用 Fiddler 将网速调慢,可以看到 css 下载后会马上渲染到页面,渲染和下载同步进行.js 的解析和运行,也类似. 对于 js 运行,以及页面加载相关事件的触发,特别做了测试.在 Fir

基于OSGI的WEB项目如何加载制定文件夹jsp文件运行

问题描述 现在手上开发的一个项目是基于OSGI的web项目,运行期会把模块打成jar包放在一般web工程下面去运行,运行环境暂订tomcat. 现在出现的问题如下:项目中有一个模块会生成一些文件到指定文件夹中(运行期为文件服务器),生成的文件包括js,jsp,css文件,其中js会到模块中去做请求后台数据,并且生成的文件会用到模块中的js或css样式.请问如何才能将生成的文件加载到tomcat中运行. 解决方案 可以参考一下这个:http://www.enet.com.cn/article/20

wro4j 1.4.4发布 Web应用程序加载优化工具

wro4j 是一个用于分析和优化Java Web应用程序页面http://www.aliyun.com/zixun/aggregation/12000.html">加载时间的工具.它可以帮助您保持静态资源(JavaScript 和 CSS)的管理,使用一个简单的过滤器来合并和减小它们的运行时间,使用Maven插件减小建立时间,并具有多种功能用于处理与Web资源. wro4j 1.4.4该版本主要修正的错误包括:CSS资源深递归通配符,1 cssLint maven插件修复,装饰处理器异常修