云顶娱乐集团

当前位置:云顶娱乐集团 > 云顶娱乐集团 > 重型网站优化工夫【云顶娱乐网站】,Canvas前端

重型网站优化工夫【云顶娱乐网站】,Canvas前端

来源:http://www.clubskodakaroq.com 作者:云顶娱乐集团 时间:2019-10-03 17:57

原型承接和类承袭

由此,原型承继和类承接是三种认识情势,本质上都以为了架空(复用代码)。相对于类,原型更初级且越来越灵敏。由此当八个系列内并未有太多涉及的事物的时候,用原型明显比用类越来越灵敏轻便。

原型承接的便捷性表未来系统中指标比较少的时候,原型承继无需结构额外的抽象类和接口就能够实现复用。(如系统里独有猫和狗二种动物来说,没供给再为它们组织一个虚幻的“动物类”)

原型传承的灵活性还表未来复用情势更灵活。由于原型和类的方式分化等,所以对复用的推断标准也就不平等,举例把一个革命皮球当作一个太阳的原型,当然是足以的(反过来也行),但一清二楚不可能将“恒星类”当做太阳和红球的共用父类(倒是能够用“球体”这几个类作为它们的公共父类)。

既然如此原型本质上是一种认识情势能够用来复用代码,那大家为什么还要模仿“类承袭”呢?在这其间大家就得看看原型承接有何样难点——

3.2、使用音讯首部字段Transfer-Encoding

当顾客端向服务器乞请二个静态页面或许一张图纸时,服务器能够很领悟的了然内容大小,然后通过Content-length音讯首部字段告诉客商端要求收取多少多少。不过假若是动态页面等时,服务器是不恐怕预先领会内容大小,那时就足以利用Transfer-Encoding:chunk情势来传输数据了。即假如要一边产生多少,一边发放顾客端,服务器就供给选用”Transfer-Encoding: chunked”那样的办法来代替Content-Length。

chunk编码将数据分为一块一块的发出。Chunked编码将利用几何个Chunk串连而成,由三个评释长度为0的chunk标示截至。每一种Chunk分为底部和正文两有的,尾部内容钦定正文的字符总数(十六进制的数字)和多少单位(通常不写),正文部分正是点名长度的实际内容,两部分之间用回车换行(C奥迪Q7LF)隔开分离。在结尾二个长短为0的Chunk中的内容是称呼footer的内容,是局地叠合的Header新闻(平日能够直接忽略)。

Chunk编码的格式如下:

Chunked-Body = *chunk
“0” CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF

hex-no-zero = <HEX excluding “0”>

chunk-size = hex-no-zero *HEX
chunk-ext = *( “;” chunk-ext-name [ “=” chunk-ext-value ] )
chunk-ext-name = token
chunk-ext-val = token | quoted-string
chunk-data = chunk-size(OCTET)

footer = *entity-header

即Chunk编码由四有的组成:1、0至多个chunk块,2、“0” CRLF,3、footer,4、CRLF.而每个chunk块由:chunk-size、chunk-ext(可选)、CRLF、chunk-data、CRLF组成。

参考

【1】:Canvas参照他事他说加以考察手册

【2】:《HTML5游乐开辟》

【3】:EdisonChou的FlappyBird

2 赞 6 收藏 评论

云顶娱乐网站 1

最小化央浼

所有在您的网址加载时用来渲染页面(外界CSS或JS文件、web字体、图片等等)的财富,都以见仁见智的HTTP乞求。平时的网址平均有 93个请求!

作者的对象是压缩HTTP诉求。一种格局是独家编译或三番五次(组合、合併)CSS和javascript到一个文本中。让这些进度自动化(比方利用营造筑工程具 Grunt 或 Gulp)是杰出的作用,但最少也应有在生产境况入手动达成。

其三方脚本是充实额外诉求最广大的罪魁祸首,很多赢得额外的文书如脚本、图像或CSS的呼吁都反复1个。浏览器内置的开辟者工具得以扶持您意识这个元凶。

云顶娱乐网站 2
谷歌(Google) Chrome开辟者工具的互联网选项卡

例如说,Facebook的台本发起3次呼吁。测验碰着中利用部分起点盛名社交网址的争论分享脚本,能够看见她们一点也不慢扩展:

站点 文件 大小
Google+ 1 15.1KB
Facebook 3 73.3KB
LinkedIn 2 47.7KB
Pinterest 3 12.9KB
Tumblr 1 1.5KB
Twitter 4 52.7KB
Total 14 203.2KB

来源:更管用的社会分享链接

那有额外的15个HTTP诉求,共203.2KB。相反,笔者看看 “share-intent” 以此url,它基本上是透过传递和创设数据来生成贰个分享,可以只利用HTML来成立社交分享链接。它让自个儿屏弃用于分享的第三方脚本,那几个本子须求7次呼吁。作者在Responsible Social Share Links那篇文章有越来越多的演讲。

评估每四个第三方脚本并规定其关键。大概存在一种不借助于第三方的艺术来成功它。你大概会遗失一些效果与利益(比如like、tweet、分享数量),可是请问一下温馨:“像数量总结就那么首要吗?”

静态财富文件自动削减并替换到压缩版本(大型网址优化手艺)

2015/11/26 · HTML5 · 静态能源

原稿出处: Kelly   

那三回,小编总计和分享一项大型网址优化本领,那正是在档案的次序中自行削减静态能源文件(css、js),并让网址活动加载压缩后的能源文件。当然,那项本事在雅虎35条前端优化提议里也许有记载,但它这只是给出二个答辩的方案而已,并且利用的是外界压缩工具去收缩,而在本身的品种中,是一向通过投机的前后相继自动化去减弱全部css、js文件,然后让页面一向加载所裁减后的能源,接下去直接步入正题。

本次实验应用的是PHP脚本语言,版本是PHP5.6,是在LINUX下搭建的境况(网络搭建无论是搭建LAMP依旧LNMP的科目都多姿多彩一无可取,后一次笔者会总计和分享什么在LINUX下搭建服务器遭受的博文,并且搭建的条件必须二次性搭建成功的)。所选用的框架是CI框架,所采取的模版是斯玛特y模板引擎。当然了,那几个只是本人所运用的条件而已,借使您是PHP开垦者,要是你要测量试验下此番试验,那么,小编提议您的PHP版本采取5.4以上,至于框架用哪些都以能够的。而一旦您不是PHP开垦者(你是JSP恐怕是ASP开拓者或然是任何开辟者),那么你精晓好这一思路后,完全能够在团结深谙的语言里张开尝试测量试验。

一、原理图

首先本人画一张思路图,便于我们先知道。

先是是财富减少原理图:

云顶娱乐网站 3

随着是能源文件替换的原理图:

云顶娱乐网站 4

假如我们认真精晓况兼看懂这两张原理图的话,基本上也就驾驭了本身所享受的笔触。借使依然不可能分晓的话,接下去笔者会结合代码,对以上原理图的每一步实行详细讲授。

二、思路详细分析

1.第一是调用该滑坡的主意,你能够把该格局放在网址所要加载的公共类的地方,举例每回访谈网址都会调用该滑坡方法开展削减。当然,这些只是在付出情况才会每一回都调用,如若是线上的条件,在您的网址发一遍新本子的时候,调用贰遍用来生成压缩版的静态能源就足以了。

class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); //压缩jscss能源文件 $this->compressResHandle(); } /** * 压缩js、css能源文件(优化) * @return [type] [description] */ private function compressResHandle() { $this->load->library('ResMinifier'); //压缩钦赐文件夹下的能源文件 $this->resminifier->compressRes(); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
 
        //压缩jscss资源文件
        $this->compressResHandle();
    }
    /**
     * 压缩js、css资源文件(优化)
     * @return [type] [description]
     */
    private function compressResHandle() {
        $this->load->library('ResMinifier');
        //压缩指定文件夹下的资源文件
        $this->resminifier->compressRes();
    }
}

2.随之就调用了 ResMinifier类里的 compressRes方法。在此间本身先附上 ResMinifier这几个类的代码,然后方便一步步拓宽深入分析教学

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * 财富压缩类 */ class ResMinifier { /** 须求减小的能源目录*/ public $compressResDir = ['css', 'js']; /** 忽略压缩的路径,譬喻此处是js/icon开头的路子忽略压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 财富根目录*/ public $resRootDir; /** 能源版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; } public function compressRes() { //获取寄存版本的能源文件 $resState = $this->getResState(); $count = 0; //早先遍历需求缩短的能源目录 foreach ($this->compressResDir as $resDir) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) { //获取该财富文件的相对路径$filePath = str_replace('\', '/', $file->getRealPath()); //获取文件相对路线 $object = substr($filePath, strlen($this->resRootDir)); //总括文件的本子号 $state = $this->_getResStateVersion($filePath); //获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; } //压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p推断是最重要部分之一*****************// //推断文件是还是不是存在且早就改成过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) { continue; } //确认保障/www/min/目录可写 $this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress) { $this->compressResFileAndSave($filePath, $minFilePath); } else { copy($filePath, $minFilePath); } $resState[$object] = $state; $resState[$minObject] = ''; $count++; if ($count == 50) { $this->_saveResState($resState); $count = 0; } } } if($count) $this->_saveResState($resState); } public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) { //获取财富绝对路径 $filePath = $this->resRootDir . $object; //推断财富是或不是留存 if (!file_exists($filePath)) return "能源文件官样文章{$file帕特h}"; //版本号 $state = $this-> _getResStateVersion($filePath); //文件名后缀 $extension = pathinfo($filePath, PATHINFO_EXTENSION); //是不是要减小 $needCompress = true; //决断能源文件是不是是以 .min.css也许.min.js结尾的 //此类结尾常常都以已减弱过,比方jquery.min.js,就不必再压缩了 if (str_end_with($object, '.min.'.$extension, true)) { //压缩后的财富存放路线,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir)) { //此处是急需减弱的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; //看看是还是不是是忽略的门路前缀 foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; } /** * 获取寄放能源版本的文件 * 它是坐落叁个数组里 * $resState = array( * '文件路线' => '对应的本子号', * '文件路线' => '对应的版本号', * '文件路线' => '对应的本子号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; } /** * 计算文件的本子号,这一个是依靠总结文件MD5散列值获得版本号 * 只要文件内容改变了,所总括获得的散列值就能不平等 * 用于剖断能源文件是或不是有改换过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); } /** * 确定保证目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } } /** * 将减弱后的能源文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}失利"); show_error("写入文件{$minFile帕特h}失利", -1); } } /** * 压缩财富文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不帮忙压缩{extension}文件[$filePath]"); show_error("不帮衬压缩{extension}文件[$filePath]", -1); } } private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $content); } } 点击打开财富压缩类

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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 资源压缩类
*/
class ResMinifier {
    /** 需要压缩的资源目录*/
    public $compressResDir = ['css', 'js'];
    /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
    public $compressResIngorePrefix = ['js/icon'];
    /** 资源根目录*/
    public $resRootDir;
    /** 资源版本文件路径*/
    private $resStatePath;
 
    public function __construct() {
        $this->resRootDir = WEBROOT . 'www/';
        $this->resStatePath = WEBROOT . 'www/resState.php';
    }
 
    public function compressRes() {
        //获取存放版本的资源文件
        $resState = $this->getResState();
        $count = 0;
 
        //开始遍历需要压缩的资源目录
        foreach ($this->compressResDir as $resDir) {
            foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                //获取该资源文件的绝对路径
                $filePath = str_replace('\', '/', $file->getRealPath());
                //获取文件相对路径
                $object = substr($filePath, strlen($this->resRootDir));
                //计算文件的版本号
                $state = $this->_getResStateVersion($filePath);
 
                //获取文件的几个参数值
                if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                    continue;
                }
 
                //压缩文件的绝对路径
                $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
 
                //************此处p判断是最重要部分之一*****************//
                //判断文件是否存在且已经改动过
                if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                    continue;
                }
 
                //确保/www/min/目录可写
                $this->_ensureWritableDir(dirname($minFilePath));
 
                if ($needCompress) {
                    $this->compressResFileAndSave($filePath, $minFilePath);
                } else {
                    copy($filePath, $minFilePath);
                }
 
                $resState[$object] = $state;
                $resState[$minObject] = '';
                $count++;
 
                if ($count == 50) {
                    $this->_saveResState($resState);
                    $count = 0;
                }
 
            }
        }
        if($count) $this->_saveResState($resState);
    }
 
    public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
        //获取资源绝对路径
        $filePath = $this->resRootDir . $object;
        //判断资源是否存在
        if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
        //版本号
        $state = $this-> _getResStateVersion($filePath);
        //文件名后缀
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        //是否要压缩
        $needCompress = true;
 
        //判断资源文件是否是以 .min.css或者.min.js结尾的
        //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
        if (str_end_with($object, '.min.'.$extension, true)) {
            //压缩后的资源存放路径,放在 /www/min/ 目录下
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
            $needCompress = false;
        } else if (in_array($extension, $this->compressResDir)) {
            //此处是需要压缩的文件目录
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
            //看看是否是忽略的路径前缀
            foreach ($this->compressResIngorePrefix as $v) {
                if (str_start_with($object, $v, true)) {
                    $needCompress = false;
                }
            }
        } else {
            $minObject = 'min/'.$object;
            $needCompress = false;
        }
        return true;
    }
 
    /**
     * 获取存放资源版本的文件
     * 它是放在一个数组里
     * $resState = array(
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *     );
     * @return [type] [description]
     */
    public function getResState() {
        if (file_exists($this->resStatePath)) {
            require $this->resStatePath;
            return $resState;
        }
        return [];
    }
 
    /**
     * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
     * 只要文件内容改变了,所计算得到的散列值就会不一样
     * 用于判断资源文件是否有改动过
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    public function _getResStateVersion($filePath) {
        return base_convert(crc32(md5_file($filePath)), 10, 36);
    }
 
    /**
     * 确保目录可写
     * @param  [type] $dir [description]
     * @return [type]      [description]
     */
    private function _ensureWritableDir($dir) {
        if (!file_exists($dir)) {
            @mkdir($dir, 0777, true);
            @chmod($dir, 0777);
        } else if (!is_writable($dir)) {
            @chmod($dir, 0777);
            if (!is_writable($dir)) {
                show_error('目录'.$dir.'不可写');
            }
        }
    }
 
    /**
     * 将压缩后的资源文件写入到/www/min/下去
     * @param  [type] $filePath    [description]
     * @param  [type] $minFilePath [description]
     * @return [type]              [description]
     */
    private function compressResFileAndSave($filePath, $minFilePath) {
        if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
 
            //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
            show_error("写入文件{$minFilePath}失败", -1);
        }
    }
 
    /**
     * 压缩资源文件
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    private function compressResFile($filePath) {
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        if ($extension === 'js') {
            require_once 'JShrink/Minifier.php';
            return JShrinkMinifier::minify(file_get_contents($filePath));
        } else if ($extension ==='css') {
            $content = file_get_contents($filePath);
            $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
            $content = str_replace(["rn", "r", "n"], '', $content);
            $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
            $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
            $content = str_replace(';}', '}', $content);
            return $content;
        } else {
            //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
            show_error("不支持压缩{extension}文件[$filePath]", -1);
 
        }
    }
 
    private function _saveResState($resState) {
        ksort($resState);
        $content = "<?phpnn$resState = array(n";
        foreach ($resState as $k => $v) {
            $content .= "t '$k' => '$v',n";
        }
        $content .= ");nn";
        file_put_contents($this->resStatePath, $content);
    }
 
}
 
点击打开 资源压缩类

万事类大多数代码笔者都加了疏解,方便大家非常快领悟。这里笔者也会对每一行代码实行表明。

(1)

PHP

/** 供给缩小的能源目录*/ public $compressResDir = ['css', 'js']; /** 忽略压缩的门路,举个例子此处是js/icon开首的不二等秘书籍忽略压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 能源根目录*/ public $resRootDir; /** 能源版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; }

1
2
3
4
5
6
7
8
9
10
11
12
13
/** 需要压缩的资源目录*/
    public $compressResDir = ['css', 'js'];
    /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
    public $compressResIngorePrefix = ['js/icon'];
    /** 资源根目录*/
    public $resRootDir;
    /** 资源版本文件路径*/
    private $resStatePath;
 
    public function __construct() {
        $this->resRootDir = WEBROOT . 'www/';
        $this->resStatePath = WEBROOT . 'www/resState.php';
    }

