图片 9

大型网站优化技术

减去HTTP请求(大型网址优化本领)

2015/11/26 · HTML5 ·
HTTP

初稿出处: Kelly   

在网站开采进度中,对于页面包车型大巴加载效用壹般都想尽办法求快。那么,怎么让能力越来越快啊?减少页面请求 是叁个优化页面加载速度很好的点子。上1篇博文大家讲课了
“利用将小Logo合成一张背景图来压缩HTTP请求”,那么,这一篇博文将执教 
“ 将图片转成2进制并生成Base6四编码,能够在网页中经过url查看图片”。

1、为什么接纳将图纸转成二进制并生成Base6四编码,能够在网页中通过url查看图片的点子减弱HTTP请求数?

干什么我会讲解“将图片转成2进制并生成Base6四编码,能够在网页中经过url查看图片”
这一种格局来收缩HTTP请求,进而优化页面吗?那里吧,是事关到活动端的Logo使用。上壹篇博文所讲的办法是还是不是使用于手提式无线电话机端的网页呢?

可是,它会产出2个主题素材:背景图+css呈现Logo时,Logo自身无法缩放,比如背景图中6四px*6四px的图标,显示到分界面时务必设置icon的尺寸也是6四*6四。在PC网页中那常常不会有哪些问题,但在运动端设备上就全盘没用。一样是肆英寸的无绳电话机显示器,其分辨率有非常大可能率是320*400,也恐怕是640*800,甚至也说不定是一玖一九*1080。这样64px*64px的Logo在差异的装备上看起来的尺寸就会距离13分显著。

侥幸的是,手提式无线电话机上的浏览器基本对此做了优化,会把设备模拟成更低的分辨率。比如在113陆*640的IPHONE
5中获得$(window).width(),收取来的是320而不是640,那样2个大幅为160px的图纸占用的是显示屏宽度的4分之3,而不是百分之二十五。手提式有线电话机设备这么处理是为着消除包容性难题。除了网页,包涵手提式有线电话机上app的分界面,在retina显示器上和非retina显示器上的轻重是截然一致的,都是因为对分辨率做了拍卖。

可是,移动装备这么的处理格局并不可能完全解决难点,因为机器的假使性推断在广大时候是不对劲的,越发是在android设备中。为了越来越好地决定成分显示的大大小小,消除的主意正是用pt代替ps,px是对应显示屏的分辨率,而pt是对准人眼睛实际上呼吸系统感染觉的深浅,无论在何种分辨率的配备上,7二pt固定是壹英寸。

HTML的img标签成分的src属性不只是足以钦点url,也足以钦命图片的二进制数据流。然后经过img元素的机关缩放作用,钦命img的轻重,就可以完成在分化分辨率的配备上显得同一的Logo大小。

2、使用Base6四编码缩小页面请求数

当我们的三个页面中要传播许多图形时,特别是局部小图标,十几K、几K,甚至是字节等第大小的小Logo,这么些小Logo都会大增HTTP请求,若是多了,就会给服务器带来十分大的压力。比如要下载一些壹两K大的小Logo,其实请求时带上的额外新闻有希望比Logo的轻重还要大。所以,在乞请越多时,在网络传输的数目自然就愈多了,传输的数码自然也就变慢了。而那边,大家使用Base64的编码情势将图片直接嵌入到网页中,而不是从外部载入,那样就减弱了HTTP请求。当然了,它有五个小瑕疵,便是使当前页面的尺寸变大了(对于优化来说,其实那些可以忽略,影响异常的小)。看一下下图,小Logo大小为二.④k,等待响应时间是1四ms,而接受多少,相当于下载时间约为0ms;综上可得,在有雅量小Logo下载的时候,那样的艺术去优化能大大升高网址的性格(在jquery
mobile和天猫的手提式有线电话机站上边都有用到此手艺)。

图片 1

3、开拓思路

将小Logo放在以icon_初阶的文件夹里(以分别不用生成base6肆的图样的文书夹)—>用程序去遍历文件夹图片
—>将每张图片的base6四编码放在3个js对象里—>在HTML页面包车型大巴img标签里
使用性质 icon-data = ‘Logo名(不带后缀)’来浮现图片 —>
JS文件写3个函数对icon-data属性进行转移,转换到src属性,然后值就因而icon-data的属性值获得Logo名,然后实行相应的轮换获得相应图标的base64编码
—> 展现图片

四、代码完成

XHTML

