详解CSS玩转图片Base64编码

什么是 base64 编码?  

我不是来讲概念的,直接切入正题,图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址。

这样做有什么意义呢?我们知道,我们所看到的网页上的每一个图片,都是需要消耗一个 http 请求下载而来的(所有才有了 csssprites 技术的应运而生,但是 csssprites 有自身的局限性,下文会提到)。

没错,不管如何,图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,而可以随着 HTML 的下载同时下载到本地那就太好了,而 base64 正好能解决这个问题。

那么图片的 base64 编码长什么样子呢?举个栗子。www.google.com的首页搜索框右侧的搜索小图标使用的就是base64编码。我们可以看到:

//在css里的写法
#fkbx-spch, #fkbx-hspch {
  background: url(data:image/gif;base64,R0lGODlhHAAmAKIHAKqqqsvLy0hISObm5vf394uLiwAAAP///yH5B…EoqQqJKAIBaQOVKHAXr3t7txgBjboSvB8EpLoFZywOAo3LFE5lYs/QW9LT1TRk1V7S2xYJADs=) no-repeat center;
}
//在html代码img标签里的写法
<img src="data:image/gif;base64,R0lGODlhHAAmAKIHAKqqqsvLy0hISObm5vf394uLiwAAAP///yH5B…EoqQqJKAIBaQOVKHAXr3t7txgBjboSvB8EpLoFZywOAo3LFE5lYs/QW9LT1TRk1V7S2xYJADs=">

上面分别是图片的 base64 编码在 css 里面的写法和在 html<img> 标签里的写法。base64 编码长得就是这个样子,当然 base64 编码不仅仅运用在图片编码,还可以:

thunder://QUFodHRwOi8vZG93bi5zYW5kYWkubmV0L3RodW5kZXI3L1RodW5kZXI3LjEuNS4yMTUyLmV4ZVpa(不要复制我我真的不是种子)

嘿嘿没错,迅雷的“专用地址”也是用 Base64 加密的,有兴趣自行 google,不做赘述。

为什么要使用 Base64 编码?  

那么为什么要使用 base64 传输图片文件?上文也有提及,因为这样可以节省一个 http 请求。图片的 base64 编码可以算是前端优化的一环。效益虽小,但却缺能积少成多。

说到这里,不得不提的是 CssSprites 技术,后者也是为了减少 http 请求,而将页面中许多细小的图片合并为一张大图。那么图片的 base64 编码和 CssSprites 有什么异同,又该如何取舍呢?

所以,在这里要明确使用 base64 的一个前提,那就是被 base64 编码的图片足够尺寸小。以博客园的 logo 为例:

如图所示,博客园的 Logo 只有 3.27KB,已经很小了,但是如果将其制作转化成 base64 编码,生成的 base64 字符串编码足足有 4406 个,也就是说,图片被编码之后,生成的字符串编码大小一般而言都会比原文件稍大一些。即便 base64 编码能够被 gzip 压缩,压缩率能达到 50% 以上,想象一下,一个元素的 css 样式编写居然超过了 2000个 字符,那对 css 整体的可读性将会造成十分大的影响,代码的冗余使得在此使用 base64 编码将得不偿失。

那么,是不是表示 base64 编码无用武之地呢?不然。当页面中的图片满足以下要求,base64 就能大显生手。

如果图片足够小且因为用处的特殊性无法被制作成雪碧图(CssSprites),在整个网站的复用性很高且基本不会被更新。

那么此时使用 base64 编码传输图片就可谓好钢用在刀刃上,思前想后,符合这个规则的,有一个是我们经常会遇到的,就是页面的背景图 background-image 。在很多地方,我们会制作一个很小的图片大概是几px*几px,然后平铺它页面当背景图。因为是背景图的缘故,所以无法将它放入雪碧图,而它却存在网站的很多页面,这种图片往往只有几十字节,却需要一个 http 请求,十分不值得。那么此时将它转化为 base64 编码,何乐而不为?

下面是一个只有 50 字节的2*2的的背景图。将其转化成 base64 编码,只有 100 多个字符,相比一个 http 请求,这种转换无疑更值得推崇。