$compressResDir变量是亟需裁减的能源目录,尽管你有新的管理目录,能够在此变量里若是新的目录名就可以管理。附上自个儿测量试验项指标目录图

云顶娱乐网站 5

$compressResIngorePrefix 忽略被收缩的门路的门路前有的是该数组变量的字符串,例如有三个财富路线为 js/icon/bg.js大概是js/icon_index.js大概是js/icon.header.js,倘使在该数组中到场了 js/icon那个字符串,那么财富路线为js/icon开端的都会被忽视掉,也正是一向跳过,不用压缩。(因为财富文件里总有一对是无需收缩的呗)

$resRootDir寄放财富根目录的

$resState帕特h 这么些是财富版本文件路线

(2)步入compressRes() 方法,大家先剖析前面这一段代码

PHP

public function compressRes() { //获取贮存版本的财富文件 $resState = $this->getResState(); $count = 0;

1
2
3
4
public function compressRes() {
        //获取存放版本的资源文件
        $resState = $this->getResState();
        $count = 0;

——————————-调用getResState() 讲解start————————————————————-

那边首先是调用 $this->getResState() 方法来得到寄放版本的能源文件,此处先跳到该方法看看是哪些写的,其实正是带有该公文,然后回到里面存放版本号的数组,大家看注释能够清楚该公文里寄放版本号的格式(顺便附上海体育场面让大家看看)

PHP

/** * 获取寄放能源版本的公文 * 它是献身贰个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路径' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
     * 获取存放资源版本的文件
     * 它是放在一个数组里
     * $resState = array(
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *     );
     * @return [type] [description]
     */
    public function getResState() {
        if (file_exists($this->resStatePath)) {
            require $this->resStatePath;
            return $resState;
        }
        return [];
    }

(能源版本文件截图:)

云顶娱乐网站 6

——————————-调用getResState() 讲解end————————————————————-

随即看compressRes()里的这一段代码

PHP

//初阶遍历需求收缩的能源目录 foreach ($this->compressResDir as $resDir) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) { //获取该能源文件的相对路径$file帕特h = str_replace('\', '/', $file->getRealPath()); //获取文件相对路线 $object = substr($filePath, strlen($this->resRootDir)); //计算文件的本子号 $state = $this->_getResStateVersion($filePath);

1
2
3
4
5
6
7
8
9
//开始遍历需要压缩的资源目录
        foreach ($this->compressResDir as $resDir) {
            foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                //获取该资源文件的绝对路径
                $filePath = str_replace('\', '/', $file->getRealPath());
                //获取文件相对路径
                $object = substr($filePath, strlen($this->resRootDir));
                //计算文件的版本号
                $state = $this->_getResStateVersion($filePath);

首先个遍历的是js和css目录 第三个遍历是将js目录可能css目录里的文书都改成路线格局,

比方获取文件的相对路线 $filePath 的值是那样子的:

/usr/local/apache2/htdocs/project/www/css/home/index.css

而文件的相对路线$object是那样子的 :

css/home/index.css

此间就初阶调用$this->_getResStateVersion($filePath)来测算文件的本子号

——————————-调用_getResStateVersion($filePath) 讲解start————————————————————

PHP

/** * 总括文件的本子号,那几个是依据总括文件MD5散列值获得版本号 * 只要文件内容更改了,所总计获得的散列值就能够不雷同 * 用于决断财富文件是还是不是有改变过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); }

1
2
3
4
5
6
7
8
9
10
/**
     * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
     * 只要文件内容改变了,所计算得到的散列值就会不一样
     * 用于判断资源文件是否有改动过
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    public function _getResStateVersion($filePath) {
        return base_convert(crc32(md5_file($filePath)), 10, 36);
    }

——————————-调用_getResStateVersion($filePath) 讲解end————————————————————-

要么到版本号后,再看下一段代码,这里最初调用$this->getObjectInfo()方法,这里得到到压缩文件的相对路径$minObject,是还是不是要求压缩$needCompress,版本号$state,文件后缀$extension。

PHP

//获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; }

1
2
3
4
//获取文件的几个参数值
                if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                    continue;
                }

——————————调用$this->getObjectInfo() 讲解start————————————————————

PHP

/** * 获取能源文件有关音讯 * @param [type] $object 财富文件路线(www/css/home/index.css) * @param [type] $minObject 压缩能源文件路径(www/min/css/home/index.ae123a.css) * @param [type] $needCompress 是还是不是须求压缩 * @param [type] $state 文件版本号 * @param [type] $extension 文件名后缀 * @return [type] [description] */ public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) { //获取财富相对路线 $file帕特h = $this->resRootDir . $object; //判定财富是还是不是留存 if (!file_exists($filePath)) return "财富文件不设有{$filePath}"; //版本号 $state = $this-> _getResStateVersion($filePath); //文件名后缀 $extension = pathinfo($file帕特h, PATHINFO_EXTENSION); //是或不是要缩减 $needCompress = true; //决断能源文件是还是不是是以 .min.css只怕.min.js结尾的 //此类结尾日常都是已压缩过,举例jquery.min.js,就不要再压缩了 if (str_end_with($object, '.min.'.$extension, true)) { //压缩后的能源存放路线,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir)) { //此处是索要缩短的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; //看看是不是是忽略的门道前缀 foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; }

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
/**
     * 获取资源文件相关信息
     * @param  [type] $object       资源文件路径 (www/css/home/index.css)
     * @param  [type] $minObject    压缩资源文件路径 (www/min/css/home/index.ae123a.css)
     * @param  [type] $needCompress 是否需要压缩
     * @param  [type] $state        文件版本号
     * @param  [type] $extension    文件名后缀
     * @return [type]               [description]
     */
    public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
        //获取资源绝对路径
        $filePath = $this->resRootDir . $object;
        //判断资源是否存在
        if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
        //版本号
        $state = $this-> _getResStateVersion($filePath);
        //文件名后缀
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        //是否要压缩
        $needCompress = true;
 
        //判断资源文件是否是以 .min.css或者.min.js结尾的
        //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
        if (str_end_with($object, '.min.'.$extension, true)) {
            //压缩后的资源存放路径,放在 /www/min/ 目录下
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
            $needCompress = false;
        } else if (in_array($extension, $this->compressResDir)) {
            //此处是需要压缩的文件目录
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
            //看看是否是忽略的路径前缀
            foreach ($this->compressResIngorePrefix as $v) {
                if (str_start_with($object, $v, true)) {
                    $needCompress = false;
                }
            }
        } else {
            $minObject = 'min/'.$object;
            $needCompress = false;
        }
        return true;
    }

这一个方法里的每一行代码基本上都有注释了,所以就不一句句举行批注了,这里最首要看上边的论断部分:

if (str_end_with($object, ‘.min.’.$extension, true)) 那个判定是比较能源文件路线字串尾部是不是以 .min.$extension 结尾,比如是 jquery.min.js,这种文件本来正是
调整和裁减过的文书,所以就无须再张开压缩管理了, $minObject 这么些变量寄放的是压缩后的资源文件路径。
此处附上str_end_with()函数的代码:

PHP

/** * 判定 subject 是或不是以 search结尾, 参数钦命是还是不是忽略大小写 * @param [type] $subject [description] * @param [type] $search [description] * @param boolean $ignore_case [description] * @return [type] [description] */ function str_end_with($subject, $search, $ignore_case = false) { $len2 = strlen($search); if (0 === $len2) return true; $len1 = strlen($subject); if ($len2 > $len1) return false; if ($ignore_case) { return 0 === strcmp(substr($subject, $len1 - $len2), $search); } else { return 0 === strcasecmp(substr($subject, $len1 - $len2), $search); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
     * 判断 subject 是否以 search结尾, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_end_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len2 > $len1) return false;
        if ($ignore_case) {
            return 0 === strcmp(substr($subject, $len1 - $len2), $search);
        } else {
            return 0 === strcasecmp(substr($subject, $len1 - $len2), $search);
        }
    }

if (in_array($extension, $this->compressResDir),那么些判断便是是还是不是是要求管理的四个目录里的。

接下来中间的foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } }

其一是推断是不是是以$this->compressResIngorePrefix属性定义的前边部分字串开端的门路,是的话就忽略压缩该资源文件。

看清到终极else 就是认证该财富文件无需收缩了,最后是重回$minObject,$needCompress,$state,$extension这么些变量。

——————————-调用$this->getObjectInfo() 讲解end————————————————————-

到这里继续回来看 compressRes()方法里面包车型客车代码

PHP

//压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p决断是最要紧片段之一*****************// //剖断文件是还是不是存在且已经济体改动过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) { continue; }

1
2
3
4
5
6
7
8
//压缩文件的绝对路径
                $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
 
                //************此处p判断是最重要部分之一*****************//
                //判断文件是否存在且已经改动过
                if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                    continue;
                }

这段代码首先是拼接出压缩文件的相对路线,

随后下边那一个剖断是至关心重视要的片段,通过这些论断就足以通晓该财富文件是或不是被改换过,假若改动过的话,就再也对该财富文件进行削减,如果没退换过,就继续处理下二个能源文件。看这里的决断:isset($resState[$object]) && $resState[$object] == $state,那几个论断正是剖断该文件路线是或不是存在  并且文件中对应的版本号和计量出的版本号是或不是还一致;isset($resState[$minObject]) &&file_exists($minFilePath),那些是推断压缩文件路线是不是存在,并且该压缩文件是不是真实存在目录中。

看下一段代码,要是能走到这一局地,表明当前的那个财富文件是被更动过的(代码修改过),那么此时就对文本进行压缩操作了

PHP

//确认保证/www/min/目录可写 $this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress) { $this->compressResFileAndSave($filePath, $minFilePath); } else { copy($filePath, $minFilePath); }

1
2
3
4
5
6
7
8
//确保/www/min/目录可写
                $this->_ensureWritableDir(dirname($minFilePath));
 
                if ($needCompress) {
                    $this->compressResFileAndSave($filePath, $minFilePath);
                } else {
                    copy($filePath, $minFilePath);
                }

$this->_ensureWritableDir(),此措施是要确认保障新成立的www/min目录是可写的,这里附上代码:

——————————-调用$this->_ensureWritableDir() 讲解start————————————————————-

PHP

/** * 确定保证目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
     * 确保目录可写
     * @param  [type] $dir [description]
     * @return [type]      [description]
     */
    private function _ensureWritableDir($dir) {
        if (!file_exists($dir)) {
            @mkdir($dir, 0777, true);
            @chmod($dir, 0777);
        } else if (!is_writable($dir)) {
            @chmod($dir, 0777);
            if (!is_writable($dir)) {
                show_error('目录'.$dir.'不可写');
            }
        }
    }

——————————-调用$this->_ensureWritableDir() 讲解end————————————————————-

if ($needCompress),那个论断财富文件是不是须要减小,须要的话调用$this->compressResFileAndSave($filePath, $minFile帕特h);没有必要的话,直接复制文件到压缩文件路线 copy($filePath, $minFilePath);

先看$this->compressResFileAndSave()

——————————-调用$this->compressResFileAndSave() 讲解start————————————————————-

PHP

/** * 将减弱后的能源文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}退步"); show_error("写入文件{$minFilePath}战败", -1); } } /** * 压缩能源文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不扶助压缩{extension}文件[$filePath]"); show_error("不支持压缩{extension}文件[$filePath]", -1); } }

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
/**
     * 将压缩后的资源文件写入到/www/min/下去
     * @param  [type] $filePath    [description]
     * @param  [type] $minFilePath [description]
     * @return [type]              [description]
     */
    private function compressResFileAndSave($filePath, $minFilePath) {
        if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
 
            //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
            show_error("写入文件{$minFilePath}失败", -1);
        }
    }
 
    /**
     * 压缩资源文件
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    private function compressResFile($filePath) {
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        if ($extension === 'js') {
            require_once 'JShrink/Minifier.php';
            return JShrinkMinifier::minify(file_get_contents($filePath));
        } else if ($extension ==='css') {
            $content = file_get_contents($filePath);
            $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
            $content = str_replace(["rn", "r", "n"], '', $content);
            $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
            $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
            $content = str_replace(';}', '}', $content);
            return $content;
        } else {
            //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
            show_error("不支持压缩{extension}文件[$filePath]", -1);
 
        }
    }

先削减,再将精减后的开始和结果写入到 压缩文件路线里去。

作者们先看下那些压缩方法:

$this->compressResFile($filePath); 此方法中分两类压缩,第一类时对js文件进行压缩,第二类的对css文件进行削减。先说js压缩,这里是调用一个JShrink的类,它

贰个用来压缩js文件的PHP类,百度得以找到,调用那些类的minify()这么些方法就能够减掉了;而css的减少利用正则替换到压缩,把那么些空格换行什么的都去掉。到此就减弱成功

了,然后再将削减后的能源写入到相应的压缩文件路线里去。

——————————-调用$this->compressResFileAndSave() 讲解end————————————————————-

随即继续看compressRes()那一个措施里的代码,这里发轫正是保存新的版本号到$resState数组里 $object=>$state,还应该有便是新的削减路线$minObject,而那边$count++的遵守是,当那一个轮回48遍就将 $resState那么些数组写入二次到 resState.php文件里,这里是由于审慎考虑而已,若是你不加那个$count的管理这一部分也得以,最终写入一次就行了。

PHP

$resState[$object] = $state; $resState[$minObject] = ''; $count++; if ($count == 50) { $this->_saveResState($resState); $count = 0; } } } if($count) $this->_saveResState($resState);

1
2
3
4
5
6
7
8
9
10
11
12
$resState[$object] = $state;
                $resState[$minObject] = '';
                $count++;
 
                if ($count == 50) {
                    $this->_saveResState($resState);
                    $count = 0;
                }
 
            }
        }
        if($count) $this->_saveResState($resState);

这里看$this->_saveResState($resState),那个方法便是将$resState数组写入到resState.php文件里去的措施。

——————————-调用$this->_saveResState($resState) 讲解start————————————————————-

PHP

private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $content); }

1
2
3
4
5
6
7
8
9
private function _saveResState($resState) {
        ksort($resState);
        $content = "<?phpnn$resState = array(n";
        foreach ($resState as $k => $v) {
            $content .= "t '$k' => '$v',n";
        }
        $content .= ");nn";
        file_put_contents($this->resStatePath, $content);
    }

——————————-调用$this->_saveResState($resState) 讲解end————————————————————-

拍卖完后,看看所生成的文本,这里叁个文件会有几个本子,旧版本未有去除掉,在付出情状下删不删除都没难题,这里怎么不删除旧版本的压缩文件,那就事关到在更新八个应用服务器代码时所要注意的主题素材里。在此作者就多讲授一点啊,简单地举例吗,日常大型项目中的静态能源和模板文件是布局在分裂的机器集群上的,上线的长河中,静态能源和页面文件的安排时间间隔大概会相当长,对于贰个大型互连网使用来讲正是在多个相当小的岁月间隔内,都有望出现新客户访谈,借使旧版本的静态能源删除了,但新本子的静态财富还没布署到位,那么客户就加载不到该静态财富,结果综上可得,所以,平日情形下我们会保留旧版本的静态财富,然后等具有片段布局变成了,再通过自然的剧本删除掉也没涉及,其实,这几个不必删除也是足以的,你思索,三个品类发贰遍版本,才会调用三次能源文件降低方法,它只会对修改过的文件进行生成新版本号的静态文件而已。那一个就看个人的做法了。

云顶娱乐网站 7

笔者们能够张开看看,上边那个便是削减后的公文的代码了,文件原大小为16K,压缩后大致少了5K,今后是11K,压缩比大约是2/3,假若在大型项目中,二个复杂点的页面会有相当的大的静态能源文件要加载,通过此形式,大大地增加了加载的进程。(或者有一点朋友以为压缩个几K可能十几K算什么,完全能够忽略,其实本人想说的是,当您在大型项目中优化品种的时候,能够减弱几K的代码,也给网址的特性升高了一大截)

云顶娱乐网站 8

到此,能源缩瑕疵理就深入分析实现了。其实,有早晚基础的相爱的人,能够一直看自身分享的要命代码就能够了,假设掌握不了,再看自个儿上面这一步步的深入分析解说,小编是地处能看过来此博客的爱侣,无论技术是好依旧是稍弱,都能看懂,所以才对代码一步步地张开深入分析疏解。(希望各位多多指教小叔子)

————————————————————————————————————————-

  1. 接下去正是教学怎么着替换压缩后的财富文件了。

这个到Home.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Home extends MY_Controller { public function index() { $this->smartyData['test'] = 111; //那么些暗中认可是加载 www/css/home/index.css文件 $this->addResLink('index.css'); //这几个暗许是加载www/js/jquery.all.min.js文件 $this->addResLink('/jquery.all.min.js'); //这么些暗许是加载www/js/index.js文件 $this->addResLink('index.js'); $this->displayView('home/index.tpl'); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class Home extends MY_Controller {
    public function index() {
        $this->smartyData['test'] = 111;
        //这个默认是加载 www/css/home/index.css文件
        $this->addResLink('index.css');
        //这个默认是加载www/js/jquery.all.min.js文件
        $this->addResLink('/jquery.all.min.js');
        //这个默认是加载www/js/index.js文件
        $this->addResLink('index.js');
        $this->displayView('home/index.tpl');
    }
}

地点有加载三个能源文件,我们先看看$this->addResLink();这么些法子,那么些法子放在My_Controller.php里:

PHP

/** * 财富路径 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
     * 资源路径
     * @param [type] $filePath [description]
     */
    protected function addResLink($filePath) {
        list($filePath, $query) = explode('?', $filePath . '?');
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        foreach ($this->_resLink as $v) {
            if (false === array_search($filePath, $this->_resLink[$extension])) {
                $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query;
            }
        }
 
        return $this;
    }