<?php $pathinfo = pathinfo($_SERVER[‘SCRIPT_FILENAME’]);
define(‘ROOT’, $pathinfo[‘dirname’]); function generateIcon_mobile()
{ $imgRoot = ROOT.”/img/mobile”; $iterator = new
DirectoryIterator($imgRoot); foreach ($iterator as $file) { if
($file->isDot()) continue; $filename = $file->getFilename();
//识别出是不是以icon_开班的公文夹,假若是,则对此文件夹的Logo举办base6四编码处理
if ($file->isDir() && 0 === strncasecmp(‘icon_’, $filename, 五)) {
generateIconMobileCallback(“$imgRoot/$filename”, ROOT.”/js/mobile”); } }
} function generateIconMobileCallback($iconDir, $styleSaveDir) {
//保存成js的公文名 $saveName = array_pop(explode(‘/’, $iconDir));
//JS文件保留路线 $styleSavePath = $styleSaveDir.’/’.$saveName.’.js’;
//将当前目录下的兼具文件及MD5组成三个鉴定区别字符串 $fileMap = array();
$iterator = new DirectoryIterator($iconDir); foreach ($iterator as
$file) { if ($file->isDot()) continue; $fileName =
$file->getFilename(); if ($file->isDir()) {
generateIconMobileCallback($iconDir.’/’.$fileName,
$styleSaveDir.’/’.$fileName); } else { $fileMap[$fileName] =
md5_file($file->getRealPath()); } } ksort($fileMap); $fileMapStr =
json_encode($fileMap); //确定保证目录可写
ensure_writable_dir($styleSaveDir); //js文件句柄 $wirteHandle =
fopen($styleSave帕特h, ‘w’); //当前小Logo文件夹的相对路线$iconSaveRelative = substr($iconDir, strlen(ROOT));
//写入,开始化保存数据的靶子 fwrite($wirteHandle, “/** icon in dir:
$iconSaveRelative/ */ \nif(typeof(\$iconData) == ‘undefined’)
\$iconData={};”); foreach ($fileMap as $fileName => $md5) {
//当前图片的相对路线 $fullPathName = “$iconDir/$fileName”;
//获得路线新闻 $pathInfo = pathinfo($fullPathName);
//获得文件名(未有后缀) $fileNameNoExt = $pathInfo[‘filename’];
//赚取图片新闻 $imageSize = getimagesize($fullPathName);
//获得文件的后缀 switch ($imageSize[2]) { case IMAGETYPE_GIF:
$imageType = ‘gif’; break; case IMAGETYPE_JPEG: $imageType = ‘jpg’;
break; case IMAGETYPE_PNG: $imageType = ‘png’; break; default:
$imageType = ‘jpg’; break; } //获得图片财富 $readHandle =
fopen($fullPathName, ‘r’); //将图片转成2进制并生成Base6四编码 $base6四 =
base6四_encode(fread($readHandle, filesize($fullPathName))); //关闭资源fclose($readHandle); //将Base64编码写入js文件中 fwrite($wirteHandle,
“\n\$iconData.$fileNameNoExt=\”data:image/$imageType;base64,$base64\”;”);
} //最后换个行 fwrite($wirteHandle, “\n”); //关闭财富fclose($wirteHandle); //处理成功的Logo文件夹给予提醒 echo
‘<p>’.$iconSaveRelative. ‘ saved</p>’; } /** *
确定保障文件夹存在并可写 * * @param string $dir */ function
ensure_writable_dir($dir) { if(!file_exists($dir)) { mkdir($dir,
0766, true); @chmod($dir, 0766); @chmod($dir, 0777); } else
if(!is_writable($dir)) { @chmod($dir, 0766); @chmod($dir, 0777);
if(!@is_writable($dir)) { throw new
BusinessLogicException(“目录不可写”, $dir); } } }
generateIcon_mobile(); ?> <!DOCTYPE html> <html>
<head> <title></title> </head> <body>
<br> <br> <br>
<div>大家直接引进所生成的js文件,测试一下是或不是中标</div>
<br> <div>直接在img标签里投入 icon-data = ‘Logo文件名’ 例如
<\img icon-data=”tryit”>,查看效果</div> <br>
<br> <br> <img icon-data=”tryit”> <script
src=”js/mobile/icon_pink.js”></script> <script
src=”js/mobile/jquery.all.min.js”></script> <script
src=”js/mobile/attrHandle.js”></script> </body>
</html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
    $pathinfo = pathinfo($_SERVER[‘SCRIPT_FILENAME’]);
    define(‘ROOT’, $pathinfo[‘dirname’]);
 
    function generateIcon_mobile() {
        $imgRoot = ROOT."/img/mobile";
        $iterator = new DirectoryIterator($imgRoot);
        foreach ($iterator as $file) {
            if ($file->isDot()) continue;
            $filename = $file->getFilename();
 
            //识别出是否以icon_开头的文件夹,如果是,则对此文件夹的图标进行base64编码处理
            if ($file->isDir() && 0 === strncasecmp(‘icon_’, $filename, 5)) {
                generateIconMobileCallback("$imgRoot/$filename", ROOT."/js/mobile");
            }
        }
 
    }
 
    function generateIconMobileCallback($iconDir, $styleSaveDir) {
        //保存成js的文件名
        $saveName = array_pop(explode(‘/’, $iconDir));
        //JS文件保存路径
        $styleSavePath = $styleSaveDir.’/’.$saveName.’.js’;
 
        //将当前目录下的所有文件及MD5组成一个识别字符串
        $fileMap = array();
        $iterator = new DirectoryIterator($iconDir);
        foreach ($iterator as $file) {
            if ($file->isDot()) continue;
            $fileName = $file->getFilename();
            if ($file->isDir()) {
                generateIconMobileCallback($iconDir.’/’.$fileName, $styleSaveDir.’/’.$fileName);
            } else {
                $fileMap[$fileName] = md5_file($file->getRealPath());
            }
        }
        ksort($fileMap);
        $fileMapStr = json_encode($fileMap);
 
        //确保目录可写
        ensure_writable_dir($styleSaveDir);
 
        //js文件句柄
        $wirteHandle = fopen($styleSavePath, ‘w’);
        //当前小图标文件夹的相对路径
        $iconSaveRelative = substr($iconDir, strlen(ROOT));
        //写入,初始化保存数据的对象
        fwrite($wirteHandle, "/** icon in dir: $iconSaveRelative/ */ \nif(typeof(\$iconData) == ‘undefined’) \$iconData={};");
        foreach ($fileMap as $fileName => $md5) {
            //当前图片的绝对路径
            $fullPathName = "$iconDir/$fileName";
            //取得路径信息
            $pathInfo = pathinfo($fullPathName);
            //取得文件名(没有后缀)
            $fileNameNoExt = $pathInfo[‘filename’];
            //取得图片信息
            $imageSize = getimagesize($fullPathName);
 
            //取得文件的后缀
            switch ($imageSize[2]) {
                case IMAGETYPE_GIF:
                    $imageType = ‘gif’;
                    break;
                case IMAGETYPE_JPEG:
                    $imageType = ‘jpg’;
                    break;
                case IMAGETYPE_PNG:
                    $imageType = ‘png’;
                    break;
 
                default:
                    $imageType = ‘jpg’;
                    break;
            }
 
            //取得图片资源
            $readHandle = fopen($fullPathName, ‘r’);
            //将图片转成二进制并生成Base64编码
            $base64 = base64_encode(fread($readHandle, filesize($fullPathName)));
            //关闭资源
            fclose($readHandle);
            //将Base64编码写入js文件中
            fwrite($wirteHandle, "\n\$iconData.$fileNameNoExt=\"data:image/$imageType;base64,$base64\";");
        }
        //最后换个行
        fwrite($wirteHandle, "\n");
        //关闭资源
        fclose($wirteHandle);
 
        //处理成功的图标文件夹给予提示
        echo ‘<p>’.$iconSaveRelative. ‘ saved</p>’;  
    }
 
    /**
    * 确保文件夹存在并可写
    *
    * @param string $dir
    */
    function ensure_writable_dir($dir) {
        if(!file_exists($dir)) {
            mkdir($dir, 0766, true);
            @chmod($dir, 0766);
            @chmod($dir, 0777);
        }
        else if(!is_writable($dir)) {
            @chmod($dir, 0766);
            @chmod($dir, 0777);
            if(!@is_writable($dir)) {
                throw new BusinessLogicException("目录不可写", $dir);
            }
        }
    }
    generateIcon_mobile();
