If your web page includes many CSS and/or JavaScript files, the page will open very slowly because the browser sends a large number of HTTP requests to download each file in separated threads. To reduce the number of requests and connections, we can combine and compress multiple CSS/JavaScript files into one or very few files in production mode, and then include these compressed files on the page instead of the original ones.
yii2-app-basic
application using the Composer package manager, as described in the official guide at http://www.yiiframework.com/doc-2.0/guide-start-installation.htmlcompiler.jar
file from https://developers.google.com/closure/compiler/yuicompressor.jar
file from https://github.com/yui/yuicompressor/releasesFollow these steps to combine and minimize assets:
index
page of your application. Check whether it is similar to the following structure:<!DOCTYPE html> <html lang="en-US"> <head> ... <title>My Yii Application</title> <link href="/assets/9b3b2888/css/bootstrap.css" rel="stylesheet"> <link href="/css/site.css" rel="stylesheet"> </head> <body> ... <script src="/assets/25f82b8a/jquery.js"></script> <script src="/assets/f4307424/yii.js"></script> <script src="/assets/9b3b2888/js/bootstrap.js"></script> </body> </html>
The page includes three JavaScript files.
config/console.php
file and add the @webroot
and @web
alias definitions:<?php Yii::setAlias('@webroot', __DIR__ . '/../web'); Yii::setAlias('@web', '/');
yii asset/template assets.php
assets.php
file and configure it as follows:<?php return [ 'jsCompressor' => 'java -jar compiler.jar --js {from} --js_output_file {to}', 'cssCompressor' => 'java -jar yuicompressor.jar --type css {from} -o {to}', 'bundles' => [ 'appassetsAppAsset', 'yiiootstrapBootstrapPluginAsset', ], 'targets' => [ 'all' => [ 'class' => 'yiiwebAssetBundle', 'basePath' => '@webroot/assets', 'baseUrl' => '@web/assets', 'js' => 'all-{hash}.js', 'css' => 'all-{hash}.css', ], ], 'assetManager' => [ 'basePath' => '@webroot/assets', 'baseUrl' => '@web/assets', ], ];
yii asset assets.php config/assets-prod.php
. If this is successful you must get the config/assets-prod.php
file with the following configuration:<?php return [ 'all' => [ 'class' => 'yii\web\AssetBundle', 'basePath' => '@webroot/assets', 'baseUrl' => '@web/assets', 'js' => [ 'all-fe792d4766bead53e7a9d851adfc6ec2.js', ], 'css' => [ 'all-37cfb42649f74eb0a4bfe0d0e715c420.css', ], ], 'yii\web\JqueryAsset' => [ 'sourcePath' => null, 'js' => [], 'css' => [], 'depends' => [ 'all', ], ], 'yii\web\YiiAsset' => [ 'sourcePath' => null, 'js' => [], 'css' => [], 'depends' => [ 'yii\web\JqueryAsset', 'all', ], ], 'yii\bootstrap\BootstrapAsset' => [ 'sourcePath' => null, 'js' => [], 'css' => [], 'depends' => [ 'all', ], ], 'app\assets\AppAsset' => [ 'sourcePath' => null, 'js' => [], 'css' => [], 'depends' => [ 'yii\web\YiiAsset', 'yii\bootstrap\BootstrapAsset', 'all', ], ], 'yii\bootstrap\BootstrapPluginAsset' => [ 'sourcePath' => null, 'js' => [], 'css' => [], 'depends' => [ 'yii\web\JqueryAsset', 'yii\bootstrap\BootstrapAsset', 'all', ], ], ];
assetManager
component into the config/web.php
file:'components' => [ // ... 'assetManager' => [ 'bundles' => YII_ENV_PROD ? require(__DIR__ . '/assets-prod.php') : [], ], ],
web/index.php
:defined('YII_ENV') or define('YII_ENV', 'prod');
<!DOCTYPE html> <html lang="en-US"> <head> ... <title>My Yii Application</title> <link href="/assets/all-37cfb42649f74eb0a4bfe0d0e715c420.css" rel="stylesheet"> </head> <body> ... <script src="/assets/all-fe792d4766bead53e7a9d851adfc6ec2.js"></script> </body> </html>
First of all, our page had a set of included files:
<link href="/assets/9b3b2888/css/bootstrap.css" rel="stylesheet"> <link href="/css/site.css" rel="stylesheet"> ... <script src="/assets/25f82b8a/jquery.js"></script> <script src="/assets/f4307424/yii.js"></script> <script src="/assets/9b3b2888/js/bootstrap.js"></script>
Next, we generated the assets.php
configuration file and specified bundles for compressing:
'bundles' => [ 'appassetsAppAsset', 'yiiootstrapBootstrapPluginAsset', ],
The AssetManager publishes all assets into the classic subdirectories in web/assets
and after publishing it runs compressors to combine all CSS and JS files into all-{hash}.js
and all-{hash}.css
.
Check whether the CSS file includes other resources by relative paths such as the bootstrap.css
file:
@font-face { font-family: 'Glyphicons Halflings'; src: url('../fonts/glyphicons-halflings-regular.eot'); }
If it is so, then in the combined file, our compressor changes all relative paths for storing all relationships as follows:
@font-face{ font-family: 'Glyphicons Halflings'; src: url('9b3b2888/fonts/glyphicons-halflings-regular.eot'); }
After processing, we get the assets-prod.php
file with the bundles configuration of the assetManager
component. It defines the new virtual asset as a dependency of clean copies of the original bundles:
return [ 'all' => [ 'class' => 'yii\web\AssetBundle', 'basePath' => '@webroot/assets', 'baseUrl' => '@web/assets', 'js' => [ 'all-fe792d4766bead53e7a9d851adfc6ec2.js', ], 'css' => [ 'all-37cfb42649f74eb0a4bfe0d0e715c420.css', ], ], 'yii\web\JqueryAsset' => [ 'sourcePath' => null, 'js' => [], 'css' => [], 'depends' => [ 'all', ], ], // ... ]
Now we can require this configuration into the config/web.php
file:
'components' => [ // ... 'assetManager' => [ 'bundles' => require(__DIR__ . '/assets-prod.php'), ], ],
Alternatively, we can require the file for the production environment only:
'components' => [ // ... 'assetManager' => [ 'bundles' => YII_ENV_PROD ? require(__DIR__ . '/assets-prod.php') : [], ], ],
18.223.160.61