此处关键是判定了能源文件是css照旧js,然后将其存放在 $this->_resLink那些个性里。

这正是说这里小编就先附上My_Controller.php那一个父类的保有代码吧

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); //压缩jscss财富文件 $this->compressResHandle(); } //==========================使用SMARTY模板引擎================================// /* Smarty母版页文件路线 */ protected $masterPage = 'default.tpl'; /* 视图像和文字件路线*/ protected $smartyView; /* 要赋值给smarty视图的数目*/ protected $smartyData = []; /* 能源文件*/ protected $_resLink = ['js'=>[], 'css'=>[]]; /** * 使用母版页输出一个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = null) { //为空则采用暗中认可母版 if ($masterPage == null) $masterPage = $this->masterPage; //获取视图的输出内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v); } //内容部分 $output .= $viewContent; //尾巴部分增添js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($v); } //发送最终输出结果以及服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_重型网站优化工夫【云顶娱乐网站】,Canvas前端游戏开采。DI酷威.'斯马特y.class.php'; $this->smarty = new 斯马特y(); $this->smarty->setCompileDir(应用软件PATH . 'cache/'); $this->smarty->setCacheDir(应用软件PATH . 'cache/'); } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } } /** * 财富路线 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; } private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) { if ('/' === $viewName[0]) $viewName = substr($viewName, 1); //是或不是利用模板,有,则路由到 /views/master_page/*****.tpl下去 if ($masterPage) { $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage); } //是否设置模板目录 if ($setTemplateDir) { $templateDir = VIEWPATH; $this->smarty->setTemplateDir($templateDir); } } /** * 压缩js、css财富文件(优化) * @return [type] [description] */ private function compressResHandle() { $this->load->library('ResMinifier'); //压缩内定文件夹下的财富文件 $this->resminifier->compressRes(); } } 点击展开 My_Controller.php

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
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
 
        //压缩jscss资源文件
        $this->compressResHandle();
    }
 
    //==========================使用SMARTY模板引擎================================//
    /* Smarty母版页文件路径 */
    protected $masterPage = 'default.tpl';
    /* 视图文件路径*/
    protected $smartyView;
    /* 要赋值给smarty视图的数据*/
    protected $smartyData = [];
    /* 资源文件*/
    protected $_resLink = ['js'=>[], 'css'=>[]];
 
    /**
     * 使用母版页输出一个视图
     * @return [type] [description]
     */
    protected function displayView($viewName = null, $masterPage = null) {
        //为空则选用默认母版
        if ($masterPage == null) $masterPage = $this->masterPage;
        //获取视图的输出内容
        $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage);
 
        $output = '';
 
        //添加css Link
        foreach ($this->_resLink['css'] as $v) {
            $output .= res_link($v);
        }
 
        //内容部分
        $output .= $viewContent;
        //尾部添加js 链接
        foreach ($this->_resLink['js'] as $v) {
            $output .= res_link($v);
        }
        //发送最终输出结果以及服务器的 HTTP 头到浏览器
 
        $this->output->_display($output);
        return $output;
    }
 
    private function _fetchView($smartyData, &$viewName, &$masterPage) {
        if ($viewName == null) $viewName = $this->smartyView;
 
        if (empty($this->smarty)) {
            require_once SMARTY_DIR.'Smarty.class.php';
            $this->smarty = new Smarty();
            $this->smarty->setCompileDir(APPPATH . 'cache/');
            $this->smarty->setCacheDir(APPPATH . 'cache/');
        }
 
        //设置视图真实路径
        $this->_getViewDir(true, $viewName, $masterPage, $templateDir);
 
        foreach ($smartyData as $k => $v) {
            $this->smarty->assign($k, $v);
        }
 
        if (empty($masterPage)) {
            return $this->smarty->fetch($viewName);
        } else {
            $this->smarty->assign('VIEW_MAIN', $viewName);
            return $this->smarty->fetch($masterPage);
        }
    }
 
    /**
     * 资源路径
     * @param [type] $filePath [description]
     */
    protected function addResLink($filePath) {
        list($filePath, $query) = explode('?', $filePath . '?');
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        foreach ($this->_resLink as $v) {
            if (false === array_search($filePath, $this->_resLink[$extension])) {
                $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query;
            }
        }
 
        return $this;
    }
 
    private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) {
        if ('/' === $viewName[0]) $viewName = substr($viewName, 1);
 
        //是否使用模板,有,则路由到 /views/master_page/*****.tpl下去
        if ($masterPage) {
            $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage);
        }
 
        //是否设置模板目录
        if ($setTemplateDir) {
            $templateDir = VIEWPATH;
            $this->smarty->setTemplateDir($templateDir);
        }
    }
 
    /**
     * 压缩js、css资源文件(优化)
     * @return [type] [description]
     */
    private function compressResHandle() {
        $this->load->library('ResMinifier');
        //压缩指定文件夹下的资源文件
        $this->resminifier->compressRes();
    }
}
 