?>
 
<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<br>
<br>
<br>
 
<div>我们直接引入所生成的js文件,测试一下是否成功</div>
<br>
<div>直接在img标签里加入 icon-data = ‘图标文件名’  例如  <\img icon-data="tryit">,查看效果</div>
<br>
<br>
<br>
    <img icon-data="tryit">
    <script src="js/mobile/icon_pink.js"></script>
    <script src="js/mobile/jquery.all.min.js"></script>
    <script src="js/mobile/attrHandle.js"></script>
</body>
</html>

下一场那里附上属性调换的JS代码

JavaScript

$(function(){ setIconData(); }); function setIconData() { if
(typeof($iconData != ‘undefined’)) {
$(‘img[icon-data]’).each(function() { var self = $(this); var name =
self.attr(‘icon-data’); if (typeof($iconData[name]) != ‘undefined’) {
self.attr(‘src’, $iconData[name]); self.removeAttr(‘icon-data’); } });
} }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$(function(){
    setIconData();
});
 
function setIconData() {
    if (typeof($iconData != ‘undefined’)) {
        $(‘img[icon-data]’).each(function() {
            var self = $(this);
            var name = self.attr(‘icon-data’);
            if (typeof($iconData[name]) != ‘undefined’) {
                self.attr(‘src’, $iconData[name]);
                self.removeAttr(‘icon-data’);
            }
        });
    }
}

 