CssSprites与Base64编码  

简单陈述一下我对何时这使用这两种优化方法的看法。

使用CssSprites合并为一张大图:

页面具有多种风格,需要换肤功能,可使用CssSprites

网站已经趋于完美,不会再三天两头的改动(例如button大小、颜色等)

使用时无需重复图形内容

没有 Base64 编码成本,降低图片更新的维护难度。(但注意 Sprites 同时修改 css 和图片某些时候可能造成负担)

不会增加 CSS 文件体积

使用base64直接把图片编码成字符串写入CSS文件:

无额外请求

对于极小或者极简单图片

可像单独图片一样使用,比如背景图片重复使用等

没有跨域问题,无需考虑缓存、文件头或者cookies问题

更便捷的将图片转化为Base64编码  

将图片转化为 base64 编码有许多工具,例如本文中我所使用的http://www.pjhome.net/web/html5/encodeDataUrl.htm,但是很多这些网站是国外网站,经常被墙登陆不了。这里介绍一个更为快捷的方法,就是利用 Chrome 浏览器(我想 FEer 都应该有Chrome 浏览器吧=。=)。

在 chrome 下新建一个窗口,然后把要转化的图片直接拖入浏览器,打开控制台,点 Source,如下图所示,点击图片,右侧就会显示该图片的 base64 编码,是不是很方便。

一些误区

Base64 虽有优点,但是缺点也很明显,在使用上存在一些明显的缺陷。

1. 使用 Base64 不代表性能优化

是的,使用 Base64 的好处是能够减少一个图片的 HTTP 请求,然而,与之同时付出的代价则是 CSS 文件体积的增大。

而 CSS 文件体积的增大意味着什么呢?意味着 CRP 的阻塞。

CRP(Critical Rendering Path,关键渲染路径):当浏览器从服务器接收到一个HTML页面的请求时,到屏幕上渲染出来要经过很多个步骤。浏览器完成这一系列的运行,或者说渲染出来我们常常称之为“关键渲染路径”。

通俗而言,就是图片不会导致关键渲染路径的阻塞,而转化为 Base64 的图片大大增加了 CSS 文件的体积,CSS 文件的体积直接影响渲染,导致用户会长时间注视空白屏幕。HTML 和 CSS 会阻塞渲染,而图片不会。

2. 页面解析 CSS 生成的 CSSOM 时间增加

Base64 跟 CSS 混在一起,大大增加了浏览器需要解析CSS树的耗时。其实解析CSS树的过程是很快的,一般在几十微妙到几毫秒之间。

CSS 对象模型 (CSSOM):CSSOM是一个建立在web页面上的 CSS 样式的映射,它和DOM类似,但是只针对CSS而不是HTML。

CSSOM 生成过程:

CSSOM 生成过程大致是,解析 HTML ,在文档的 head 部分遇到了一个 link 标记,该标记引用一个外部 CSS 样式表,下载该样式表后根据上述过程生成 CSSOM 树。这里我们要知道的是,CSSOM 阻止任何东西渲染,(意味着在CSS没处理好之前所有东西都不会展示),而如果CSS文件中混入了Base64,那么(因为文件体积的大幅增长)解析时间会增长到十倍以上。

而且,最重要的是,增加的解析时间全部都在关键渲染路径上。

所以,当我们需要使用到 Base64 技术的时,一定要意识到上述的问题,有取舍的进行使用。

