mirror of
https://github.com/mrclay/minify.git
synced 2025-01-29 19:27:45 +01:00
Added/improved ab tests. Prepended "minify_" to cache filenames.
This commit is contained in:
parent
8cde22b934
commit
4c85da1fb3
@ -196,7 +196,7 @@ class Minify {
|
||||
// the goal is to use only the cache methods to sniff the length and
|
||||
// output the content, as they do not require ever loading the file into
|
||||
// memory.
|
||||
$cacheId = self::_getCacheId();
|
||||
$cacheId = 'minify_' . self::_getCacheId();
|
||||
$encodingExtension = self::$_options['encodeMethod']
|
||||
? ('deflate' === self::$_options['encodeMethod']
|
||||
? '.zd'
|
||||
|
10
web/ab_tests/README.txt
Normal file
10
web/ab_tests/README.txt
Normal file
@ -0,0 +1,10 @@
|
||||
This is a little AB testing setup for Windows. Before committing any non-trivial
|
||||
change, these tests should be run so "results_summary.txt" will be an up-to-date
|
||||
document of each revision's performance.
|
||||
|
||||
Before testing make sure all cache locations are correct.
|
||||
|
||||
Double-click "test_all.bat" to run the tests. At the end, "results_summary.txt"
|
||||
will be opened in notepad. For more details see "results.txt".
|
||||
|
||||
Delete "results.txt" before committing. We don't need this much info in svn.
|
3
web/ab_tests/_delimiter
Normal file
3
web/ab_tests/_delimiter
Normal file
@ -0,0 +1,3 @@
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -1,4 +0,0 @@
|
||||
C:\xampp\apache\bin\ab -c 100 -n 2000 -H "Accept-Encoding: deflate, gzip" http://mc.dev/_3rd_party/minify/web/ab_tests/ideal_php/before.php > results_ideal_php.txt
|
||||
C:\xampp\apache\bin\ab -c 100 -n 2000 -H "Accept-Encoding: deflate, gzip" http://mc.dev/_3rd_party/minify/web/ab_tests/minify/before.js.php > results_minify.txt
|
||||
C:\xampp\apache\bin\ab -c 100 -n 2000 -H "Accept-Encoding: deflate, gzip" http://mc.dev/_3rd_party/minify/web/ab_tests/mod_deflate/before.js > results_deflate.txt
|
||||
C:\xampp\apache\bin\ab -c 100 -n 2000 -H "Accept-Encoding: deflate, gzip" http://mc.dev/_3rd_party/minify/web/ab_tests/type-map/before.js.var > results_type-map.txt
|
15
web/ab_tests/minify/test_Version1.php
Normal file
15
web/ab_tests/minify/test_Version1.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
ini_set('include_path',
|
||||
dirname(__FILE__) . '/../../../lib'
|
||||
. PATH_SEPARATOR . ini_get('include_path')
|
||||
);
|
||||
|
||||
define('MINIFY_BASE_DIR', realpath(
|
||||
dirname(__FILE__) . '/../minify'
|
||||
));
|
||||
define('MINIFY_CACHE_DIR', 'C:/xampp/tmp');
|
||||
|
||||
require 'Minify.php';
|
||||
|
||||
Minify::serve('Version1');
|
204
web/ab_tests/results.txt
Normal file
204
web/ab_tests/results.txt
Normal file
@ -0,0 +1,204 @@
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking localhost (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.8
|
||||
Server Hostname: localhost
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /minify/web/ab_tests/ideal_php/before.php
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 3.234395 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32794000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 618.35 [#/sec] (mean)
|
||||
Time per request: 161.720 [ms] (mean)
|
||||
Time per request: 1.617 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 9901.39 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min avg max
|
||||
Connect: 0 0 15
|
||||
Processing: 46 155 656
|
||||
Total: 46 155 671
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking localhost (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.8
|
||||
Server Hostname: localhost
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /minify/web/ab_tests/v1.0/minify.php?files=before.js
|
||||
Document Length: 54159 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 3.968775 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 108996000 bytes
|
||||
HTML transferred: 108318000 bytes
|
||||
Requests per second: 503.93 [#/sec] (mean)
|
||||
Time per request: 198.439 [ms] (mean)
|
||||
Time per request: 1.984 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 26819.61 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min avg max
|
||||
Connect: 0 0 15
|
||||
Processing: 78 191 297
|
||||
Total: 78 191 312
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking localhost (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.8
|
||||
Server Hostname: localhost
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /minify/web/ab_tests/minify/test_Files.php
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 4.875031 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32764000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 410.25 [#/sec] (mean)
|
||||
Time per request: 243.752 [ms] (mean)
|
||||
Time per request: 2.438 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 6563.24 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min avg max
|
||||
Connect: 0 0 15
|
||||
Processing: 46 236 328
|
||||
Total: 46 236 343
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking localhost (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.8
|
||||
Server Hostname: localhost
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /minify/web/ab_tests/minify/test_Version1.php?files=before.js
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 5.609411 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32872000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 356.54 [#/sec] (mean)
|
||||
Time per request: 280.471 [ms] (mean)
|
||||
Time per request: 2.805 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 5722.70 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min avg max
|
||||
Connect: 0 0 15
|
||||
Processing: 46 272 891
|
||||
Total: 46 272 906
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking localhost (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.8
|
||||
Server Hostname: localhost
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /minify/web/ab_tests/mod_deflate/before.js
|
||||
Document Length: 16053 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 11.328198 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32994000 bytes
|
||||
HTML transferred: 32106000 bytes
|
||||
Requests per second: 176.55 [#/sec] (mean)
|
||||
Time per request: 566.410 [ms] (mean)
|
||||
Time per request: 5.664 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 2844.23 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min avg max
|
||||
Connect: 0 0 93
|
||||
Processing: 62 547 1266
|
||||
Total: 62 547 1359
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking localhost (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.8
|
||||
Server Hostname: localhost
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /minify/web/ab_tests/type-map/before.js.var
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 4.500029 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32990000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 444.44 [#/sec] (mean)
|
||||
Time per request: 225.001 [ms] (mean)
|
||||
Time per request: 2.250 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 7159.06 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min avg max
|
||||
Connect: 0 0 15
|
||||
Processing: 62 216 297
|
||||
Total: 62 216 312
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
@ -1,43 +0,0 @@
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking mc.dev (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.4
|
||||
Server Hostname: mc.dev
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /_3rd_party/minify/web/ab_tests/mod_deflate/before.js
|
||||
Document Length: 16053 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 10.734375 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 33048000 bytes
|
||||
HTML transferred: 32106000 bytes
|
||||
Requests per second: 186.32 [#/sec] (mean)
|
||||
Time per request: 536.719 [ms] (mean)
|
||||
Time per request: 5.367 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 3006.51 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min mean[+/-sd] median max
|
||||
Connect: 0 1 9.5 0 187
|
||||
Processing: 15 531 179.0 531 1000
|
||||
Waiting: 0 412 191.3 453 937
|
||||
Total: 15 533 179.3 546 1000
|
||||
|
||||
Percentage of the requests served within a certain time (ms)
|
||||
50% 546
|
||||
66% 546
|
||||
75% 593
|
||||
80% 640
|
||||
90% 750
|
||||
95% 875
|
||||
98% 953
|
||||
99% 1000
|
||||
100% 1000 (longest request)
|
@ -1,43 +0,0 @@
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking mc.dev (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.4
|
||||
Server Hostname: mc.dev
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /_3rd_party/minify/web/ab_tests/ideal_php/before.php
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 4.437500 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32848000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 450.70 [#/sec] (mean)
|
||||
Time per request: 221.875 [ms] (mean)
|
||||
Time per request: 2.219 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 7228.85 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min mean[+/-sd] median max
|
||||
Connect: 0 0 2.6 0 15
|
||||
Processing: 31 214 37.5 218 359
|
||||
Waiting: 31 209 32.7 218 281
|
||||
Total: 31 215 37.5 218 359
|
||||
|
||||
Percentage of the requests served within a certain time (ms)
|
||||
50% 218
|
||||
66% 218
|
||||
75% 234
|
||||
80% 234
|
||||
90% 234
|
||||
95% 250
|
||||
98% 296
|
||||
99% 343
|
||||
100% 359 (longest request)
|
@ -1,43 +0,0 @@
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking mc.dev (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.4
|
||||
Server Hostname: mc.dev
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /_3rd_party/minify/web/ab_tests/minify/before.js.php
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 17.312500 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32736000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 115.52 [#/sec] (mean)
|
||||
Time per request: 865.625 [ms] (mean)
|
||||
Time per request: 8.656 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 1846.53 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min mean[+/-sd] median max
|
||||
Connect: 0 0 2.1 0 15
|
||||
Processing: 125 853 150.1 844 1296
|
||||
Waiting: 125 852 150.1 843 1281
|
||||
Total: 125 854 150.1 859 1296
|
||||
|
||||
Percentage of the requests served within a certain time (ms)
|
||||
50% 859
|
||||
66% 906
|
||||
75% 953
|
||||
80% 984
|
||||
90% 1046
|
||||
95% 1109
|
||||
98% 1156
|
||||
99% 1187
|
||||
100% 1296 (longest request)
|
@ -1,43 +0,0 @@
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking mc.dev (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.4
|
||||
Server Hostname: mc.dev
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /_3rd_party/minify/web/ab_tests/minify/before.js.php
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 6.468750 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 32818000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 309.18 [#/sec] (mean)
|
||||
Time per request: 323.438 [ms] (mean)
|
||||
Time per request: 3.234 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 4954.28 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min mean[+/-sd] median max
|
||||
Connect: 0 0 2.5 0 31
|
||||
Processing: 31 313 74.8 312 828
|
||||
Waiting: 31 309 70.0 312 796
|
||||
Total: 31 314 74.7 312 828
|
||||
|
||||
Percentage of the requests served within a certain time (ms)
|
||||
50% 312
|
||||
66% 312
|
||||
75% 328
|
||||
80% 328
|
||||
90% 328
|
||||
95% 343
|
||||
98% 578
|
||||
99% 640
|
||||
100% 828 (longest request)
|
@ -1,43 +0,0 @@
|
||||
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
|
||||
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
|
||||
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
|
||||
|
||||
Benchmarking mc.dev (be patient)
|
||||
|
||||
|
||||
Server Software: Apache/2.2.4
|
||||
Server Hostname: mc.dev
|
||||
Server Port: 80
|
||||
|
||||
Document Path: /_3rd_party/minify/web/ab_tests/type-map/before.js.var
|
||||
Document Length: 15993 bytes
|
||||
|
||||
Concurrency Level: 100
|
||||
Time taken for tests: 4.171875 seconds
|
||||
Complete requests: 2000
|
||||
Failed requests: 0
|
||||
Write errors: 0
|
||||
Total transferred: 33044000 bytes
|
||||
HTML transferred: 31986000 bytes
|
||||
Requests per second: 479.40 [#/sec] (mean)
|
||||
Time per request: 208.594 [ms] (mean)
|
||||
Time per request: 2.086 [ms] (mean, across all concurrent requests)
|
||||
Transfer rate: 7734.89 [Kbytes/sec] received
|
||||
|
||||
Connection Times (ms)
|
||||
min mean[+/-sd] median max
|
||||
Connect: 0 0 2.9 0 31
|
||||
Processing: 31 202 53.4 203 453
|
||||
Waiting: 15 195 52.1 203 453
|
||||
Total: 31 202 53.4 203 453
|
||||
|
||||
Percentage of the requests served within a certain time (ms)
|
||||
50% 203
|
||||
66% 218
|
||||
75% 218
|
||||
80% 218
|
||||
90% 250
|
||||
95% 312
|
||||
98% 343
|
||||
99% 343
|
||||
100% 453 (longest request)
|
33
web/ab_tests/test_all.bat
Normal file
33
web/ab_tests/test_all.bat
Normal file
@ -0,0 +1,33 @@
|
||||
@SET PATH=%PATH%;C:\xampp\apache\bin
|
||||
@SET ABCALL=ab -d -S -c 100 -n 2000 -H "Accept-Encoding: deflate, gzip" http://localhost
|
||||
@SET DELIM=TYPE _delimiter
|
||||
|
||||
DEL results.txt
|
||||
|
||||
@REM baseline PHP
|
||||
%ABCALL%/minify/web/ab_tests/ideal_php/before.php >> results.txt
|
||||
%DELIM% >> results.txt
|
||||
|
||||
@REM 1.0 release
|
||||
%ABCALL%/minify/web/ab_tests/v1.0/minify.php?files=before.js >> results.txt
|
||||
%DELIM% >> results.txt
|
||||
|
||||
@REM Files controller
|
||||
%ABCALL%/minify/web/ab_tests/minify/test_Files.php >> results.txt
|
||||
%DELIM% >> results.txt
|
||||
|
||||
@REM Version1 controller
|
||||
%ABCALL%/minify/web/ab_tests/minify/test_Version1.php?files=before.js >> results.txt
|
||||
%DELIM% >> results.txt
|
||||
|
||||
@REM mod_deflate
|
||||
%ABCALL%/minify/web/ab_tests/mod_deflate/before.js >> results.txt
|
||||
%DELIM% >> results.txt
|
||||
|
||||
@REM type-map
|
||||
%ABCALL%/minify/web/ab_tests/type-map/before.js.var >> results.txt
|
||||
%DELIM% >> results.txt
|
||||
|
||||
FINDSTR "Path: Length: Requests --" results.txt > results_summary.txt
|
||||
|
||||
notepad results_summary.txt
|
499
web/ab_tests/v1.0/minify.php
Normal file
499
web/ab_tests/v1.0/minify.php
Normal file
@ -0,0 +1,499 @@
|
||||
<?php
|
||||
// ab test of Minify 1.0, mostly to see how fast it can serve server-cached files.
|
||||
|
||||
define('MINIFY_BASE_DIR', realpath(
|
||||
dirname(__FILE__) . '/../minify'
|
||||
));
|
||||
define('MINIFY_CACHE_DIR', 'C:/xampp/tmp');
|
||||
|
||||
/**
|
||||
* Minify - Combines, minifies, and caches JavaScript and CSS files on demand.
|
||||
*
|
||||
* See http://code.google.com/p/minify/ for usage instructions.
|
||||
*
|
||||
* This library was inspired by jscsscomp by Maxim Martynyuk <flashkot@mail.ru>
|
||||
* and by the article "Supercharged JavaScript" by Patrick Hunlock
|
||||
* <wb@hunlock.com>.
|
||||
*
|
||||
* JSMin was originally written by Douglas Crockford <douglas@crockford.com>.
|
||||
*
|
||||
* Requires PHP 5.2.1+.
|
||||
*
|
||||
* @package Minify
|
||||
* @author Ryan Grove <ryan@wonko.com>
|
||||
* @copyright 2007 Ryan Grove. All rights reserved.
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version 1.1.0 (?)
|
||||
* @link http://code.google.com/p/minify/
|
||||
*/
|
||||
|
||||
if (!defined('MINIFY_BASE_DIR')) {
|
||||
/**
|
||||
* Base path from which all relative file paths should be resolved. By default
|
||||
* this is set to the document root.
|
||||
*/
|
||||
define('MINIFY_BASE_DIR', realpath($_SERVER['DOCUMENT_ROOT']));
|
||||
}
|
||||
|
||||
if (!defined('MINIFY_CACHE_DIR')) {
|
||||
/** Directory where compressed files will be cached. */
|
||||
define('MINIFY_CACHE_DIR', sys_get_temp_dir());
|
||||
}
|
||||
|
||||
if (!defined('MINIFY_ENCODING')) {
|
||||
/** Character set to use when outputting the minified files. */
|
||||
define('MINIFY_ENCODING', 'utf-8');
|
||||
}
|
||||
|
||||
if (!defined('MINIFY_MAX_FILES')) {
|
||||
/** Maximum number of files to combine in one request. */
|
||||
define('MINIFY_MAX_FILES', 16);
|
||||
}
|
||||
|
||||
if (!defined('MINIFY_REWRITE_CSS_URLS')) {
|
||||
/**
|
||||
* Whether or not Minify should attempt to rewrite relative URLs used in CSS
|
||||
* files so that they continue to point to the correct location after the file
|
||||
* is combined and minified.
|
||||
*
|
||||
* Minify is pretty good at getting this right, but occasionally it can make
|
||||
* mistakes. If you find that URL rewriting results in problems, you should
|
||||
* disable it.
|
||||
*/
|
||||
define('MINIFY_REWRITE_CSS_URLS', true);
|
||||
}
|
||||
|
||||
if (!defined('MINIFY_USE_CACHE')) {
|
||||
/**
|
||||
* Whether or not Minify should use a disk-based cache to increase
|
||||
* performance.
|
||||
*/
|
||||
define('MINIFY_USE_CACHE', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minify is a library for combining, minifying, and caching JavaScript and CSS
|
||||
* files on demand before sending them to a web browser.
|
||||
*
|
||||
* @package Minify
|
||||
* @author Ryan Grove <ryan@wonko.com>
|
||||
* @copyright 2007 Ryan Grove. All rights reserved.
|
||||
* @license http://opensource.org/licenses/bsd-license.php New BSD License
|
||||
* @version 1.1.0 (?)
|
||||
* @link http://code.google.com/p/minify/
|
||||
*/
|
||||
class Minify {
|
||||
const TYPE_CSS = 'text/css';
|
||||
const TYPE_HTML = 'text/html';
|
||||
const TYPE_JS = 'text/javascript';
|
||||
|
||||
protected $files = array();
|
||||
protected $type = self::TYPE_JS;
|
||||
|
||||
// -- Public Static Methods --------------------------------------------------
|
||||
|
||||
/**
|
||||
* Combines, minifies, and outputs the requested files.
|
||||
*
|
||||
* Inspects the $_GET array for a 'files' entry containing a comma-separated
|
||||
* list and uses this as the set of files to be combined and minified.
|
||||
*/
|
||||
public static function handleRequest() {
|
||||
// 404 if no files were requested.
|
||||
if (!isset($_GET['files'])) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
exit;
|
||||
}
|
||||
|
||||
$files = array_map('trim', explode(',', $_GET['files'], MINIFY_MAX_FILES));
|
||||
|
||||
// 404 if the $files array is empty for some weird reason.
|
||||
if (!count($files)) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
exit;
|
||||
}
|
||||
|
||||
// Determine the content type based on the extension of the first file
|
||||
// requested.
|
||||
if (preg_match('/\.js$/iD', $files[0])) {
|
||||
$type = self::TYPE_JS;
|
||||
} else if (preg_match('/\.css$/iD', $files[0])) {
|
||||
$type = self::TYPE_CSS;
|
||||
} else {
|
||||
$type = self::TYPE_HTML;
|
||||
}
|
||||
|
||||
// Minify and spit out the result.
|
||||
try {
|
||||
$minify = new Minify($type, $files);
|
||||
|
||||
header("Content-Type: $type;charset=".MINIFY_ENCODING);
|
||||
|
||||
$minify->browserCache();
|
||||
echo $minify->combine();
|
||||
exit;
|
||||
}
|
||||
catch (MinifyException $e) {
|
||||
header('HTTP/1.0 404 Not Found');
|
||||
echo htmlentities($e->getMessage());
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Minifies the specified string and returns it.
|
||||
*
|
||||
* @param string $string JavaScript, CSS, or HTML string to minify
|
||||
* @param string $type content type of the string (Minify::TYPE_CSS,
|
||||
* Minify::TYPE_HTML, or Minify::TYPE_JS)
|
||||
* @return string minified string
|
||||
*/
|
||||
public static function min($string, $type = self::TYPE_JS) {
|
||||
switch ($type) {
|
||||
case self::TYPE_CSS:
|
||||
return self::minifyCSS($string);
|
||||
break;
|
||||
|
||||
case self::TYPE_HTML:
|
||||
return self::minifyHTML($string);
|
||||
break;
|
||||
|
||||
case self::TYPE_JS:
|
||||
return self::minifyJS($string);
|
||||
break;
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
// -- Protected Static Methods -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Minifies the specified CSS string and returns it.
|
||||
*
|
||||
* @param string $css CSS string
|
||||
* @return string minified string
|
||||
* @see minify()
|
||||
* @see minifyJS()
|
||||
*/
|
||||
protected static function minifyCSS($css) {
|
||||
// Compress whitespace.
|
||||
$css = preg_replace('/\s+/', ' ', $css);
|
||||
|
||||
// Remove comments.
|
||||
$css = preg_replace('/\/\*.*?\*\//', '', $css);
|
||||
|
||||
return trim($css);
|
||||
}
|
||||
|
||||
protected static function minifyHTML($html) {
|
||||
require_once dirname(__FILE__).'/lib/htmlmin.php';
|
||||
return HTMLMin::minify($html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Minifies the specified JavaScript string and returns it.
|
||||
*
|
||||
* @param string $js JavaScript string
|
||||
* @return string minified string
|
||||
* @see minify()
|
||||
* @see minifyCSS()
|
||||
*/
|
||||
protected static function minifyJS($js) {
|
||||
require_once dirname(__FILE__).'/../../../lib/JSMin.php';
|
||||
return JSMin::minify($js);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrites relative URLs in the specified CSS string to point to the correct
|
||||
* location. URLs are assumed to be relative to the absolute path specified in
|
||||
* the $path parameter.
|
||||
*
|
||||
* @param string $css CSS string
|
||||
* @param string $path absolute path to which URLs are relative (should be a
|
||||
* directory, not a file)
|
||||
* @return string CSS string with rewritten URLs
|
||||
*/
|
||||
protected static function rewriteCSSUrls($css, $path) {
|
||||
/*
|
||||
Parentheses, commas, whitespace chars, single quotes, and double quotes are
|
||||
escaped with a backslash as described in the CSS spec:
|
||||
http://www.w3.org/TR/REC-CSS1#url
|
||||
*/
|
||||
$relativePath = preg_replace('/([\(\),\s\'"])/', '\\\$1',
|
||||
str_replace(MINIFY_BASE_DIR, '', $path));
|
||||
|
||||
|
||||
return preg_replace('/url\(\s*[\'"]?\/?(.+?)[\'"]?\s*\)/i', 'url('.
|
||||
$relativePath.'/$1)', $css);
|
||||
}
|
||||
|
||||
// -- Public Instance Methods ------------------------------------------------
|
||||
|
||||
/**
|
||||
* Instantiates a new Minify object. A filename can be in the form of a
|
||||
* relative path or a URL that resolves to the same site that hosts Minify.
|
||||
*
|
||||
* @param string $type content type of the specified files (either
|
||||
* Minify::TYPE_CSS or Minify::TYPE_JS)
|
||||
* @param array|string $files filename or array of filenames to be minified
|
||||
*/
|
||||
public function __construct($type = self::TYPE_JS, $files = array()) {
|
||||
if ($type !== self::TYPE_JS && $type !== self::TYPE_CSS) {
|
||||
throw new MinifyInvalidArgumentException('Invalid argument ($type): '.
|
||||
$type);
|
||||
}
|
||||
|
||||
$this->type = $type;
|
||||
|
||||
if (count((array) $files)) {
|
||||
$this->addFile($files);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified filename or array of filenames to the list of files to
|
||||
* be minified. A filename can be in the form of a relative path or a URL
|
||||
* that resolves to the same site that hosts Minify.
|
||||
*
|
||||
* @param array|string $files filename or array of filenames
|
||||
* @see getFiles()
|
||||
* @see removeFile()
|
||||
*/
|
||||
public function addFile($files) {
|
||||
$files = @array_map(array($this, 'resolveFilePath'), (array) $files);
|
||||
$this->files = array_unique(array_merge($this->files, $files));
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to serve the combined, minified files from the cache if possible.
|
||||
*
|
||||
* This method first checks the ETag value and If-Modified-Since timestamp
|
||||
* sent by the browser and exits with an HTTP "304 Not Modified" response if
|
||||
* the requested files haven't changed since they were last sent to the
|
||||
* client.
|
||||
*
|
||||
* If the browser hasn't cached the content, we check to see if it's been
|
||||
* cached on the server and, if so, we send the cached content and exit.
|
||||
*
|
||||
* If neither the client nor the server has the content in its cache, we don't
|
||||
* do anything.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function browserCache() {
|
||||
$hash = $this->getHash();
|
||||
$lastModified = $this->getLastModified();
|
||||
|
||||
$lastModifiedGMT = gmdate('D, d M Y H:i:s', $lastModified).' GMT';
|
||||
|
||||
// Check/set the ETag.
|
||||
$etag = $hash.'_'.$lastModified;
|
||||
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
if (strpos($_SERVER['HTTP_IF_NONE_MATCH'], $etag) !== false) {
|
||||
header("Last-Modified: $lastModifiedGMT", true, 304);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
header('ETag: "'.$etag.'"');
|
||||
|
||||
// Check If-Modified-Since.
|
||||
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
if ($lastModified <= strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
header("Last-Modified: $lastModifiedGMT", true, 304);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
header("Last-Modified: $lastModifiedGMT");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines and returns the contents of all files that have been added with
|
||||
* addFile() or via this class's constructor.
|
||||
*
|
||||
* If MINIFY_USE_CACHE is true, the content will be returned from the server's
|
||||
* cache if the cache is up to date; otherwise the new content will be saved
|
||||
* to the cache for future use.
|
||||
*
|
||||
* @param bool $minify minify the combined contents before returning them
|
||||
* @return string combined file contents
|
||||
*/
|
||||
public function combine($minify = true) {
|
||||
// Return contents from server cache if possible.
|
||||
if (MINIFY_USE_CACHE) {
|
||||
if ($cacheResult = $this->serverCache(true)) {
|
||||
return $cacheResult;
|
||||
}
|
||||
}
|
||||
|
||||
// Combine contents.
|
||||
$combined = array();
|
||||
|
||||
foreach($this->files as $file) {
|
||||
if ($this->type === self::TYPE_CSS && MINIFY_REWRITE_CSS_URLS) {
|
||||
// Rewrite relative CSS URLs.
|
||||
$combined[] = self::rewriteCSSUrls(file_get_contents($file),
|
||||
dirname($file));
|
||||
}
|
||||
else {
|
||||
$combined[] = file_get_contents($file);
|
||||
}
|
||||
}
|
||||
|
||||
$combined = $minify ? self::min(implode("\n", $combined), $this->type) :
|
||||
implode("\n", $combined);
|
||||
|
||||
// Save combined contents to the cache.
|
||||
if (MINIFY_USE_CACHE) {
|
||||
$cacheFile = MINIFY_CACHE_DIR.'/minify_'.$this->getHash();
|
||||
@file_put_contents($cacheFile, $combined, LOCK_EX);
|
||||
}
|
||||
|
||||
return $combined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an array of absolute pathnames of all files that have been added with
|
||||
* addFile() or via this class's constructor.
|
||||
*
|
||||
* @return array array of absolute pathnames
|
||||
* @see addFile()
|
||||
* @see removeFile()
|
||||
*/
|
||||
public function getFiles() {
|
||||
return $this->files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MD5 hash of the concatenated filenames from the list of files to
|
||||
* be minified.
|
||||
*/
|
||||
public function getHash() {
|
||||
return hash('md5', implode('', $this->files));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the timestamp of the most recently modified file.
|
||||
*
|
||||
* @return int timestamp
|
||||
*/
|
||||
public function getLastModified() {
|
||||
$lastModified = 0;
|
||||
|
||||
// Get the timestamp of the most recently modified file.
|
||||
foreach($this->files as $file) {
|
||||
$modified = filemtime($file);
|
||||
|
||||
if ($modified !== false && $modified > $lastModified) {
|
||||
$lastModified = $modified;
|
||||
}
|
||||
}
|
||||
|
||||
return $lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified filename or array of filenames from the list of files
|
||||
* to be minified.
|
||||
*
|
||||
* @param array|string $files filename or array of filenames
|
||||
* @see addFile()
|
||||
* @see getFiles()
|
||||
*/
|
||||
public function removeFile($files) {
|
||||
$files = @array_map(array($this, 'resolveFilePath'), (array) $files);
|
||||
$this->files = array_diff($this->files, $files);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to serve the combined, minified files from the server's disk-based
|
||||
* cache if possible.
|
||||
*
|
||||
* @param bool $return return cached content as a string instead of outputting
|
||||
* it to the client
|
||||
* @return bool|string
|
||||
*/
|
||||
public function serverCache($return = false) {
|
||||
$cacheFile = MINIFY_CACHE_DIR.'/minify_'.$this->getHash();
|
||||
$lastModified = $this->getLastModified();
|
||||
|
||||
if (is_file($cacheFile) && $lastModified <= filemtime($cacheFile)) {
|
||||
if ($return) {
|
||||
return file_get_contents($cacheFile);
|
||||
}
|
||||
else {
|
||||
echo file_get_contents($cacheFile);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// -- Protected Instance Methods ---------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns the canonicalized absolute pathname to the specified file or local
|
||||
* URL.
|
||||
*
|
||||
* @param string $file relative file path
|
||||
* @return string canonicalized absolute pathname
|
||||
*/
|
||||
protected function resolveFilePath($file) {
|
||||
// Is this a URL?
|
||||
if (preg_match('/^https?:\/\//i', $file)) {
|
||||
if (!$parsedUrl = parse_url($file)) {
|
||||
throw new MinifyInvalidUrlException("Invalid URL: $file");
|
||||
}
|
||||
|
||||
// Does the server name match the local server name?
|
||||
if (!isset($parsedUrl['host']) ||
|
||||
$parsedUrl['host'] != $_SERVER['SERVER_NAME']) {
|
||||
throw new MinifyInvalidUrlException('Non-local URL not supported: '.
|
||||
$file);
|
||||
}
|
||||
|
||||
// Get the file's absolute path.
|
||||
$filepath = realpath(MINIFY_BASE_DIR.$parsedUrl['path']);
|
||||
}
|
||||
else {
|
||||
// Get the file's absolute path.
|
||||
$filepath = realpath(MINIFY_BASE_DIR.'/'.$file);
|
||||
}
|
||||
|
||||
// Ensure that the file exists, that the path is under the base directory,
|
||||
// that the file's extension is either '.css' or '.js', and that the file is
|
||||
// actually readable.
|
||||
if (!$filepath ||
|
||||
!is_file($filepath) ||
|
||||
!is_readable($filepath) ||
|
||||
!preg_match('/^'.preg_quote(MINIFY_BASE_DIR, '/').'/', $filepath) ||
|
||||
!preg_match('/\.(?:css|js)$/iD', $filepath)) {
|
||||
|
||||
// Even when the file exists, we still throw a
|
||||
// MinifyFileNotFoundException in order to try to prevent an information
|
||||
// disclosure vulnerability.
|
||||
throw new MinifyFileNotFoundException("File not found: $file");
|
||||
}
|
||||
|
||||
return $filepath;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Exception Classes --------------------------------------------------------
|
||||
class MinifyException extends Exception {}
|
||||
class MinifyFileNotFoundException extends MinifyException {}
|
||||
class MinifyInvalidArgumentException extends MinifyException {}
|
||||
class MinifyInvalidUrlException extends MinifyException {}
|
||||
|
||||
// -- Global Scope -------------------------------------------------------------
|
||||
if (realpath(__FILE__) == realpath($_SERVER['SCRIPT_FILENAME'])) {
|
||||
Minify::handleRequest();
|
||||
}
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user