点击打开 My_Controller.php

打字与印刷出来 $this->_resLink这特个性的结构是那样子的:

PHP

Array ( [js] => Array ( [0] => /jquery.all.min.js [1] => index.js ) [css] => Array ( [0] => index.css ) )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Array
(
    [js] => Array
        (
            [0] => /jquery.all.min.js
            [1] => index.js
        )
 
    [css] => Array
        (
            [0] => index.css
        )
 
)

再回到Home.php里面调用 $this->displayView(‘home/index.tpl’);

我们看那几个艺术:

PHP

/** * 使用母版页输出三个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = null) { //为空则选拔私下认可母版 if ($masterPage == null) $masterPage = $this->masterPage; //获取视图的出口内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v); } //内容部分 $output .= $viewContent; //尾巴部分增多js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($v); } //发送最终输出结果以及服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_DI本田CR-V.'斯马特y.class.php'; $this->smarty = new 斯Matty(); $this->smarty->setCompileDir(应用程式PATH . 'cache/'); $this->smarty->setCacheDir(APPPATH . 'cache/'); } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } }

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
/**
     * 使用母版页输出一个视图
     * @return [type] [description]
     */
    protected function displayView($viewName = null, $masterPage = null) {
        //为空则选用默认母版
        if ($masterPage == null) $masterPage = $this->masterPage;
        //获取视图的输出内容
        $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage);
 
        $output = '';
 
        //添加css Link
        foreach ($this->_resLink['css'] as $v) {
            $output .= res_link($v);
        }
 
        //内容部分
        $output .= $viewContent;
        //尾部添加js 链接
        foreach ($this->_resLink['js'] as $v) {
            $output .= res_link($v);
        }
        //发送最终输出结果以及服务器的 HTTP 头到浏览器
 
        $this->output->_display($output);
        return $output;
    }
 
    private function _fetchView($smartyData, &$viewName, &$masterPage) {
        if ($viewName == null) $viewName = $this->smartyView;
 
        if (empty($this->smarty)) {
            require_once SMARTY_DIR.'Smarty.class.php';
            $this->smarty = new Smarty();
            $this->smarty->setCompileDir(APPPATH . 'cache/');
            $this->smarty->setCacheDir(APPPATH . 'cache/');
        }
 
        //设置视图真实路径
        $this->_getViewDir(true, $viewName, $masterPage, $templateDir);
 
        foreach ($smartyData as $k => $v) {
            $this->smarty->assign($k, $v);
        }
 
        if (empty($masterPage)) {
            return $this->smarty->fetch($viewName);
        } else {
            $this->smarty->assign('VIEW_MAIN', $viewName);
            return $this->smarty->fetch($masterPage);
        }
    }

这一段代码未有一部分正是调用了斯马特y模板引擎的从头到尾的经过,那一个关于斯马特y的学问笔者就不讲了,我们能够友善百度,这里关键讲 res_link() 这么些函数,正是通过那一个函数来张开财富文件替换的。先看那一个函数的代码:

PHP