以上就是详解CSS玩转图片Base64编码的详细内容,更多关于CSS玩转图片Base64编码的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解盒子端CSS动画性能提升

    流畅动画的标准 理论上说,FPS 越高,动画会越流畅,目前大多数设备的屏幕刷新率为 60 次/秒,所以通常来讲 FPS 为 60frame/s 时动画效果最好,也就是每帧的消耗时间为 16.67ms. 直观感受,不同帧率的体验 帧率能够达到 50 - 60 FPS 的动画将会相当流畅,让人倍感舒适: 帧率在 30 - 50 FPS 之间的动画,因各人敏感程度不同,舒适度因人而异: 帧率在 30 FPS 以下的动画,让人感觉到明显的卡顿和不适感: 帧率波动很大的动画,亦会使人感觉到卡顿. 盒子端动

  • 原生js和css实现图片轮播效果

    本文实例为大家分享了javascript图片轮播效果的具体代码,供大家参考,具体内容如下 <!DOCTYPE HTML> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>图片轮播</title> <style> #box { width:506px; height:306px; margin: 20px auto; b

  • 如何在CSS中绘制曲线图形及展示动画

    理解 box-shadow 首先,回顾一下box-shadow这个属性.基本属性用法就是给元素创造一层阴影. 再简单提一下,本文会用到的关于阴影的第一个技巧: 使用阴影复制图像/投影图像 当 box-shadow 的第三.第四个参数模糊半径和扩张半径都为 0 的时候,我们可以得到一个和元素大小一样的阴影: div { width: 80px; height: 80px; border: 1px solid #333; box-sizing: border-box; box-shadow: 80p

  • 利用CSS、JavaScript及Ajax实现图片预加载的三大方法

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.本文将分享三个不同的预加载技术,来增强网站的性能与可用性. 方法一:用CSS和JavaScript实现预加载 实现预加载图片有很多方法,包括使用CSS.JavaScript及两者的各种组合.这些技术可根据不同设计场景设计出相应的解决方案,十分高效.

  • 详解CSS不定宽溢出文本适配滚动

    hover 时弹出框提示 一种可行的方案是在 hover 的时候,弹出一个文本框展示全文,最简单的就是在文本标签下添加 title 属性,填充我们需要的内容: <ul> <li title="溢出文本1 溢出文本2 溢出文本3 溢出文本4">溢出文本1 溢出文本2 溢出文本3 溢出文本4</li> </ul> 当然,这种方法简单但是可能缺乏点用户体验. 本文将简单介绍在文本长度不确定,容器长度也不确定的情况下,任意长度的文本实现 hove

  • js css3实现图片拖拽效果

    本文实例为大家分享了css3实现图片拖拽效果的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <style type="text/css"> body{ text-align: center; } .container{ display: flex; just

  • 利用CSS、JavaScript及Ajax实现图片预加载的方法

    预加载图片是提高用户体验的一个很好方法.图片预先加载到浏览器中,访问者便可顺利地在你的网站上冲浪,并享受到极快的加载速度.这对图片画廊及图片占据很大比例的网站来说十分有利,它保证了图片快速.无缝地发布,也可帮助用户在浏览你网站内容时获得更好的用户体验.本文将分享三个不同的预加载技术,来增强网站的性能与可用性. 实现图片预加载可以使用css.JavaScript.Ajax三种方法.下面分别介绍这些方法的实现. 使用CSS 单纯的使用css可以将图片加载到页面元素的背景上,这种方法简单.高效: #d

  • 基于cssSlidy.js插件实现响应式手机图片轮播效果

    cssSlidy是一款支持手机移动端的焦点图轮播插件,支持标题设置,滑动动画,间隔时间等. 在线实例 实例演示 使用方法 <div id="slidy-container"> <figure id="slidy"> <a href='#' target='_blank'><img src="img/2.jpg" alt="jQuery.nicescroll美化滚动条" data-cap

  • BootStrap 图片样式、辅助类样式和CSS组件的实例详解

    首先把模板代码上上来: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial

  • 详解CSS玩转图片Base64编码

    什么是 base64 编码? 我不是来讲概念的,直接切入正题,图片的 base64 编码就是可以将一副图片数据编码成一串字符串,使用该字符串代替图像地址. 这样做有什么意义呢?我们知道,我们所看到的网页上的每一个图片,都是需要消耗一个 http 请求下载而来的(所有才有了 csssprites 技术的应运而生,但是 csssprites 有自身的局限性,下文会提到). 没错,不管如何,图片的下载始终都要向服务器发出请求,要是图片的下载不用向服务器发出请求,而可以随着 HTML 的下载同时下载到本

  • jmeter添加自定义扩展函数之图片base64编码示例详解

    打开eclipse,新建maven工程,在pom中引入jmeter核心jar包: <!-- https://mvnrepository.com/artifact/org.apache.jmeter/ApacheJMeter_core --> <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_core</artifactId> <v

  • 详解CSS开发过程中的20个快速提升技巧

    1.使用CSS重置(reset) css重置库如normalize.css已经被使用很多年了,它们可以为你的网站样式提供一个比较清晰的标准,来确保跨浏览器之间的一致性. 大多数项目并不需要这些库包含的所有规则,可以通过一条简单的规则来应用于布局中的所有元素,删除所有的margin.padding改变浏览器默认的盒模型. *{box-sizing:border-box;margin:0;padding:0} 使用box-sizing声明是可选择,如果你使用下面继承的盒模型形式可以跳过它. 2.继承

  • 详解CSS故障艺术

    概述 本文的主题是 Glitch Art,故障艺术. 什么是故障艺术?我们熟知的抖音的 LOGO 正是故障艺术其中一种表现形式.它有一种魔幻的感觉,看起来具有闪烁.震动的效果,很吸引人眼球. 故障艺术它模拟了画面信号出现故障导致成像错误的感觉.青色色块与红色色块无法重合就是这种故障的体现.从胶片时代开始到今天的数码时代,这种故障一直是观众非常熟悉的现象.即使抖音的 LOGO 只是静态的,大脑也会自己补完整个效果,甚至还会自己脑补信号干扰的噪音. 使用混合模式实现抖音 LOGO 首先从静态的开始,

  • 详解CSS伪元素的妙用单标签之美

    :before和::before的区别 在介绍具体用法之前,简单介绍下伪类和伪元素.伪类大家听的多了,伪元素可能听到的不是那么频繁,其实 CSS 对这两个是有区分的. 有时你会发现伪类元素使用了两个冒号 (::) 而不是一个冒号 (:),这是 CSS3 规范中的一部分要求,目的是为了区分伪类和伪元素,大多数浏览器都支持这两种表示方式. #id:after{ ... } #id::after{ ... } 单冒号(:)用于 CSS3 伪类,双冒号(::)用于 CSS3 伪元素.对于 CSS2 中已

  • 详解CSS样式中的!important、*、_符号

    详解CSS样式中的!important.*._符号 !important.*._其实没什么用,皆是用来设置样式的优先级,但是样式的优先级你可以自行排好其先后位置来设置,然而你还是要看懂的. 我们知道,CSS写在不同的地方有不同的优先级, .css文件中的定义 < 元素style中的属性,但是如果使用!important,事情就会变得不一样. 首先,先看下面一段代码: <!DOCTYPE HTML> <html> <head> <meta http-equiv

  • HTML5 JS压缩图片并获取图片BASE64编码上传

    本文实例为大家分享了HTML5 JS压缩图片,并获取图片BASE64编码上传的方法,供大家参考,具体内容如下 基本过程 1) 调用 FileReader 的 reader.readAsDataURL(img); 方法, 在其onload事件中, 将用户选择的图片读入 Image对象. 2) 在image对象的 onload 事件中, 通过 canvas 的 canvas.getContext('2d') 的 drawImage 方法, 将Image 改变大小绘制到canvas上. 3) 通过 c

  • 详解JAVA生成将图片存入数据库的sql语句实现方法

    详解JAVA生成将图片存入数据库的sql语句实现方法 实现代码: 注释很清楚,不在重述~ public class Image2Hex { public static void main(String[] args) { try{ //存放图片的文件夹 File list = new File("d:/qmx"); File[] lists = list.listFiles(); String name; //生成的语句存放文件 PrintWriter pw = new PrintWr

  • 详解CSS不受控制的position fixed

    失效的 position:fixed 在许多情况下,position:fixed将会失效.MDN用一句话概括了这种情况: 当元素祖先的 transform 属性非 none 时,定位容器由视口改为该祖先. What!还有这种操作?可能有部分同学还没 get 到上面这句话的意思,通俗的讲就是指定了position:fixed的元素,如果其祖先元素存在非 none 的 transform 值 ,那么该元素将相对于设定了transform的祖先元素进行定位. 那么,为什么会发生这种情况呢?说好的相对视

随机推荐