伍、完成效益

  那是页面输入效果,小Logo平常展现出来了

 

图片 2

 

此地大家自动生成的JS文件是这样子的格式:

图片 3

 

页面调用的代码:

图片 4

 

JS对img的icon-data属性转变处理的代码:

图片 5

 

我们相比下用base64编码和毫无base6肆时所成本的岁月:

先看不用的进程

图片 6

再看咱们用了base6四编码的快慢   图片 7

 

借使1个页面有不少小Logo,那么那种措施对网址的个性优化会有大大的提高。近日此种优化方案是用在自小编明日的体系中移动端,而上壹篇博文批注的调换背景图的优化方案用在大家项目中的PC端。优化成效是很分明的!当然了,base64编码那种措施也得以用在PC端,大家的项目为啥将它用在手提式有线电话机端,本博文开端部分也有对其做表明。那里测试自身就径直在PC端测试,手机端测试也是二个样的。

这里小编补偿某个:

(一)所生成的base6四的js文件是在开荒中就变化的了,而不是在用户访问时才去变通,小编把HTML代码和PHP代码写在1个文书里是便于,在真正项目中是分手的;

(二)使用此种优化技能有它的独到之处,当然也会有它的败笔,只有切合本人项指标优化手艺才是好技术;

(三)当中优化技能提出利用在手提式有线话机端(能够化解背景图优化措施所无法缓解的难点),而PC端的则用联合小Logo生成背景图的格局(看此文:);

(肆)此种优化本事壹般用来小Logo(十几K之下),也便是HTTP响应时间远远不止下载时间的时候,用此格局优化会看出明明的效益;

(5)当然能够包容别的优化本领协同使用,效果更显明,比如缓存等。

 

那二次就享受那么多给大家,代码笔者都贴上了,而且不少都标上了讲授,方便我们清楚。

假诺此博文中有哪个地方讲得令人为难精晓,欢迎留言交换,若有疏解错的地点欢迎提议。

只要您感到您能在此博经济学到了新知识,请为自己顶3个,如小说中有表明错的地点,欢迎建议。

  相互学习,共同进步!

2 赞 2 收藏
评论

图片 8

在网址开荒进度中,对于页面包车型大巴加载效用壹般都想尽办法求快。那么,怎么让本事更加快呢?收缩页面请求
是多个优化页面加载速度很好的秘技。上一篇博文

咱俩解说了
“利用将小Logo合成一张背景图来收缩HTTP请求”,那么,那1篇博文将执教

“ 将图片转成2进制并生成Base64编码,能够在网页中经过url查看图片”。

1、为啥选拔将图片转成二进制并生成Base6四编码,能够在网页中经过url查看图片的不二秘技减少HTTP请求数?

缘何作者会讲授“将图纸转成二进制并生成Base6肆编码,能够在网页中通过url查看图片”
那一种办法来压缩HTTP请求,进而优化页面吗?那里呢,是关系到移动端的Logo使用。上一篇博文所讲的措施是不是利用于手提式有线电话机端的网页呢?

不过,它会并发三个主题材料:背景图+css突显Logo时,Logo本人不能够缩放,比如背景图中6四px*6肆px的Logo,展现到分界面时务必设置icon的大

小也是64*6四。在PC网页中那常常不会有哪些难题,但在移动端设备上就完全不行。一样是四英寸的无绳电话机显示器,其分辨率有希望是320*400,也可能

是640*800,甚至也恐怕是191九*1080。这样64px*6肆px的图标在分裂的装置上看起来的深浅就会距离格外显著。

幸运的是,手提式无线电话机上的浏览器基本对此做了优化,会把装备模拟成更低的分辨率。比如在1136*640的IPHONE

5中得到$(window).width(),抽出来的是320而不是640,那样三个小幅为160px的图样占用的是显示器宽度的八分之四,而不是四分之一。手

机设备那样处理是为着化解包容性难题。除了网页,包含手提式有线电话机上app的分界面,在retina显示器上和非retina显示器上的大小是全然同样的,都以因为对分

辨率做了拍卖。