/** * 输出 HttpHead 中的能源总是。 css/js 自动判定真实路线 * @param string 文件路线 * @return string */ function res_link($file) { $file = res_path($file, $extension); if ($extension === 'css') { return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>'; } else if ($extension === 'js') { return '<script type="text/javascript" src="'.$file.'"></script>'; } else { return false; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
     * 输出 HttpHead 中的资源连接。 css/js 自动判断真实路径
     * @param  string  文件路径
     * @return string      
     */
    function res_link($file) {
        $file = res_path($file, $extension);
 
        if ($extension === 'css') {
           return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>';
        } else if ($extension === 'js') {
            return '<script type="text/javascript" src="'.$file.'"></script>';
        } else {
            return false;
        }
    }

这边最关键就是 res_path() 函数了,那个函数能半自动路由财富的真正路径。举例:index.css = > css/home/index.css

该函数最根本的二个作用是替换能源的收缩版本。

一贯看代码:

PHP

/** * 智能路由能源实际路线 * @param string 路径 * @param string 扩展名 * @return string 真实路线 */ function res_path($file, &$extension) { //检查是不是留存询问字符串 list($file, $query) = explode('?', $file . '?'); //获得扩大名 $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); // $file = str_replace('\', '/', $file); //取妥帖前调节器名 global $class; if ($class == null) exit('can not get class name'); $className = strtolower($class); //此处的准则是这么: //比如,借使不加 / ,Home调节器对应的格式是: index.css,那么 此处的路线会产生css/home/index.css //即使有 / ,调控器的格式能够是 /main.css,那么这里的路线会产生 css/main.css(公用的css类) if ('/' !== $file[0]) { //index.css => css/home/index.css $object = $extension .'/'. $className .'/' . $file; } else { // /css/main.css 或许 /main.css => css/main.css $object = substr($file, 1); //若object是 main.css ,则自动抬高 扩展名目录 => css/main.css if (0 !== strncasecmp($extension, $object, strlen($extension))) { $object = $extension . '/' . $object; } } //财富真实路线 $filepath = WEBROOT.'www/'.$object; //替换压缩版本,那有的逻辑与公事收缩逻辑对应 if (in_array($extension, array('css', 'js'))) { if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) { require_once 应用软件PATH.'libraries/ResMinifier.php'; $resminifier = new ResMinifier(); //获取存放财富版本的文件的数组变量 $resState = $resminifier->getResState(); //总结取稳妥前文件版本号 $state = $resminifier->_getResStateVersion($filepath); //判定该版本号是或不是留存 if (isset($resState[$object])) { //推断是不是是.min.css或.min.js结尾 if (str_end_with($object, '.min.'.$extension)) { //将版本号拼接上去,然后拿走min的文本路线 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension; } else { //将版本号拼接上去,然后拿走min的文件路线 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; } //判别min的门径是还是不是留存在$resState里面 if (isset($resState[$minObject])) { $object = $minObject; $query = ''; } } } $file = RES_BASE_URL . $object; } return ($query == null) ? $file : ($file .'?'. $query); }

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
/**
     * 智能路由资源真实路径
     * @param  string      路径
     * @param  string      扩展名
     * @return string       真实路径
     */
    function res_path($file, &$extension) {
        //检查是否存在查询字符串
        list($file, $query) = explode('?', $file . '?');
        //取得扩展名
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        //
        $file = str_replace('\', '/', $file);
        //取得当前控制器名
        global $class;
        if ($class == null) exit('can not get class name');
        $className = strtolower($class);
 
        //此处的规则是这样:
        //例如,如果不加 / ,Home控制器对应的格式是: index.css,那么 此处的路径会变成css/home/index.css
        //假如有 / ,控制器的格式可以是 /main.css,那么此处的路径会变成 css/main.css(公用的css类)
        if ('/' !== $file[0]) {
            //index.css => css/home/index.css
            $object = $extension .'/'. $className .'/' . $file;
        } else {
            // /css/main.css 或者 /main.css => css/main.css
            $object = substr($file, 1);
 
            //若object是 main.css ,则自动加上 扩展名目录 => css/main.css
            if (0 !== strncasecmp($extension, $object, strlen($extension))) {
                $object = $extension . '/' . $object;
            }
        }
        //资源真实路径
        $filepath = WEBROOT.'www/'.$object;
 
        //替换压缩版本,这部分逻辑与文件压缩逻辑对应
        if (in_array($extension, array('css', 'js'))) {
            if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) {
                require_once APPPATH.'libraries/ResMinifier.php';
                $resminifier = new ResMinifier();
                //获取存放资源版本的文件的数组变量
                $resState = $resminifier->getResState();
                //计算得到当前文件版本号
                $state = $resminifier->_getResStateVersion($filepath);
                //判断该版本号是否存在
                if (isset($resState[$object])) {
                    //判断是否是.min.css或.min.js结尾
                    if (str_end_with($object, '.min.'.$extension)) {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension;
                    } else {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                    }
                    //判断min的路径是否存在在$resState里面
                     if (isset($resState[$minObject])) {
                        $object = $minObject;
                        $query = '';
                     }
                }
 
            }
 
            $file = RES_BASE_URL . $object;
        }
 
        return ($query == null) ? $file : ($file .'?'. $query);
 
    }

代码基本上都给了批注,方便我们轻易去领会,前面一部分是智能路线css、js能源的门路,前边一部分是替换压缩版本,这一有的的逻辑其实和资源减少这里的逻辑基本一样,正是通过财富文件路线,实行推断和管理,最终得到能源的滑坡版本的门径,最终就将资源的回退版本的路子重回去,放在'<link rel=”stylesheet” type=”text/css” href=”‘ . $file . ‘”/>’里面。那样  ,就打响地将财富文件路线替换到了削减版本的财富文件路线,何况在模板输出时,输出的是缩减后的财富文件。

到此,能源替换的内容就到此讲明结束。而整一项技巧也深入分析到此。

三、总结

在这里小编聚焦地附着本博文讲授中的多少个公文代码:

Home.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Home extends MY_Controller { public function index() { $this->smartyData['test'] = 111; //这些暗许是加载 www/css/home/index.css文件 $this->addResLink('index.css'); //那些暗许是加载www/js/jquery.all.min.js文件 $this->addResLink('/jquery.all.min.js'); //那么些暗中认可是加载www/js/index.js文件 $this->addResLink('index.js'); $this->displayView('home/index.tpl'); } } 点击展开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class Home extends MY_Controller {
    public function index() {
        $this->smartyData['test'] = 111;
        //这个默认是加载 www/css/home/index.css文件
        $this->addResLink('index.css');
        //这个默认是加载www/js/jquery.all.min.js文件
        $this->addResLink('/jquery.all.min.js');
        //这个默认是加载www/js/index.js文件
        $this->addResLink('index.js');
        $this->displayView('home/index.tpl');
    }
}
 
点击打开

My_Controller.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); //压缩jscss财富文件 $this->compressResHandle(); } //==========================使用SMARTY模板引擎================================// /* 斯马特y母版页文件路线 */ protected $masterPage = 'default.tpl'; /* 视图像和文字件路线*/ protected $smartyView; /* 要赋值给smarty视图的多寡*/ protected $smartyData = []; /* 财富文件*/ protected $_resLink = ['js'=>[], 'css'=>[]]; /** * 使用母版页输出七个视图 * @return [type] [description] */ protected function displayView($viewName = null, $masterPage = null) { //为空则选择暗中同意母版 if ($masterPage == null) $masterPage = $this->masterPage; //获取视图的输出内容 $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage); $output = ''; //添加css Link foreach ($this->_resLink['css'] as $v) { $output .= res_link($v); } //内容部分 $output .= $viewContent; //尾巴部分增多js 链接 foreach ($this->_resLink['js'] as $v) { $output .= res_link($v); } //发送最后输出结果以及服务器的 HTTP 头到浏览器 $this->output->_display($output); return $output; } private function _fetchView($smartyData, &$viewName, &$masterPage) { if ($viewName == null) $viewName = $this->smartyView; if (empty($this->smarty)) { require_once SMARTY_DILacrosse.'Smarty.class.php'; $this->smarty = new 斯马特y(); $this->smarty->setCompileDir(应用程式PATH . 'cache/'); $this->smarty->setCacheDir(应用程式PATH . 'cache/'); } //设置视图真实路线 $this->_getViewDir(true, $viewName, $masterPage, $templateDir); foreach ($smartyData as $k => $v) { $this->smarty->assign($k, $v); } if (empty($masterPage)) { return $this->smarty->fetch($viewName); } else { $this->smarty->assign('VIEW_MAIN', $viewName); return $this->smarty->fetch($masterPage); } } /** * 能源路线 * @param [type] $filePath [description] */ protected function addResLink($filePath) { list($filePath, $query) = explode('?', $filePath . '?'); $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); foreach ($this->_resLink as $v) { if (false === array_search($filePath, $this->_resLink[$extension])) { $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query; } } return $this; } private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) { if ('/' === $viewName[0]) $viewName = substr($viewName, 1); //是不是利用模板,有,则路由到 /views/master_page/*****.tpl下去 if ($masterPage) { $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage); } //是不是设置模板目录 if ($setTemplateDir) { $templateDir = VIEWPATH; $this->smarty->setTemplateDir($templateDir); } } /** * 压缩js、css能源文件(优化) * @return [type] [description] */ private function compressResHandle() { $this->load->library('ResMinifier'); //压缩内定文件夹下的能源文件 $this->resminifier->compressRes(); } } 点击展开

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
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
 
class MY_Controller extends CI_Controller {
    public function __construct() {
        parent::__construct();
 
        //压缩jscss资源文件
        $this->compressResHandle();
    }
 
    //==========================使用SMARTY模板引擎================================//
    /* Smarty母版页文件路径 */
    protected $masterPage = 'default.tpl';
    /* 视图文件路径*/
    protected $smartyView;
    /* 要赋值给smarty视图的数据*/
    protected $smartyData = [];
    /* 资源文件*/
    protected $_resLink = ['js'=>[], 'css'=>[]];
 
    /**
     * 使用母版页输出一个视图
     * @return [type] [description]
     */
    protected function displayView($viewName = null, $masterPage = null) {
        //为空则选用默认母版
        if ($masterPage == null) $masterPage = $this->masterPage;
        //获取视图的输出内容
        $viewContent = $this->_fetchView($this->smartyData, $viewName, $masterPage);
 
        $output = '';
 
        //添加css Link
        foreach ($this->_resLink['css'] as $v) {
            $output .= res_link($v);
        }
 
        //内容部分
        $output .= $viewContent;
        //尾部添加js 链接
        foreach ($this->_resLink['js'] as $v) {
            $output .= res_link($v);
        }
        //发送最终输出结果以及服务器的 HTTP 头到浏览器
 
        $this->output->_display($output);
        return $output;
    }
 
    private function _fetchView($smartyData, &$viewName, &$masterPage) {
        if ($viewName == null) $viewName = $this->smartyView;
 
        if (empty($this->smarty)) {
            require_once SMARTY_DIR.'Smarty.class.php';
            $this->smarty = new Smarty();
            $this->smarty->setCompileDir(APPPATH . 'cache/');
            $this->smarty->setCacheDir(APPPATH . 'cache/');
        }
 
        //设置视图真实路径
        $this->_getViewDir(true, $viewName, $masterPage, $templateDir);
 
        foreach ($smartyData as $k => $v) {
            $this->smarty->assign($k, $v);
        }
 
        if (empty($masterPage)) {
            return $this->smarty->fetch($viewName);
        } else {
            $this->smarty->assign('VIEW_MAIN', $viewName);
            return $this->smarty->fetch($masterPage);
        }
    }
 
    /**
     * 资源路径
     * @param [type] $filePath [description]
     */
    protected function addResLink($filePath) {
        list($filePath, $query) = explode('?', $filePath . '?');
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        foreach ($this->_resLink as $v) {
            if (false === array_search($filePath, $this->_resLink[$extension])) {
                $this->_resLink[$extension][] = $query == null ? $filePath : $filePath .'?'. $query;
            }
        }
 
        return $this;
    }
 
    private function _getViewDir($setTemplateDir, &$viewName, &$masterPage = null, &$templateDir) {
        if ('/' === $viewName[0]) $viewName = substr($viewName, 1);
 
        //是否使用模板,有,则路由到 /views/master_page/*****.tpl下去
        if ($masterPage) {
            $masterPage = '/' === $masterPage[0] ? substr($masterPage, 1) : ('master_page' .'/'. $masterPage);
        }
 
        //是否设置模板目录
        if ($setTemplateDir) {
            $templateDir = VIEWPATH;
            $this->smarty->setTemplateDir($templateDir);
        }
    }
 
    /**
     * 压缩js、css资源文件(优化)
     * @return [type] [description]
     */
    private function compressResHandle() {
        $this->load->library('ResMinifier');
        //压缩指定文件夹下的资源文件
        $this->resminifier->compressRes();
    }
}
 
点击打开

ResMinifier.php

PHP

<?php defined('BASEPATH') OR exit('No direct script access allowed'); /** * 财富压缩类 */ class ResMinifier { /** 需求减小的能源目录*/ public $compressResDir = ['css', 'js']; /** 忽略压缩的路线,举例此处是js/icon开首的门径忽略压缩*/ public $compressResIngorePrefix = ['js/icon']; /** 财富根目录*/ public $resRootDir; /** 能源版本文件路线*/ private $resStatePath; public function __construct() { $this->resRootDir = WEBROOT . 'www/'; $this->resStatePath = WEBROOT . 'www/resState.php'; } public function compressRes() { //获取寄存版本的财富文件 $resState = $this->getResState(); $count = 0; //初步遍历需求减弱的财富目录 foreach ($this->compressResDir as $resDir) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) { //获取该能源文件的相对路线$filePath = str_replace('\', '/', $file->getRealPath()); //获取文件相对路线 $object = substr($filePath, strlen($this->resRootDir)); //计算文件的本子号 $state = $this->_getResStateVersion($filePath); //获取文件的多少个参数值 if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) { continue; } //压缩文件的相对路线 $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject); //************此处p判别是最入眼部分之一*****************// //判定文件是或不是存在且已经济体改成过 if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) { continue; } //确定保证/www/min/目录可写 $this->_ensureWritableDir(dirname($minFilePath)); if ($needCompress) { $this->compressResFileAndSave($filePath, $minFilePath); } else { copy($filePath, $minFilePath); } $resState[$object] = $state; $resState[$minObject] = ''; $count++; if ($count == 50) { $this->_saveResState($resState); $count = 0; } } } if($count) $this->_saveResState($resState); } /** * 获取能源文件有关新闻 * @param [type] $object 能源文件路径 (www/css/home/index.css) * @param [type] $minObject 压缩财富文件路线 (www/min/css/home/index.ae123a.css) * @param [type] $needCompress 是不是要求压缩 * @param [type] $state 文件版本号 * @param [type] $extension 文件名后缀 * @return [type] [description] */ public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) { //获取资源相对路线 $filePath = $this->resRootDir . $object; //判别能源是或不是留存 if (!file_exists($filePath)) return "资源文件子虚乌有{$filePath}"; //版本号 $state = $this-> _getResStateVersion($file帕特h); //文件名后缀 $extension = pathinfo($file帕特h, PATHINFO_EXTENSION); //是不是要削减 $needCompress = true; //判别财富文件是或不是是以 .min.css或然.min.js结尾的 //此类结尾日常都是已收缩过,例如jquery.min.js,就无须再压缩了 if (str_end_with($object, '.min.'.$extension, true)) { //压缩后的资源贮存路径,放在 /www/min/ 目录下 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension; $needCompress = false; } else if (in_array($extension, $this->compressResDir)) { //此处是急需减小的文件目录 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; //看看是或不是是忽略的路径前缀 foreach ($this->compressResIngorePrefix as $v) { if (str_start_with($object, $v, true)) { $needCompress = false; } } } else { $minObject = 'min/'.$object; $needCompress = false; } return true; } /** * 获取存放财富版本的文书 * 它是坐落三个数组里 * $resState = array( * '文件路线' => '对应的版本号', * '文件路径' => '对应的本子号', * '文件路线' => '对应的版本号', * ); * @return [type] [description] */ public function getResState() { if (file_exists($this->resStatePath)) { require $this->resStatePath; return $resState; } return []; } /** * 总计文件的版本号,那一个是基于估测计算文件MD5散列值得到版本号 * 只要文件内容更换了,所计算获得的散列值就能够不均等 * 用于判定财富文件是还是不是有改换过 * @param [type] $filePath [description] * @return [type] [description] */ public function _getResStateVersion($filePath) { return base_convert(crc32(md5_file($filePath)), 10, 36); } /** * 确定保证目录可写 * @param [type] $dir [description] * @return [type] [description] */ private function _ensureWritableDir($dir) { if (!file_exists($dir)) { @mkdir($dir, 0777, true); @chmod($dir, 0777); } else if (!is_writable($dir)) { @chmod($dir, 0777); if (!is_writable($dir)) { show_error('目录'.$dir.'不可写'); } } } /** * 将缩减后的能源文件写入到/www/min/下去 * @param [type] $filePath [description] * @param [type] $minFilePath [description] * @return [type] [description] */ private function compressResFileAndSave($filePath, $minFilePath) { if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) { //$CI->exceptions->show_exception("写入文件{$minFilePath}失利"); show_error("写入文件{$minFilePath}战败", -1); } } /** * 压缩财富文件 * @param [type] $filePath [description] * @return [type] [description] */ private function compressResFile($filePath) { $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); if ($extension === 'js') { require_once 'JShrink/Minifier.php'; return JShrinkMinifier::minify(file_get_contents($filePath)); } else if ($extension ==='css') { $content = file_get_contents($filePath); $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content); $content = str_replace(["rn", "r", "n"], '', $content); $content = preg_replace('/([{}),;:>])s+/', '$1', $content); $content = preg_replace('/s+([{}),;:>])/', '$1', $content); $content = str_replace(';}', '}', $content); return $content; } else { //$CI->exceptions->show_exception("不扶助压缩{extension}文件[$filePath]"); show_error("不接济压缩{extension}文件[$filePath]", -1); } } private function _saveResState($resState) { ksort($resState); $content = "<?phpnn$resState = array(n"; foreach ($resState as $k => $v) { $content .= "t '$k' => '$v',n"; } $content .= ");nn"; file_put_contents($this->resStatePath, $content); } } 点击展开

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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/**
* 资源压缩类
*/
class ResMinifier {
    /** 需要压缩的资源目录*/
    public $compressResDir = ['css', 'js'];
    /** 忽略压缩的路径,例如此处是js/icon开头的路径忽略压缩*/
    public $compressResIngorePrefix = ['js/icon'];
    /** 资源根目录*/
    public $resRootDir;
    /** 资源版本文件路径*/
    private $resStatePath;
 
    public function __construct() {
        $this->resRootDir = WEBROOT . 'www/';
        $this->resStatePath = WEBROOT . 'www/resState.php';
    }
 
    public function compressRes() {
        //获取存放版本的资源文件
        $resState = $this->getResState();
        $count = 0;
 
        //开始遍历需要压缩的资源目录
        foreach ($this->compressResDir as $resDir) {
            foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->resRootDir . $resDir , FilesystemIterator::SKIP_DOTS)) as $file) {
                //获取该资源文件的绝对路径
                $filePath = str_replace('\', '/', $file->getRealPath());
 
                //获取文件相对路径
                $object = substr($filePath, strlen($this->resRootDir));
 
                //计算文件的版本号
                $state = $this->_getResStateVersion($filePath);
 
                //获取文件的几个参数值
                if (true !== $this->getObjectInfo($object, $minObject, $needCompress, $state, $extension)) {
                    continue;
                }
 
                //压缩文件的绝对路径
                $minFilePath = str_replace('\', '/', $this->resRootDir. $minObject);
 
                //************此处p判断是最重要部分之一*****************//
                //判断文件是否存在且已经改动过
                if (isset($resState[$object]) && $resState[$object] == $state && isset($resState[$minObject]) && file_exists($minFilePath)) {
                    continue;
                }
 
                //确保/www/min/目录可写
                $this->_ensureWritableDir(dirname($minFilePath));
 
                if ($needCompress) {
                    $this->compressResFileAndSave($filePath, $minFilePath);
                } else {
                    copy($filePath, $minFilePath);
                }
 
                $resState[$object] = $state;
                $resState[$minObject] = '';
                $count++;
 
                if ($count == 50) {
                    $this->_saveResState($resState);
                    $count = 0;
                }
 
            }
        }
        if($count) $this->_saveResState($resState);
    }
 
    /**
     * 获取资源文件相关信息
     * @param  [type] $object       资源文件路径 (www/css/home/index.css)
     * @param  [type] $minObject    压缩资源文件路径 (www/min/css/home/index.ae123a.css)
     * @param  [type] $needCompress 是否需要压缩
     * @param  [type] $state        文件版本号
     * @param  [type] $extension    文件名后缀
     * @return [type]               [description]
     */
    public function getObjectInfo($object, &$minObject, &$needCompress, &$state, &$extension) {
        //获取资源绝对路径
        $filePath = $this->resRootDir . $object;
        //判断资源是否存在
        if (!file_exists($filePath)) return "资源文件不存在{$filePath}";
        //版本号
        $state = $this-> _getResStateVersion($filePath);
        //文件名后缀
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        //是否要压缩
        $needCompress = true;
 
        //判断资源文件是否是以 .min.css或者.min.js结尾的
        //此类结尾一般都是已压缩过,例如jquery.min.js,就不必再压缩了
        if (str_end_with($object, '.min.'.$extension, true)) {
            //压缩后的资源存放路径,放在 /www/min/ 目录下
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state .'.'. $extension;
            $needCompress = false;
        } else if (in_array($extension, $this->compressResDir)) {
            //此处是需要压缩的文件目录
            $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
            //看看是否是忽略的路径前缀
            foreach ($this->compressResIngorePrefix as $v) {
                if (str_start_with($object, $v, true)) {
                    $needCompress = false;
                }
            }
        } else {
            $minObject = 'min/'.$object;
            $needCompress = false;
        }
        return true;
    }
 
    /**
     * 获取存放资源版本的文件
     * 它是放在一个数组里
     * $resState = array(
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *         '文件路径' => '对应的版本号',
     *     );
     * @return [type] [description]
     */
    public function getResState() {
        if (file_exists($this->resStatePath)) {
            require $this->resStatePath;
            return $resState;
        }
        return [];
    }
 
    /**
     * 计算文件的版本号,这个是根据计算文件MD5散列值得到版本号
     * 只要文件内容改变了,所计算得到的散列值就会不一样
     * 用于判断资源文件是否有改动过
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    public function _getResStateVersion($filePath) {
        return base_convert(crc32(md5_file($filePath)), 10, 36);
    }
 
    /**
     * 确保目录可写
     * @param  [type] $dir [description]
     * @return [type]      [description]
     */
    private function _ensureWritableDir($dir) {
        if (!file_exists($dir)) {
            @mkdir($dir, 0777, true);
            @chmod($dir, 0777);
        } else if (!is_writable($dir)) {
            @chmod($dir, 0777);
            if (!is_writable($dir)) {
                show_error('目录'.$dir.'不可写');
            }
        }
    }
 
    /**
     * 将压缩后的资源文件写入到/www/min/下去
     * @param  [type] $filePath    [description]
     * @param  [type] $minFilePath [description]
     * @return [type]              [description]
     */
    private function compressResFileAndSave($filePath, $minFilePath) {
        if (!file_put_contents($minFilePath, $this->compressResFile($filePath))) {
 
            //$CI->exceptions->show_exception("写入文件{$minFilePath}失败");
            show_error("写入文件{$minFilePath}失败", -1);
        }
    }
 
    /**
     * 压缩资源文件
     * @param  [type] $filePath [description]
     * @return [type]           [description]
     */
    private function compressResFile($filePath) {
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        if ($extension === 'js') {
            require_once 'JShrink/Minifier.php';
            return JShrinkMinifier::minify(file_get_contents($filePath));
        } else if ($extension ==='css') {
            $content = file_get_contents($filePath);
            $content = preg_replace('!/*[^*]**+([^/][^*]**+)*/!', '', $content);
            $content = str_replace(["rn", "r", "n"], '', $content);
            $content = preg_replace('/([{}),;:>])s+/', '$1', $content);
            $content = preg_replace('/s+([{}),;:>])/', '$1', $content);
            $content = str_replace(';}', '}', $content);
            return $content;
        } else {
            //$CI->exceptions->show_exception("不支持压缩{extension}文件[$filePath]");
            show_error("不支持压缩{extension}文件[$filePath]", -1);
 
        }
    }
 
    private function _saveResState($resState) {
        ksort($resState);
        $content = "<?phpnn$resState = array(n";
        foreach ($resState as $k => $v) {
            $content .= "t '$k' => '$v',n";
        }
        $content .= ");nn";
        file_put_contents($this->resStatePath, $content);
    }
 
}
 
点击打开

Common.php

PHP

<?php /** * 输出 HttpHead 中的财富总是。 css/js 自动决断真实路线 * @param string 文件路线 * @return string */ function res_link($file) { $file = res_path($file, $extension); if ($extension === 'css') { return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>'; } else if ($extension === 'js') { return '<script type="text/javascript" src="'.$file.'"></script>'; } else { return false; } } /** * 智能路由财富实际路线 * @param string 路径 * @param string 扩展名 * @return string 真实路线 */ function res_path($file, &$extension) { //检查是或不是留存询问字符串 list($file, $query) = explode('?', $file . '?'); //猎取增加名 $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); // $file = str_replace('\', '/', $file); //取妥善前调节器名 global $class; if ($class == null) exit('can not get class name'); $className = strtolower($class); //此处的条条框框是如此: //举例,假若不加 / ,Home调整器对应的格式是: index.css,那么 此处的路线会产生css/home/index.css //若是有 / ,调控器的格式能够是 /main.css,那么这里的路线会造成 css/main.css(公用的css类) if ('/' !== $file[0]) { //index.css => css/home/index.css $object = $extension .'/'. $className .'/' . $file; } else { // /css/main.css 可能 /main.css => css/main.css $object = substr($file, 1); //若object是 main.css ,则自动抬高 扩大名目录 => css/main.css if (0 !== strncasecmp($extension, $object, strlen($extension))) { $object = $extension . '/' . $object; } } //财富真实路线 $filepath = WEBROOT.'www/'.$object; //替换压缩版本,这部分逻辑与公事缩小逻辑对应 if (in_array($extension, array('css', 'js'))) { if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) { require_once 应用软件PATH.'libraries/Res迷你fier.php'; $resminifier = new ResMinifier(); //获取存放能源版本的文本的数组变量 $resState = $resminifier->getResState(); //总结取妥当前文件版本号 $state = $resminifier->_getResStateVersion($filepath); //剖断该版本号是还是不是留存 if (isset($resState[$object])) { //推断是或不是是.min.css或.min.js结尾 if (str_end_with($object, '.min.'.$extension)) { //将版本号拼接上去,然后拿走min的文件路线 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension; } else { //将版本号拼接上去,然后拿走min的公文路线 $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension; } //判定min的路线是还是不是留存在$resState里面 if (isset($resState[$minObject])) { $object = $minObject; $query = ''; } } } $file = RES_BASE_URL . $object; } return ($query == null) ? $file : ($file .'?'. $query); } /** * 判别 subject 是不是以 search起头, 参数钦命是或不是忽略大小写 * @param [type] $subject [description] * @param [type] $search [description] * @param boolean $ignore_case [description] * @return [type] [description] */ function str_start_with($subject, $search, $ignore_case = false) { $len2 = strlen($search); if (0 === $len2) return true; $len1 = strlen($subject); if ($len1 < $len2) return false; if ($ignore_case) { return 0 === strncmp($subject, $search, $len2); } else { return 0 === strncasecmp($subject, $search, $len2); } } /** * 判别 subject 是还是不是以 search结尾, 参数钦点是还是不是忽略大小写 * @param [type] $subject [description] * @param [type] $search [description] * @param boolean $ignore_case [description] * @return [type] [description] */ function str_end_with($subject, $search, $ignore_case = false) { $len2 = strlen($search); if (0 === $len2) return true; $len1 = strlen($subject); if ($len2 > $len1) return false; if ($ignore_case) { return 0 === strcmp(substr($subject, $len1 - $len2), $search); } else { return 0 === strcasecmp(substr($subject, $len1 - $len2), $search); } } 点击展开

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
<?php
    /**
     * 输出 HttpHead 中的资源连接。 css/js 自动判断真实路径
     * @param  string  文件路径
     * @return string      
     */
    function res_link($file) {
        $file = res_path($file, $extension);
 
        if ($extension === 'css') {
           return '<link rel="stylesheet" type="text/css" href="' . $file . '"/>';
        } else if ($extension === 'js') {
            return '<script type="text/javascript" src="'.$file.'"></script>';
        } else {
            return false;
        }
    }
 
    /**
     * 智能路由资源真实路径
     * @param  string      路径
     * @param  string      扩展名
     * @return string       真实路径
     */
    function res_path($file, &$extension) {
        //检查是否存在查询字符串
        list($file, $query) = explode('?', $file . '?');
        //取得扩展名
        $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
        //
        $file = str_replace('\', '/', $file);
        //取得当前控制器名
        global $class;
        if ($class == null) exit('can not get class name');
        $className = strtolower($class);
 
        //此处的规则是这样:
        //例如,如果不加 / ,Home控制器对应的格式是: index.css,那么 此处的路径会变成css/home/index.css
        //假如有 / ,控制器的格式可以是 /main.css,那么此处的路径会变成 css/main.css(公用的css类)
        if ('/' !== $file[0]) {
            //index.css => css/home/index.css
            $object = $extension .'/'. $className .'/' . $file;
        } else {
            // /css/main.css 或者 /main.css => css/main.css
            $object = substr($file, 1);
 
            //若object是 main.css ,则自动加上 扩展名目录 => css/main.css
            if (0 !== strncasecmp($extension, $object, strlen($extension))) {
                $object = $extension . '/' . $object;
            }
        }
        //资源真实路径
        $filepath = WEBROOT.'www/'.$object;
 
        //替换压缩版本,这部分逻辑与文件压缩逻辑对应
        if (in_array($extension, array('css', 'js'))) {
            if(!str_start_with($object, 'min/') && file_exists(APPPATH.'libraries/ResMinifier.php')) {
                require_once APPPATH.'libraries/ResMinifier.php';
                $resminifier = new ResMinifier();
                //获取存放资源版本的文件的数组变量
                $resState = $resminifier->getResState();
                //计算得到当前文件版本号
                $state = $resminifier->_getResStateVersion($filepath);
                //判断该版本号是否存在
                if (isset($resState[$object])) {
                    //判断是否是.min.css或.min.js结尾
                    if (str_end_with($object, '.min.'.$extension)) {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension) - 4) . $state . '.' . $extension;
                    } else {
                        //将版本号拼接上去,然后得到min的文件路径
                        $minObject = 'min/'.substr($object, 0, strlen($object) - strlen($extension)) . $state . '.' . $extension;
                    }
                    //判断min的路径是否存在在$resState里面
                     if (isset($resState[$minObject])) {
                        $object = $minObject;
                        $query = '';
                     }
                }
 
            }
 
            $file = RES_BASE_URL . $object;
        }
 
        return ($query == null) ? $file : ($file .'?'. $query);
 
    }
 
    /**
     * 判断 subject 是否以 search开头, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_start_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len1 < $len2) return false;
        if ($ignore_case) {
            return 0 === strncmp($subject, $search, $len2);
        } else {
            return 0 === strncasecmp($subject, $search, $len2);
        }
    }
 
    /**
     * 判断 subject 是否以 search结尾, 参数指定是否忽略大小写
     * @param  [type]  $subject     [description]
     * @param  [type]  $search      [description]
     * @param  boolean $ignore_case [description]
     * @return [type]               [description]
     */
    function str_end_with($subject, $search, $ignore_case = false) {
        $len2 = strlen($search);
        if (0 === $len2) return true;
        $len1 = strlen($subject);
        if ($len2 > $len1) return false;
        if ($ignore_case) {
            return 0 === strcmp(substr($subject, $len1 - $len2), $search);
        } else {
            return 0 === strcasecmp(substr($subject, $len1 - $len2), $search);
        }
    }
 
点击打开

$resState.php(里面包车型大巴代码是自动生成的)

XHTML

<?php $resState = array( 'css/home/index.css' => 'gwy933', 'js/echarts-all.min.js' => 'wqrf1c', 'js/home/index.js' => 's2z6f5', 'js/icon.js' => 'pgcyih', 'js/icon_home.js' => 'zhl9iu', 'js/ion.rangeSlider.min.js' => 'akq381', 'js/jquery-ui-autocomplete.js' => '8nzacv', 'js/jquery-ui.min.js' => 'i6tw8z', 'js/jquery.all.min.js' => 'd2w76v', 'js/jquery.city.js' => 'toxdrf', 'js/jquery.easydropdown.min.js' => '2ni3i0', 'js/jquery.matrix.js' => '3vrqkk', 'js/jquery.mobile.all.min.js' => 'ernu7r', 'js/jquery.qrcode.min.js' => 'yuhnsj', 'js/jquery.tinyscrollbar.min.js' => 'oakk3c', 'js/mobiscroll.custom.min.js' => 'kn8h2e', 'js/store.min.js' => 'n50jwr', 'js/swiper.animate1.0.2.min.js' => 'mm27zc', 'js/swiper.min.js' => 'jicwhh', 'min/css/home/index.6a4e83eb.css' => '', 'min/css/home/index.gwy933.css' => '', 'min/css/home/index.puzbnf.css' => '', 'min/css/home/index.thv8x7.css' => '', 'min/js/echarts-all.76025ee0.js' => '', 'min/js/echarts-all.wqrf1c.js' => '', 'min/js/home/index.65363d41.js' => '', 'min/js/home/index.s2z6f5.js' => '', 'min/js/icon.5bbd4db9.js' => '', 'min/js/icon.pgcyih.js' => '', 'min/js/icon_home.7fe74076.js' => '', 'min/js/icon_home.zhl9iu.js' => '', 'min/js/ion.rangeSlider.261d8ed1.js' => '', 'min/js/ion.rangeSlider.akq381.js' => '', 'min/js/jquery-ui-autocomplete.1f3bb62f.js' => '', 'min/js/jquery-ui-autocomplete.8nzacv.js' => '', 'min/js/jquery-ui.418e9683.js' => '', 'min/js/jquery-ui.i6tw8z.js' => '', 'min/js/jquery.all.2f248267.js' => '', 'min/js/jquery.all.d2w76v.js' => '', 'min/js/jquery.city.6b036feb.js' => '', 'min/js/jquery.city.toxdrf.js' => '', 'min/js/jquery.easydropdown.2ni3i0.js' => '', 'min/js/jquery.easydropdown.98fa138.js' => '', 'min/js/jquery.matrix.3vrqkk.js' => '', 'min/js/jquery.matrix.dfe2a44.js' => '', 'min/js/jquery.mobile.all.3539ebb7.js' => '', 'min/js/jquery.mobile.all.ernu7r.js' => '', 'min/js/jquery.qrcode.7d9738b3.js' => '', 'min/js/jquery.qrcode.yuhnsj.js' => '', 'min/js/jquery.tinyscrollbar.578e4cb8.js' => '', 'min/js/jquery.tinyscrollbar.oakk3c.js' => '', 'min/js/mobiscroll.custom.4a684f66.js' => '', 'min/js/mobiscroll.custom.kn8h2e.js' => '', 'min/js/store.536545cb.js' => '', 'min/js/store.n50jwr.js' => '', 'min/js/swiper.4650ad75.js' => '', 'min/js/swiper.animate1.0.2.517f82e8.js' => '', 'min/js/swiper.animate1.0.2.mm27zc.js' => '', 'min/js/swiper.jicwhh.js' => '', ); 点击打开

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
<?php
 
$resState = array(
     'css/home/index.css' => 'gwy933',
     'js/echarts-all.min.js' => 'wqrf1c',
     'js/home/index.js' => 's2z6f5',
     'js/icon.js' => 'pgcyih',
     'js/icon_home.js' => 'zhl9iu',
     'js/ion.rangeSlider.min.js' => 'akq381',
     'js/jquery-ui-autocomplete.js' => '8nzacv',
     'js/jquery-ui.min.js' => 'i6tw8z',
     'js/jquery.all.min.js' => 'd2w76v',
     'js/jquery.city.js' => 'toxdrf',
     'js/jquery.easydropdown.min.js' => '2ni3i0',
     'js/jquery.matrix.js' => '3vrqkk',
     'js/jquery.mobile.all.min.js' => 'ernu7r',
     'js/jquery.qrcode.min.js' => 'yuhnsj',
     'js/jquery.tinyscrollbar.min.js' => 'oakk3c',
     'js/mobiscroll.custom.min.js' => 'kn8h2e',
     'js/store.min.js' => 'n50jwr',
     'js/swiper.animate1.0.2.min.js' => 'mm27zc',
     'js/swiper.min.js' => 'jicwhh',
     'min/css/home/index.6a4e83eb.css' => '',
     'min/css/home/index.gwy933.css' => '',
     'min/css/home/index.puzbnf.css' => '',
     'min/css/home/index.thv8x7.css' => '',
     'min/js/echarts-all.76025ee0.js' => '',
     'min/js/echarts-all.wqrf1c.js' => '',
     'min/js/home/index.65363d41.js' => '',
     'min/js/home/index.s2z6f5.js' => '',
     'min/js/icon.5bbd4db9.js' => '',
     'min/js/icon.pgcyih.js' => '',
     'min/js/icon_home.7fe74076.js' => '',
     'min/js/icon_home.zhl9iu.js' => '',
     'min/js/ion.rangeSlider.261d8ed1.js' => '',
     'min/js/ion.rangeSlider.akq381.js' => '',
     'min/js/jquery-ui-autocomplete.1f3bb62f.js' => '',
     'min/js/jquery-ui-autocomplete.8nzacv.js' => '',
     'min/js/jquery-ui.418e9683.js' => '',
     'min/js/jquery-ui.i6tw8z.js' => '',
     'min/js/jquery.all.2f248267.js' => '',
     'min/js/jquery.all.d2w76v.js' => '',
     'min/js/jquery.city.6b036feb.js' => '',
     'min/js/jquery.city.toxdrf.js' => '',
     'min/js/jquery.easydropdown.2ni3i0.js' => '',
     'min/js/jquery.easydropdown.98fa138.js' => '',
     'min/js/jquery.matrix.3vrqkk.js' => '',
     'min/js/jquery.matrix.dfe2a44.js' => '',
     'min/js/jquery.mobile.all.3539ebb7.js' => '',
     'min/js/jquery.mobile.all.ernu7r.js' => '',
     'min/js/jquery.qrcode.7d9738b3.js' => '',
     'min/js/jquery.qrcode.yuhnsj.js' => '',
     'min/js/jquery.tinyscrollbar.578e4cb8.js' => '',
     'min/js/jquery.tinyscrollbar.oakk3c.js' => '',
     'min/js/mobiscroll.custom.4a684f66.js' => '',
     'min/js/mobiscroll.custom.kn8h2e.js' => '',
     'min/js/store.536545cb.js' => '',
     'min/js/store.n50jwr.js' => '',
     'min/js/swiper.4650ad75.js' => '',
     'min/js/swiper.animate1.0.2.517f82e8.js' => '',
     'min/js/swiper.animate1.0.2.mm27zc.js' => '',
     'min/js/swiper.jicwhh.js' => '',
);
 
点击打开

 

别的附上JShrink这一个PHP类的链接给大家下载 

假定咱们依旧认为相当不足OK的话,作者一向将以此实验项目打包供我们下载下来学习和询问:

四、结语

末尾小编来分享大家线上项目标具体贯彻方案:

我们的品类分线上景况、开采条件和测量试验景况,在支付和测验情状中,大家每叁回访谈都会调用压缩文件的接口,然后再对转移的财富文件的深浅是要做剖断的,要是缩减后文件过小,将须求将该财富文件的代码合併到别的能源文件里去,以此收缩不须要的HTTP央浼(因为文件太小,财富的下载时间远远低于HTTP诉求响应所费用的时刻);另一个是图片的管理,全部图片都要通过压缩技能通过(比方在:  那个网址去降低图片),在PC端,固然是小Logo的话,使用图片合併的不二法门举办优化,详细情形可参照自个儿的那篇博文:http://www.cnblogs.com/it-cen/p/4618954.html    而在wap端的图形管理利用的是base64编码格局来管理图片,实际情况能够参见自己的那篇博文:  ,当页面输出时,会采纳redis来缓存页面(为何用内部存款和储蓄器来缓存并不是行使页面缓存,这一个未来再享受给大家)。借使是线上情状,每发一回版本,才会调用一下财富文件缩短那么些接口,并且线上的静态能源(css、js、图片)是贮存在在Ali云的OSS里的,与大家的应用服务器是分别的。那是我们线上项指标一有的优消除决方案,当然了,还会有越来越多优化技能,我会在后来各样总计和享受出去,方便大家共同学习和互换。

本次博文就享受到此,谢谢观察此博文的意中大家。

1 赞 1 收藏 评论

云顶娱乐网站 9

总结

原型承继和类承接是两种不一致的体味格局,原型承接在对象不是累累的简短利用模型里比类继承更灵敏方便。可是JavaScript的原型承接在语法上有一个组织器额向外调拨运输用的标题,大家只要经过 createObjWithoutConstructor 来延迟构造器的调用,就能够消除这么些难点。

3 赞 8 收藏 1 评论

云顶娱乐网站 10

HTTP Keep-Alive模式

2015/12/01 · HTML5 · 1 评论 · HTTP

原来的文章出处: 吴秦   

传说爆发在三月份的叁回面试经历中,本来作者不想讲出来丢人显眼,不过为了警醒自个儿和劝诫子孙,作者说了算写成博文发出来。因为在面试进程中,笔者讲在二零一零年写过QQ农场入手,在那中间深刻学习了HTTP合同,而且在二〇〇九-05-18写了博文:HTTP协议及其POST与GET操作差距& C#中怎样运用POST、GET等。面试官说既然自身熟谙HTTP公约,就问“当HTTP选用keepalive情势,当客商端向服务器发生乞请之后,顾客端怎么样剖断服务器的数码现已发出完毕?”

说真话,那时自己懵了,一向尚未青眼过keepalive格局。笔者只掌握:HTTP协议中型地铁户端发送三个小央求,服务器响应以所企盼的音信(比方叁个html文件或一副gif图像)。服务器平时在发送回所央浼的数目现在就停业连接。那样客商端读数据时会重返EOF(-1),就精通多少现已吸收接纳完全了。自身就这么被面试官判了极刑!!!说作者完全停留在外界,未有深入(那时的确相当受打击,一向自感到技巧还可以!)。小编立刻真正很想找各样借口:

  • 事先未有动用HTTP的keepalive情势,所以并未有尖锐
  • 悠长没有用HTTP公约,细节忘了
  • 实习的事物跟HTTP协议未有关联,用得少了就忘了
  • 。。。。。。

以为种种解释都以那么苍白无力!作者再度感叹书到需要的时候才感到少,也感慨一人的年月是何其的星星(曾一度想形成三个IT专门的职业全才),根本未有精力面面俱圆,并且当未有真的使用二个事物的时候,往往会忽略掉非常多细节。朋友要是您也答不上去,请认真审视下文,不要怀着浮躁了的心,说不定下一次就有人问您那个标题。

HTML5之Canvas

Canvas是Html5中用于绘图的要素,它能够绘制各类图片,举个例子圆柱形,多边形,圆形等等。假设想要领悟Canvas的运用能够参见:

 

//如果想要使用canvas,首先需求得到上下文对象: ctx = document.getElementById('canvas').getContext('2d'); //然后使用那个ctx绘制图形

1
2
3
//如果想要使用canvas,首先需要获得上下文对象:
ctx = document.getElementById('canvas').getContext('2d');
//然后使用这个ctx绘制图形

在cavas各种绘制都是单身的操作。比方下图的多个绘制图形,第一个会以掩没的花样绘制,因而绘图图形的相继就展现十一分尤为重要了。

云顶娱乐网站 11

页面渲染

在那或多或少上,经过职业和汗水得出这个细节,小编确信自身的 Google PageSpeed Insights 的分数将是90s。

云顶娱乐网站 12

在活动平台PSI分数为73/100,而桌面平台上好一点在88/100。它提议笔者“解决render-blocking的JavaScript和CSS”。

render-blocking文件扩展了浏览器展现内容的光阴,因为那些文件必要先下载并拍卖。七个render-blocking文件必要浏览器接纳三个线程去获得和管理它们,等待时间更是扩张。

云顶娱乐网站 13

优化JavaScript、CSS和web字体的传输,能够升高页面包车型地铁“第临时间渲染。将这一个时间降到最低,精通“关键的渲染路线”很关键,它呈报了在当页面包车型大巴率先个字节被吸收接纳,与页面第三次渲染成像素之间时有发生了哪些。

WebPagetest 是用来赞助你计划网址和页面品质最佳的可视化学工业具。

云顶娱乐网站 14

About页面在渲染优化前的WebPagetest结果

当最小化第三遍渲染时间时,大家更加多的关注以全力以赴快的进程渲染内容,然后允许额外的“东西”在管理进度中国和日本渐渲染。

类继承

几年过后,那时的幼童长大了,随着她的文化结构不断丰富,她认识世界的措施也发生了有的转移,她学会了太多的动物,有喵喵叫的猫,百兽之王克鲁格狮,温婉的山林之王苏门答腊虎,还会有豺狼、大象之类。

此刻,单纯的相似性的认知形式已经少之又少被运用在这么丰硕的学问内容里,越发严酷的体味格局——分类,最初被更频繁利用。

云顶娱乐网站 15

那会儿当年的小孩会说,猫和狗都以动物,假设她碰巧学习的是明媒正娶的生物学,她可能还或者会说猫和狗都以脊索门哺乳纲,于是,相似性被“类”这一种更加高品位的肤浅表明替代,我们用JavaScript来说述:

JavaScript

class Animal{ eat(){} say(){} climb(){} ... } class Cat extends Animal{ say(){return "喵"} } class Dog extends Animal{ say(){return "汪"} }

1
2
3
4
5
6
7
8
9
10
11
12
class Animal{
    eat(){}
    say(){}
    climb(){}
    ...
}
class Cat extends Animal{
    say(){return "喵"}
}
class Dog extends Animal{
    say(){return "汪"}
}

5、HTTP头字段总计

最终笔者计算下HTTP协议的头顶字段。

  • 1、 Accept:告诉WEB服务器自身接受什么介质类型,*/* 表示其他项目,type/* 表示该品种下的富有子类型,type/sub-type。
  • 2、 Accept-Charset: 浏览器注脚自身收到的字符集
    Accept-Encoding: 浏览器表明自身接受的编码方法,经常钦定压缩方法,是或不是扶助压缩,援助什么压缩方法(gzip,deflate)
    Accept-Language:浏览器注明本人吸取的语言
    言语跟字符集的界别:闽南语是语言,粤语有多样字符集,举例big5,gb2312,gbk等等。
  • 3、 Accept-Ranges:WEB服务器声明自身是或不是接受获取其有个别实体的一有个别(比如文件的一有个别)的伏乞。bytes:表示接受,none:表示不收受。
  • 4、 Age:今世理服务器用自身缓存的实体去响应央求时,用该尾部表明该实体从发生到现行反革命透过多久了。
  • 5、 Authorization:当顾客端接收到来自WEB服务器的 WWW-Authenticate 响应时,用该底部来应对本人的身份验证新闻给WEB服务器。
  • 6、 Cache-Control:乞求:no-cache(不要缓存的实业,须要以后从WEB服务器去取)
    max-age:(只接受 Age 值小于 max-age 值,况且未有过期的靶子)
    max-stale:(基本上能用过去的靶子,不过过期时间必得低于 max-stale 值)
    min-fresh:(接受其独具匠心生命期大于其眼下 Age 跟 min-fresh 值之和的缓存对象)
    一呼百应:public(能够用 Cached 内容回应任何客商)
    private(只能用缓存内容回答先前恳请该内容的拾叁分客商)
    no-cache(能够缓存,不过独有在跟WEB服务器验证了其立见成效后,本领回去给客户端)
    max-age:(本响应包涵的对象的晚点时间)
    ALL: no-store(不允许缓存)
  • 7、 Connection:须求:close(告诉WEB服务器只怕代理服务器,在成功这一次诉求的响应后,断开连接,不要等待此次连接的后续央浼了)。
    keepalive(告诉WEB服务器也许代理服务器,在成就本次央浼的响应后,保持一连,等待这一次连接的一连诉求)。
    响应:close(连接已经关门)。
    keepalive(连接保持着,在等待此次连接的继续伏乞)。
    Keep-Alive:借使浏览器央浼保持再而三,则该底部注脚希望 WEB 服务器保持三番五次多久(秒)。举例:Keep-Alive:300
  • 8、 Content-Encoding:WEB服务器表明自身行使了什么样压缩方法(gzip,deflate)压缩响应中的对象。比方:Content-Encoding:gzip
  • 9、Content-Language:WEB 服务器告诉浏览器本人响应的靶子的语言。
  • 10、Content-Length: WEB 服务器告诉浏览器自个儿响应的靶子的长度。举例:Content-Length: 26012
  • 11、Content-Range: WEB 服务器证明该响应饱含的部分目的为全部对象的哪些部分。比如:Content-Range: bytes 21010-4702二分之一7022
  • 12、Content-Type: WEB 服务器告诉浏览器本人响应的对象的种类。比如:Content-Type:application/xml
  • 13、ETag:正是多个对象(比如U法拉利488L)的标识值,就二个目的来说,譬如一个html 文件,即便被涂改了,其 Etag 也会别修改,所以ETag 的效果跟 Last-Modified 的效果大约,主要供 WEB 服务器判定多个对象是或不是退换了。举例前三回呼吁某些 html 文件时,得到了其 ETag,当此次又必要这一个文件时,浏览器就可以把原先收获的 ETag 值发送给WEB 服务器,然后 WEB 服务器会把那个 ETag 跟该公文的当下 ETag 实行对照,然后就明白那么些文件有没有退换了。
  • 14、 Expired:WEB服务器注明该实体将在哪一天过期,对于逾期了的靶子,唯有在跟WEB服务器验证了其卓有成效后,能力用来响应客户央求。是 HTTP/1.0 的头顶。举个例子:Expires:Sat, 23 May 二〇〇八 10:02:12 放线菌壮观素T
  • 15、 Host:客商端钦命自个儿想探问的WEB服务器的域名/IP 地址和端口号。举个例子:Host:rss.sina.com.cn
  • 16、 If-Match:如若目的的 ETag 未有改换,其实也就意味著对象未有改换,才实行央求的动作。
  • 17、 If-None-Match:如若目的的 ETag 改动了,其实也就意味著对象也更换了,才施行央浼的动作。
  • 18、 If-Modified-Since:假使乞求的对象在该底部钦命的岁月现在修改了,才施行央求的动作(举例再次回到对象),不然重返代码304,告诉浏览器该指标未有改造。比如:If-Modified-Since:Thu, 10 Apr 贰零壹零 09:14:42 达托霉素T
  • 19、 If-Unmodified-Since:要是央求的靶子在该头部钦命的大运以往没修改过,才实行央浼的动作(比如重返对象)。
  • 20、 If-Range:浏览器告诉 WEB 服务器,假若小编伸手的靶子未有改观,就把本身远远不够的一部分给小编,如果目的改换了,就把全部对象给本身。浏览器通过发送恳求对象的 ETag 只怕 自个儿所知道的末尾修改时间给 WEB 服务器,让其推断目的是不是变动了。总是跟 Range 尾部一齐行使。
  • 21、 Last-Modified:WEB 服务器以为对象的末段修改时间,比如文件的末尾修改时间,动态页面包车型大巴末梢发生时间等等。比方:Last-Modified:Tue, 06 May 二零一零 02:42:43 GMT
  • 22、 Location:WEB 服务器告诉浏览器,试图访谈的指标已经被移到其余地点了,到该底部内定的地点去取。举例:Location:
  • 23、 Pramga:首要选取 Pramga: no-cache,相当于 Cache-Control: no-cache。比方:Pragma:no-cache
  • 24、 Proxy-Authenticate: 代理服务器响应浏览器,须要其提供代理身份验证消息。Proxy-Authorization:浏览器响应代理服务器的身份验证须要,提供温馨的身份消息。
  • 25、 Range:浏览器(譬喻 Flashget 十二线程下载时)告诉 WEB 服务器本人想取对象的哪部分。比如:Range: bytes=1173546-
  • 26、 Referer:浏览器向 WEB 服务器表明本身是从哪个 网页/U中华VL 获得/点击 当前恳请中的网站/UENCOREL。比方:Referer:
  • 27、 Server: WEB 服务器注脚本人是怎么样软件及版本等音信。比如:Server:Apache/2.0.61 (Unix)
  • 28、 User-Agent: 浏览器评释本人的身份(是哪一种浏览器)。举例:User-Agent:Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.14) Gecko/20100404 Firefox/2、0、0、14
  • 29、 Transfer-Encoding: WEB 服务器表明本人对本响应音讯体(不是新闻体里面包车型地铁指标)作了怎么着的编码,比方是不是分块(chunked)。比方:Transfer-Encoding: chunked
  • 30、 Vary: WEB服务器用该尾部的剧情告诉 Cache 服务器,在什么条件下才干用本响应所重返的对象响应后续的呼吁。假诺源WEB服务器在接受第贰个央浼音讯时,其响应音信的头顶为:Content-Encoding: gzip; Vary: Content-Encoding那么 Cache 服务器会深入分析后续央求信息的头顶,检查其 Accept-Encoding,是还是不是跟在此以前响应的 Vary 头部值一致,正是还是不是选取同一的内容编码方法,那样就能够防止 Cache 服务器用自身 Cache 里面压缩后的实业响应给不享有解压技巧的浏览器。举例:Vary:Accept-Encoding
  • 31、 Via: 列出从顾客端到 OCS 或许相反方向的响应经过了什么代理服务器,他们用什么样左券(和本子)发送的伸手。当客户端央求到达第多少个代理服务器时,该服务器会在和睦产生的乞求里面增多Via 尾部,并填上团结的有关音信,当下三个代理服务器收到第二个代理服务器的呼吁时,会在友好发生的伸手里面复制前贰个代理服务器的伸手的Via 底部,并把团结的相关音讯加到后边,就那样类推,当 OCS 收到最终二个代理服务器的央求时,检查 Via 尾部,就知晓该诉求所经过的路由。比方:Via:1.0 236.D0707195.sina.com.cn:80 (squid/2.6.STABLE13)

===============================================================================
HTTP 央浼音讯尾部实例:
Host:rss.sina.com.cn
User-Agent:Mozilla/5、0 (Windows; U; Windows NT 5、1; zh-CN; rv:1、8、1、14) Gecko/20080404 Firefox/2、0、0、14
Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0、9,text/plain;q=0、8,image/png,*/*;q=0、5
Accept-Language:zh-cn,zh;q=0、5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0、7,*;q=0、7
Keep-Alive:300
Connection:keep-alive
Cookie:userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW <– Cookie
If-Modified-Since:Sun, 01 Jun 2008 12:05:30 GMT
Cache-Control:max-age=0
HTTP 响应音信底部实例:
Status:OK – 200 <– 响应状态码,表示 web 服务器管理的结果。
Date:Sun, 01 Jun 2008 12:35:47 GMT
Server:Apache/2、0、61 (Unix)
Last-Modified:Sun, 01 Jun 2008 12:35:30 GMT
Accept-Ranges:bytes
Content-Length:18616
Cache-Control:max-age=120
Expires:Sun, 01 Jun 2008 12:37:47 GMT
Content-Type:application/xml
Age:2
X-Cache:HIT from 236-41、D0707一九五三、sina、com、cn <– 反向代理服务器使用的 HTTP 尾部
Via:1.0 236-41.D07071951.sina.com.cn:80 (squid/2.6.STABLE13)
Connection:close

本节摘自:

1 赞 3 收藏 1 评论

云顶娱乐网站 16

分数计算

分数的企图与碰撞检验类似,设置一个按钮,当管敬仲重新出现时,设置为true。当分值加1时,设置为false。

鸟类的最左侧的x坐标借使凌驾了管敬仲的x+width,就认为成功通过。

if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){ score += 1; isScore = false; if(score>0 && score%10 === 0){ velocity++; } }

1
2
3
4
5
6
7
if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){
                score += 1;
                isScore = false;
                if(score>0 && score%10 === 0){
                    velocity++;
                }
            }

通过后,分值加1,速度+1。

CSS和JavaScript

压缩样式表和JavaScript文件能够分明滑坡文件大小,笔者仅在减小上就从三个文书上节省了四分之一的上空。

压缩前 压缩后 节省比例
CSS 135KB 104KB 23.0%
JS 16KB 7KB 56.3%

我使用 BEM (代码、元素、修饰符) 方法论编写CSS,这将形成冗长的类名。重构作者的部分代码变得更简便易行(“navigation”为 “nav”, “introduction” 为 “intro”),那让自个儿节约了部分空间,但和本身盼望的早先时期压缩比较并不是那么明显。

冗长的类 精简后 节省比例
104KB 97KB 6.7%

笔者也重新评估了使用jQuery的要求性。对于滑坡的135KB的JavaScript,大概96KB是jQuery库——71%之多!这里并不曾过多亟待借助于jQuery,所以小编花时间重构了代码。作者通过剥离jQuery和在Vanilla重写它,去除了122KB,最后减掉后的文件大小减少到13KB。

jQuery Vanilla JS 节省比例
135KB 13KB 122KB (90%)

从那时候起,笔者灵机一动去掉越多空间(压缩后7KB),最终脚本在回退和gzipped后唯有0.365KB。

本文由云顶娱乐集团发布于云顶娱乐集团,转载请注明出处:重型网站优化工夫【云顶娱乐网站】,Canvas前端

关键词: