首页 > 优化 > 关键词 > 网站优化最新资讯 > 正文

大型网站优化技术:减少HTTP请求

2015-12-03 09:13 · 稿源:卢松松博客

在网站开发过程中,对于页面的加载效率一般都想尽办法求快。那么,怎么让才能更快呢?减少页面请求 是一个优化页面加载速度很好的方法。上一篇博文我们讲解了 “利用将小图标合成一张背景图来减少HTTP请求”,那么,这一篇博文将讲解  “ 将图片转成二进制并生成Base64编码,可以在网页中通过url查看图片”。

一、为何选择将图片转成二进制并生成Base64编码,可以在网页中通过url查看图片的方法减少HTTP请求数?

为什么我会讲解 “将图片转成二进制并生成Base64编码,可以在网页中通过url查看图片” 这一种方式来减少HTTP请求,进而优化页面呢?这里呢,是涉及到移动端的图标使用。上一篇博文所讲的方法能否使用于手机端的网页呢?

但是,它会出现一个问题:背景图+css显示图标时,图标本身无法缩放,比如背景图中64px*64px的图标,显示到界面时必须设置icon的大小也是64*64。在PC网页中这通常不会有什么问题,但在移动端设备上就完全行不通。同样是4英寸的手机屏幕,其分辨率有可能是320*400,也可能是640*800,甚至也可能是1920*1080。这样64px*64px的图标在不同的设备上看起来的大小就会差别非常明显。

幸运的是,手机上的浏览器基本对此做了优化,会把设备模拟成更低的分辨率。比如在1136*640的IPHONE 5中获取$(window).width(),取出来的是320而不是640,这样一个宽度为160px的图片占用的是屏幕宽度的一半,而不是1/4。手机设备这样处理是为了解决兼容性问题。除了网页,包括手机上app的界面,在retina屏幕上和非retina屏幕上的大小是完全一样的,都是因为对分辨率做了处理。

但是,移动设备这样的处理方式并不能完全解决问题,因为机器的假设性猜测在很多时候是不合适的,尤其是在android设备中。为了更好地控制元素显示的大小,解决的办法就是用pt代替ps,px是对应屏幕的分辨率,而pt是针对人眼睛实际感觉的大小,无论在何种分辨率的设备上,72pt固定是1英寸。

HTML的img标签元素的src属性不只是可以指定url,也可以指定图片的二进制数据流。然后通过img元素的自动缩放功能,指定img的大小,就可以实现在不同分辨率的设备上显示一致的图标大小。

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

当我们的一个页面中要传入很多图片时,特别是一些小图标,十几K、几K,甚至是字节级别大小的小图标,这些小图标都会增加HTTP请求,假如多了,就会给服务器带来很大的压力。比如要下载一些一两K大的小图标,其实请求时带上的额外信息有可能比图标的大小还要大。所以,在请求越多时,在网络传输的数据自然就越多了,传输的数据自然也就变慢了。而这里,我们采用Base64的编码方式将图片直接嵌入到网页中,而不是从外部载入,这样就减少了HTTP请求。当然了,它有一个小缺点,就是使当前页面的大小变大了(对于优化来说,其实这个可以忽略,影响不大)。看一下下图,小图标大小为2.4k,等待响应时间是14ms,而接受数据,也就是下载时间约为0ms;可想而知,在有大量小图标下载的时候,这样的方式去优化能大大提高网站的性能(在jquery mobile和天猫的手机站上面都有用到此技术)。

三、开发思路

将小图标放在以icon_开头的文件夹里(以区分不用生成base64的图片的文件夹)—>用程序去遍历文件夹图片 —>将每张图片的base64编码放在一个js对象里—>在HTML页面的img标签里 使用属性 icon-data = ‘图标名(不带后缀)’来显示图片 —> JS文件写一个函数对icon-data属性进行转换,转换成src属性,然后值就通过icon-data的属性值获得图标名,然后进行相应的替换得到相应图标的base64编码 —> 显示图片

四、代码实现