但是,移动设备这么的处理格局并不可能完全解决难点,因为机器的假如性测度在无数时候是不伏贴的,尤其是在android设备中。为了更加好地调控成分

展示的轻重,化解的不贰秘诀正是用pt代替ps,px是对应荧屏的分辨率,而pt是本着人眼睛实际上呼吸系统感染觉的轻重缓急,无论在何种分辨率的装备上,7二pt固定是一英

寸。

HTML的img标签成分的src属性不只是能够钦赐url,也足以钦定图片的贰进制数据流。然后经过img成分的自行缩放功效,内定img的轻重缓急,就能够兑以往分歧分辨率的配备上出示同一的Logo大小。

二、使用Base6四编码减少页面请求数

当大家的贰个页面中要传播诸多图纸时,尤其是局地小Logo,十几K、几K,甚至是字节级别大小的小Logo,那些小Logo都会大增HTTP请求,假使多了,

就会给服务器带来异常的大的下压力。比如要下载1些1两K大的小Logo,其实请求时带上的额外新闻有希望比Logo的深浅还要大。所以,在呼吁更多时,在网络传输的数

据自然就更加多了,传输的数目自然也就变慢了。而这里,大家利用Base6四的编码方式将图片直接嵌入到网页中,而不是从外部载入,那样就减少了HTTP请

求。当然了,它有三个小缺点,便是使近期页面的深浅变大了(对于优化来讲,其实这么些能够忽略,影响微乎其微)。看一下下图,小Logo大小为二.四k,等待响应时

间是1四ms,而接受多少,也便是下载时间约为0ms;总来讲之,在有大批量小Logo下载的时候,那样的格局去优化能大大提升网址的属性(在jquery

mobile和Taobao的手提式有线电话机站上边都有用到此技艺)。

图片 9

叁、开辟思路

将小Logo放在以icon_开头的文本夹里(以界别不用生成base64的图纸的公文夹)—>用程序去遍历文件夹图片

—>将每张图片的base64编码放在一个js对象里—>在HTML页面包车型客车img标签里
使用性质 icon-data =

‘Logo名(不带后缀)’来展现图片 —>

JS文件写八个函数对icon-data属性实行更改,变换来src属性,然后值就透过icon-data的属性值获得Logo名,然后开展对应的更迭获得相

应Logo的base6四编码 —> 显示图片

肆、代码完毕

$pathinfo=pathinfo($_SERVER[‘SCRIPT_FILENAME’]);

define(‘ROOT’,$pathinfo[‘dirname’]);

functiongenerateIcon_mobile(){

$imgRoot=ROOT.”/img/mobile”;

$iterator=newDirectoryIterator($imgRoot);

foreach($iteratoras$file){

if($file->isDot())continue;

$filename=$file->getFilename();

//识别出是不是以icon_起来的文书夹,假诺是,则对此文件夹的Logo举办base64编码处理

if($file->isDir()&&0===strncasecmp(‘icon_’,$filename,5)){

generateIconMobileCallback(“$imgRoot/$filename”,ROOT.”/js/mobile”);

}

}

}

functiongenerateIconMobileCallback($iconDir,$styleSaveDir){

//保存成js的文书名

$saveName=array_pop(explode(‘/’,$iconDir));

//JS文件保留路径

$styleSavePath=$styleSaveDir.’/’.$saveName.’.js’;

//将当前目录下的享有文件及MD5组成三个鉴定识别字符串

$fileMap=array();

$iterator=newDirectoryIterator($iconDir);

foreach($iteratoras$file){

if($file->isDot())continue;

$fileName=$file->getFilename();

if($file->isDir()){

generateIconMobileCallback($iconDir.’/’.$fileName,$styleSaveDir.’/’.$fileName);

}else{

$fileMap[$fileName]=md5_file($file->getRealPath());

}

}

ksort($fileMap);

$fileMapStr=json_encode($fileMap);

//确认保障目录可写

ensure_writable_dir($styleSaveDir);

//js文件句柄

$wirteHandle=fopen($styleSavePath,’w’);

//当前小Logo文件夹的相对路径

$iconSaveRelative=substr($iconDir,strlen(ROOT));

//写入,初步化保存数据的指标

fwrite($wirteHandle,”/** icon in dir: $iconSaveRelative/ */
\nif(typeof(\$iconData) == ‘undefined’) \$iconData={};”);

foreach($fileMapas$fileName=>$md5){

//当前图片的绝对路线

$fullPathName=”$iconDir/$fileName”;

//获得路线音讯

$pathInfo=pathinfo($fullPathName);

发表评论

电子邮件地址不会被公开。 必填项已用*标注