<?php
    $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_开头的文件夹,如果是,则对此文件夹的图标进行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');
        //当前小图标文件夹的相对路径
        $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);
            //取得文件名(没有后缀)
            $fileNameNoExt=$pathInfo['filename'];
            //取得图片信息
            $imageSize=getimagesize($fullPathName);
 
            //取得文件的后缀
            switch($imageSize[2]){
                caseIMAGETYPE_GIF:
                    $imageType='gif';
                    break;
                caseIMAGETYPE_JPEG:
                    $imageType='jpg';
                    break;
                caseIMAGETYPE_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
    */
    functionensure_writable_dir($dir){
        if(!file_exists($dir)){
            mkdir($dir,0766,true);
            @chmod($dir,0766);
            @chmod($dir,0777);
        }
        elseif(!is_writable($dir)){
            @chmod($dir,0766);
            @chmod($dir,0777);
            if(!@is_writable($dir)){
                thrownewBusinessLogicException("目录不可写",$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代码

$(function(){
    setIconData();
});
 
functionsetIconData(){
    if(typeof($iconData!='undefined')){
        $('img[icon-data]').each(function(){
            varself=$(this);
            varname=self.attr('icon-data');
            if(typeof($iconData[name])!='undefined'){
                self.attr('src',$iconData[name]);
                self.removeAttr('icon-data');
            }
        });
    }
}
  • 相关推荐
  • 大家在看
  • HTTP和HTTPS是什么?

    我们都知道使用浏览器访问一个网站页面,需要知道该网站的域名,例如访问百度知道,在浏览器的地址栏中我们会看到一串URL。网站的URL会分为两部分:通信协议和域名地址。域名地址都很好理解,不同的域名地址表示网站中不同的页面,而通信协议,简单来说就是浏览器和服务器之间沟通的语言。网站中的通信协议一般就是HTTP协议和HTTPS协议。两者分别是什么,有什么区别呢?HTTP协议HTTP协议也就是超文本传输协议,是一种使用明文数据?

  • 瑞幸咖啡宣布撤销召开听证会请求

    今日,瑞幸咖啡宣布,已决定撤回之前举行听证会的请求,公司股票将于2020年6月29日开盘时停牌。

  • 如何将访客转化为潜在客户?这个8个网站优化策略了解下

    你是否已经将自己的网站优化到最佳状态了呢?通过优化来产生潜在客户是转化网站已经获得的流量的最好方法之一。然而,如果你认为在网站的主页上添加几个“点击这里”的CTA策略(注:Callto Action,行动呼吁),就能获取更多的潜在客户,很遗憾的说,这个想法大错特错。

  • 李国庆发布离婚诉讼声明 请求法院尽快判离

    昨日晚间,李国庆发布《关于离婚诉讼的公开声明》称,俞渝不离婚目的是拖延离婚程序,控制当当,且不能排除通过赢得时间转移资产的可能。希望法院在事实基础上尽快判离,结束这场闹剧。

  • 最高法裁定加多宝可继续使用怕上火广告语 广药请求被驳回

    昨日,加多宝集团发布《关于“怕上火喝加多宝”广告语案件再审裁定书的公告》称,2020年6月18日,加多宝收到最高人民法院(2019) 最高法民申579号民事裁定书,该裁定书裁定驳回广药集团的再审申请。

  • 腾讯请求查封老干妈公司财产,原因是欠千万广告费

    6月30日,一则“腾讯诉贵州老干妈,申请查封贵州老干妈 1624 万财产”的消息成为今天的热门新闻,不少人认为这原本很难有交际的两家公司为何会对簿公堂,并且要求查封冻结千万财产,这让很多人十分疑惑。

  • 腾讯请求查封老干妈公司财产 附腾讯回应起诉老干妈原因全文

    腾讯请求查封老干妈公司财产是怎么回事?腾讯回应起诉老干妈说了什么?据中国裁判文书网信息,日前广东省深圳市南山区人民法院发布一则民事裁定书,同意原告腾讯请求查封、冻结被告老干妈公司公司名下价值人民币 16240600 元的财产。

  • 腾讯请求查封老干妈公司1624万财产 冻结原因介绍

    腾讯请求查封老干妈公司财产是怎么回事?据中国裁判文书网信息,日前广东省深圳市南山区人民法院发布一则民事裁定书,同意原告腾讯请求查封、冻结被告老干妈公司公司名下价值人民币 16240600 元的财产。

  • 因合同纠纷 腾讯请求查封贵州老干妈公司1624万财产

    6月30日消息,据媒体报道,广东省深圳市南山区人民法院发布一则民事裁定书,同意原告腾讯请求查封、冻结被告老干妈公司名下价值人民币16240600元的财产。公告显示,原告深圳市腾讯计算机系统有

  • 徐福记起诉聖福記商标无效一审胜诉 聖福記诉讼请求被驳回

    近日,北京知识产权法院就审结了一件因“聖福記及图” 商标而引发的商标权无效行政纠纷,法院一审认定原告圣福记公司所注册的第 13705835 号“聖福記及图”商标(下称诉争商标)不足以与徐福记公司的在先八枚引证商标相区分,从而判决驳回了原告的诉讼请求。

  • 瑞幸咖啡宣布撤销召开听证会请求 股票6月29日停牌退市

    今日,瑞幸咖啡宣布,已决定撤回之前举行听证会的请求,公司股票将于2020年6月29日开盘时停牌。受此影响,瑞幸咖啡开盘跌29.3%,开盘后触发熔断。

  • 腾讯回应请求查封老干妈1624万财产:长期拖欠千万元广告费 多次催办无果

    针对“腾讯请求查封老干妈1624万财产,向法院申请财产保全”一事,腾讯向凤凰网科技回应称,此事系老干妈在腾讯投放了千万元市场合作,但无视合同长期拖欠未支付,腾讯被迫依法起诉,申请资产保全,法院裁定冻结对方企业账户。2019年3月,腾讯与老干妈公司签订了一份《联合市场推广合作协议》,腾讯侧投放资源用于老干妈油辣椒系列推广,腾讯已依约履行相关义务、但老干妈未按照合同约定付款。腾讯多次?

  • 这个网站靠帮人们分析怎么在网上赚钱,月入近3万

    不少想要搞副业的人,曾经花费大量时间和精力尝试在线赚钱,但最后才发现自己白折腾了。eBiz Facts 是一个小团队,该平台花费大量时间研究和审查各种在线赚钱方法是否靠谱,然后给用户一些建议,让他们避免被骗,以及浪费时间、精力和金钱在一些容易“踩坑”在线业务,并做出更明智的决策。

  • Win10五月更新强力优化Chrome:内存占用量大幅减少

    尽管以超过60%的市场占有率荣膺全球第一大桌面浏览器,然而谷歌Chrome有个顽疾长期未被解决,即内存占用过高。以资源换速度的做法虽然有一定的道理,但对于不急于升级配置的用户来说,就没那么

  • HTC新机发布会官宣:6月16日见

    近日,HTC在官网挂出了一张全新海报,预告将于6月16日举行“1+1无限可能”发布会!海报上有一款手机若隐若现,如无意外,这次发布会应该就是HTC全新手机发布会。至于这款新机是谁

  • 苹果自动驾驶技术去年路测大幅减少 仅23辆车上路测试

    【TechWeb】6月16日消息,据国外媒体报道,外界期待很大的苹果自动驾驶项目,在去年的进展并不顺利,此前已经出现了大规模调整员工的消息,人员由5000人削减到了200人。而从最新的报道来看,苹果自动驾驶技术去年的路测也大幅减少,上路测试的车辆仅注册量的三分之一,路测里程也不到2018年一成。在上路测试的车辆方面,外媒在报道中表示,去年仅23辆配备有苹果自动驾驶系统的车辆上路测试,而苹果在加州机动车辆管理局注册有69辆

  • 主播临界爆料女友与LPL选手knight约会,事件完整经过介绍

    6月22日凌晨,微博认证为斗鱼直播平台签约主播“修仙者临界”在微博上表示LPL某选手和自己的女友约会,而这位LPL选手被指是TES战队的中单Knight,这引起了很多网友的关注,以下是这件事情的部分事件经过。

  • HTC U20 5G、Desire 20 Pro正式发布

    DoNews 6月16日消息(记者 刘文轩)许久未公布新机的HTC今天正式发布第一款5G手机HTC U20 5G,一同发布的还有4G中端手机Desire 20 Pro。HTC U20 5G搭载高通骁龙765G,支持原生双模5G连接,配备6.8英寸屏幕,5000mAh容量电池,售价只要18990元新台币(约4130元人民币),成为目前台湾市场最便宜的5G新机。HTC U20 5G背部搭载4颗镜头,分别是4800万像素/f1.8光圈标准镜头、800万像素/118度超广角镜头、超微距20mm镜头、200万像素景深

    HTC
  • 群晖DSM内嵌花生壳PHTunnel,无需公网IP快速实现NAS外网访问!

    随着互联网人口红利的消失,企业在创新求变的浪潮下不断寻求新的出路,资源整合、优势互补,才能不断为产品赋能,助推服务升级,保持强劲的发展动力。作为国产老牌内网穿透服务商,花生壳经过十几年技术沉淀,已经为千万级用户提供了成熟、稳定、专业的内网穿透服务,如今,通过开放内网穿透核心组件花生壳PHTunnel SDK,在为更多用户提供免费服务的同时,花生壳也为厂商提供了更好的增值服务。目前,已经有TP-LINK、中兴、360、小

  • CB Insights金融科技榜单出炉 云从科技成功入选

    6 月 29 日,由CB Insights 主办的“Future of Fintech China”峰会在上海普华永道会议厅发布了CB Insights Fintech 榜单,云从科技、蚂蚁集团、陆金所、京东数科等优秀企业成功入选TOP 50 金融科技企业。 CB Insights作为全球知名的市场数据研究平台,致力在中国范围内找出本年度最具前景的金融科技公司,以及该领域中的下一个独角兽。于是在甄选出的全球 250 家金融科技企业中,CB Insights中国团队全方位评估金融科技企业的自身

  • 参与评论
文明上网理性发言,请遵守新闻评论服务协议

热文