Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Introducing Assetic
  Asset Management for PHP 5.3




         March 1, 2011
@kriswallsmith

•   Symfony Guru at

•   Symfony core team member

•   Doctrine contributor

•   10+ years experience with...
OpenSky connects you with innovators,
trendsetters and tastemakers.You choose
   the ones you like and each week they
  in...
OpenSky connects you with innovators,
trendsetters and tastemakers.You choose
   the ones you like and each week they
  in...
ShopOpenSky.com

•   PHP 5.3 + Symfony2

•   MongoDB + Doctrine MongoDB ODM

•   MySQL + Doctrine2 ORM

•   Less CSS

•   ...
Agenda


•   !(straw man)

•   Assetic

•   Twig, Symfony2 integration
If you haven’t optimized your
frontend, you haven’t optimized
A poorly optimized frontend
     can destroy UX
…and SEO


http://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html
Get your assets in line.
Asset Management
Lots of awesome tools:
Lots of awesome tools:
•   CoffeeScript              •   Packer

•   Compass Framework         •   SASS

•   CSSEmbed     ...
The ones written in PHP…
The ones written in PHP…
This is a difficult problem
Assetic makes it easy
Enough talk
# /path/to/web/js/core.php

$core = new FileAsset('/path/to/jquery.js');
$core->load();

header('Content-Type: text/javasc...
# /path/to/web/js/core.php

$core = new AssetCollection(array(
    new FileAsset('/path/to/jquery.js'),
    new GlobAsset(...
# /path/to/web/js/core.php

$core = new AssetCollection(array(
    new FileAsset('/path/to/jquery.js'),
    new GlobAsset(...
# /path/to/web/js/core.php

$core = new AssetCollection(array(
    new FileAsset('/path/to/jquery.js'),
    new GlobAsset(...
# /path/to/web/js/core.php

$core = new AssetCollection(array(
    new FileAsset('/path/to/jquery.js'),
    new GlobAsset(...
<script src="js/core.php"></script>
Assetic is
Assets & Filters
Inspired by Python’s webassets


        https://github.com/miracle2k/webassets
Assets have lazy, mutable content
Filters act on asset contents during
         “load” and “dump”
Assets can be gathered in
       collections
A collection is an asset
Asset
Filter
Asset
Filter
Filter
Asset
Load
   Filter
   Filter
   Asset
Filter
Filter
Asset




         Dump
Filter
Filter
Asset
Asset Collection
Filter              Filter
Filter              Filter
Asset               Asset
Asset Collection   Filter
                                 Filter
     Asset Collection            Asset
Filter           ...
# /path/to/web/css/styles.php

$styles = new AssetCollection(
    array(new FileAsset('/path/to/main.sass')),
    array(ne...
# /path/to/web/css/styles.php

$styles = new AssetCollection(array(
    new AssetCollection(
        array(new FileAsset('...
# /path/to/web/css/styles.php

$styles = new AssetCollection(array(
    new AssetCollection(
        array(new FileAsset('...
# /path/to/web/css/styles.php

$styles = new AssetCollection(array(
    new AssetCollection(
          array(new FileAsset...
Basic Asset Classes

•   AssetCollection

•   AssetReference

•   FileAsset

•   GlobAsset

•   StringAsset
Core Filter Classes
•   CallablesFilter                   •   SassScssFilter

•   CoffeeScriptFilter                •   Sp...
Asset Manager
$am = new AssetManager();
$am->set('jquery',
    new FileAsset('/path/to/jquery.js'));
$plugin = new AssetCollection(array(
    new AssetReference($am, 'jquery'),
    new FileAsset('/path/to/jquery.plugin.js')...
$core = new AssetCollection(array(
    $jquery,
    $plugin1,
    $plugin2,
));

header('text/javascript');
echo $core->du...
jQuery will only be included once
       $core = new AssetCollection(array(
           $jquery,
           $plugin1,
     ...
Filter Manager
$yui = new YuiCompressorJs();
$yui->setNomunge(true);

$fm = new FilterManager();
$fm->set('yui_js', $yui);
$jquery = new FileAsset('/path/to/core.js');
$jquery->ensureFilter($fm->get('yui_js'));

$core = new AssetCollection(array...
jQuery will only be compressed once

   $jquery = new FileAsset('/path/to/core.js');
   $jquery->ensureFilter($fm->get('yu...
Asset Factory
# /path/to/asset_factory.php

$fm = new FilterManager();
$fm->set('coffee', new CoffeeScriptFilter());
$fm->set('closure',...
include '/path/to/asset_factory.php';

$asset = $factory->createAsset(
    array('js/src/*.coffee'),
    array('coffee', '...
Debug Mode
Debugging compressed
   Javascript sucks
Mark filters for omission
in debug mode using a “?”
// new AssetFactory('/path/to/web', true);

include '/path/to/asset_factory.php';

$asset = $factory->createAsset(
    arr...
// new AssetFactory('/path/to/web', true);

include '/path/to/asset_factory.php';

$asset = $factory->createAsset(
    arr...
// new AssetFactory('/path/to/web', false);

include '/path/to/asset_factory.php';

$asset = $factory->createAsset(
    ar...
Factory Workers
Everything passes through the
       workers’ hands
$worker = new EnsureFilterWorker(
    '/.css$/',         // the output pattern
    $fm->get('yui_css') // the filter
);

$...
Good: Basic Caching
# /path/to/web/css/styles.php

$styles = new AssetCollection(
    array(new FileAsset('/path/to/main.sass')),
    array(ne...
# /path/to/web/css/styles.php

$styles = new AssetCache(new AssetCollection(
    array(new FileAsset('/path/to/main.sass')...
# /path/to/web/css/styles.php

$styles = new AssetCache(new AssetCollection(
    array(new FileAsset('/path/to/main.sass')...
Better: HTTP Caching
// $core = new AssetCache(...

$mtime = gmdate('D, d M y H:i:s',
    $core->getLastModified()).' GMT';

if ($mtime == $_SE...
Best: Static Assets
# /path/to/scripts/dump_assets.php

$am = new AssetManager();
$am->set('foo', $foo);
// etc...

$writer = new AssetWriter(...
Best-est:
Content Distribution Network
new AssetWriter('s3://my-bucket')
new AssetWriter('s3://my-bucket')

                 A CloudFront S3 bucket
Not Lazy Enough?
Asset Formulae and the
 Lazy Asset Manager
$asset = $factory->createAsset(
    array('js/src/*.coffee'),
    array('coffee', '?closure'),
    array('output' => 'js/*...
$formula = array(
    array('js/src/*.coffee'),
    array('coffee', '?closure'),
    array('output' => 'js/*.js')
);
$am = new LazyAssetManager($factory);
$am->setFormula('core_js', $formula);

header('Content-Type: text/javascript');
echo...
This will make more sense
    in a few minutes…
Thought…
Assets are a part of the view layer
  and should be defined there.
<!-- header.php -->

<?php foreach (assetic_javascripts(
    array('js/core.js', 'js/more.js'),
    array('?yui_js')) as $...
# config/assetic.php

require_once '/path/to/assetic/functions.php';
assetic_init($factory);
Issue…
Assets defined in the view layer
must actually exist somewhere
Option Bad...
Lazily dump assets to the
      web directory
Option Good…
Eagerly dump assets to the
      web directory
Formula Loaders
$loader = new FunctionCallsFormulaLoader();
$resource = new DirectoryResource(
    '/path/to/templates',
    '/.php$/'
);
...
$am = new LazyAssetManager($factory);
$am->setLoader('php', $loader);
$am->addResource($resource, 'php');

$writer = new A...
$am = new LazyAssetManager($factory);
$am->setLoader('php', $loader);
$am->addResource($resource, 'php');
               E...
$cache = new ConfigCache('/path/to/cache');

$loader = new CachedFormulaLoader(
    $loader,
    $cache,
    $debug
);
Twig Integration
$twig->addExtension(new AsseticExtension($factory));
{% assetic 'js/*.coffee', filter='coffee' %}
<script src="{{ asset_url }}"></script>
{% endassetic %}
<script src="assets/92429d8"></script>
{% assetic 'js/*.coffee', filter='coffee' %}
<script src="{{ asset_url }}"></script>
{% endassetic %}
{% assetic 'js/*.coffee', filter='coffee',
   output='js/*.js' %}
<script src="{{ asset_url }}"></script>
{% endassetic %}
<script src="js/92429d8.js"></script>
{% assetic 'js/*.coffee', filter='coffee',
   output='js/*.js' %}
<script src="{{ asset_url }}"></script>
{% endassetic %}
{% assetic 'js/*.coffee', filter='coffee,?closure',
   output='js/*.js', name='core_js' %}
<script src="{{ asset_url }}"><...
AsseticBundle
  Symfony2 integration
{% assetic filter='scss,?yui_css', output='css/all.css',
   '@MainBundle/Resources/sass/main.scss',
   '@AnotherBundle/Res...
<link href="css/all.css" rel="stylesheet" />
{% assetic filter='scss,?yui_css', output='css/all.css',
   '@MainBundle/Resources/sass/main.scss',
   '@AnotherBundle/Res...
{% assetic filter='scss,?yui_css', output='css/all.css',
   '@MainBundle/Resources/sass/main.scss', debug=true,
   '@Anoth...
<link href="css/all_part1.css" rel="stylesheet" />
<link href="css/all_part2.css" rel="stylesheet" />
Each "leaf" asset is referenced individually

<link href="css/all_part1.css" rel="stylesheet" />
<link href="css/all_part2...
Configuration
assetic:
    debug:            %kernel.debug%
    use_controller:   %kernel.debug%
    read_from:        %kernel.root_dir%...
{# when use_controller=true #}

<script src="{{ path('assetic_foo') }}"...
# routing_dev.yml
_assetic:
    resource: .
    type:     assetic
{# when use_controller=false #}

<script src="{{ asset('js/core.js') }}"></script>
{# when use_controller=false #}

<script src="{{ asset('js/core.js') }}"></script>

                 Lots for free
The Symfony2 Assets Helper


•   Multiple asset domains

•   Cache buster
framework:
    templating:
        assets_version: 1.2.3
        assets_base_urls:
            - http://assets1.domain.com...
{% assetic filter='scss,?yui_css', output='css/all.css',
   '@MainBundle/Resources/sass/main.scss',
   '@AnotherBundle/Res...
<link href="http://assets3.domain.com/css/all.css?1.2.3" ...
assetic:dump
$ php app/console assetic:dump web/
$ php app/console assetic:dump s3://my-bucket
assetic:dump --watch
  Dump static assets in the background as you develop
Questions?
http://github.com/kriswallsmith/assetic
Introducing Assetic (NYPHP)
Upcoming SlideShare
Loading in …5
×

of

Introducing Assetic (NYPHP) Slide 1 Introducing Assetic (NYPHP) Slide 2 Introducing Assetic (NYPHP) Slide 3 Introducing Assetic (NYPHP) Slide 4 Introducing Assetic (NYPHP) Slide 5 Introducing Assetic (NYPHP) Slide 6 Introducing Assetic (NYPHP) Slide 7 Introducing Assetic (NYPHP) Slide 8 Introducing Assetic (NYPHP) Slide 9 Introducing Assetic (NYPHP) Slide 10 Introducing Assetic (NYPHP) Slide 11 Introducing Assetic (NYPHP) Slide 12 Introducing Assetic (NYPHP) Slide 13 Introducing Assetic (NYPHP) Slide 14 Introducing Assetic (NYPHP) Slide 15 Introducing Assetic (NYPHP) Slide 16 Introducing Assetic (NYPHP) Slide 17 Introducing Assetic (NYPHP) Slide 18 Introducing Assetic (NYPHP) Slide 19 Introducing Assetic (NYPHP) Slide 20 Introducing Assetic (NYPHP) Slide 21 Introducing Assetic (NYPHP) Slide 22 Introducing Assetic (NYPHP) Slide 23 Introducing Assetic (NYPHP) Slide 24 Introducing Assetic (NYPHP) Slide 25 Introducing Assetic (NYPHP) Slide 26 Introducing Assetic (NYPHP) Slide 27 Introducing Assetic (NYPHP) Slide 28 Introducing Assetic (NYPHP) Slide 29 Introducing Assetic (NYPHP) Slide 30 Introducing Assetic (NYPHP) Slide 31 Introducing Assetic (NYPHP) Slide 32 Introducing Assetic (NYPHP) Slide 33 Introducing Assetic (NYPHP) Slide 34 Introducing Assetic (NYPHP) Slide 35 Introducing Assetic (NYPHP) Slide 36 Introducing Assetic (NYPHP) Slide 37 Introducing Assetic (NYPHP) Slide 38 Introducing Assetic (NYPHP) Slide 39 Introducing Assetic (NYPHP) Slide 40 Introducing Assetic (NYPHP) Slide 41 Introducing Assetic (NYPHP) Slide 42 Introducing Assetic (NYPHP) Slide 43 Introducing Assetic (NYPHP) Slide 44 Introducing Assetic (NYPHP) Slide 45 Introducing Assetic (NYPHP) Slide 46 Introducing Assetic (NYPHP) Slide 47 Introducing Assetic (NYPHP) Slide 48 Introducing Assetic (NYPHP) Slide 49 Introducing Assetic (NYPHP) Slide 50 Introducing Assetic (NYPHP) Slide 51 Introducing Assetic (NYPHP) Slide 52 Introducing Assetic (NYPHP) Slide 53 Introducing Assetic (NYPHP) Slide 54 Introducing Assetic (NYPHP) Slide 55 Introducing Assetic (NYPHP) Slide 56 Introducing Assetic (NYPHP) Slide 57 Introducing Assetic (NYPHP) Slide 58 Introducing Assetic (NYPHP) Slide 59 Introducing Assetic (NYPHP) Slide 60 Introducing Assetic (NYPHP) Slide 61 Introducing Assetic (NYPHP) Slide 62 Introducing Assetic (NYPHP) Slide 63 Introducing Assetic (NYPHP) Slide 64 Introducing Assetic (NYPHP) Slide 65 Introducing Assetic (NYPHP) Slide 66 Introducing Assetic (NYPHP) Slide 67 Introducing Assetic (NYPHP) Slide 68 Introducing Assetic (NYPHP) Slide 69 Introducing Assetic (NYPHP) Slide 70 Introducing Assetic (NYPHP) Slide 71 Introducing Assetic (NYPHP) Slide 72 Introducing Assetic (NYPHP) Slide 73 Introducing Assetic (NYPHP) Slide 74 Introducing Assetic (NYPHP) Slide 75 Introducing Assetic (NYPHP) Slide 76 Introducing Assetic (NYPHP) Slide 77 Introducing Assetic (NYPHP) Slide 78 Introducing Assetic (NYPHP) Slide 79 Introducing Assetic (NYPHP) Slide 80 Introducing Assetic (NYPHP) Slide 81 Introducing Assetic (NYPHP) Slide 82 Introducing Assetic (NYPHP) Slide 83 Introducing Assetic (NYPHP) Slide 84 Introducing Assetic (NYPHP) Slide 85 Introducing Assetic (NYPHP) Slide 86 Introducing Assetic (NYPHP) Slide 87 Introducing Assetic (NYPHP) Slide 88 Introducing Assetic (NYPHP) Slide 89 Introducing Assetic (NYPHP) Slide 90 Introducing Assetic (NYPHP) Slide 91 Introducing Assetic (NYPHP) Slide 92 Introducing Assetic (NYPHP) Slide 93 Introducing Assetic (NYPHP) Slide 94 Introducing Assetic (NYPHP) Slide 95 Introducing Assetic (NYPHP) Slide 96 Introducing Assetic (NYPHP) Slide 97 Introducing Assetic (NYPHP) Slide 98 Introducing Assetic (NYPHP) Slide 99 Introducing Assetic (NYPHP) Slide 100 Introducing Assetic (NYPHP) Slide 101 Introducing Assetic (NYPHP) Slide 102 Introducing Assetic (NYPHP) Slide 103 Introducing Assetic (NYPHP) Slide 104 Introducing Assetic (NYPHP) Slide 105 Introducing Assetic (NYPHP) Slide 106 Introducing Assetic (NYPHP) Slide 107 Introducing Assetic (NYPHP) Slide 108 Introducing Assetic (NYPHP) Slide 109 Introducing Assetic (NYPHP) Slide 110 Introducing Assetic (NYPHP) Slide 111 Introducing Assetic (NYPHP) Slide 112 Introducing Assetic (NYPHP) Slide 113 Introducing Assetic (NYPHP) Slide 114 Introducing Assetic (NYPHP) Slide 115 Introducing Assetic (NYPHP) Slide 116 Introducing Assetic (NYPHP) Slide 117 Introducing Assetic (NYPHP) Slide 118 Introducing Assetic (NYPHP) Slide 119 Introducing Assetic (NYPHP) Slide 120 Introducing Assetic (NYPHP) Slide 121 Introducing Assetic (NYPHP) Slide 122 Introducing Assetic (NYPHP) Slide 123 Introducing Assetic (NYPHP) Slide 124 Introducing Assetic (NYPHP) Slide 125
Upcoming SlideShare
Assetic (Zendcon)
Next
Download to read offline and view in fullscreen.

14 Likes

Share

Download to read offline

Introducing Assetic (NYPHP)

Download to read offline

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Introducing Assetic (NYPHP)

  1. 1. Introducing Assetic Asset Management for PHP 5.3 March 1, 2011
  2. 2. @kriswallsmith • Symfony Guru at • Symfony core team member • Doctrine contributor • 10+ years experience with PHP and web development • Open source evangelist and international speaker
  3. 3. OpenSky connects you with innovators, trendsetters and tastemakers.You choose the ones you like and each week they invite you to their private online sales.
  4. 4. OpenSky connects you with innovators, trendsetters and tastemakers.You choose the ones you like and each week they invite you to their private online sales.
  5. 5. ShopOpenSky.com • PHP 5.3 + Symfony2 • MongoDB + Doctrine MongoDB ODM • MySQL + Doctrine2 ORM • Less CSS • jQuery
  6. 6. Agenda • !(straw man) • Assetic • Twig, Symfony2 integration
  7. 7. If you haven’t optimized your frontend, you haven’t optimized
  8. 8. A poorly optimized frontend can destroy UX
  9. 9. …and SEO http://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html
  10. 10. Get your assets in line.
  11. 11. Asset Management
  12. 12. Lots of awesome tools:
  13. 13. Lots of awesome tools: • CoffeeScript • Packer • Compass Framework • SASS • CSSEmbed • Sprockets • Google Closure Compiler • Stylus • JSMin • YUI Compressor • LESS
  14. 14. The ones written in PHP…
  15. 15. The ones written in PHP…
  16. 16. This is a difficult problem
  17. 17. Assetic makes it easy
  18. 18. Enough talk
  19. 19. # /path/to/web/js/core.php $core = new FileAsset('/path/to/jquery.js'); $core->load(); header('Content-Type: text/javascript'); echo $core->dump();
  20. 20. # /path/to/web/js/core.php $core = new AssetCollection(array( new FileAsset('/path/to/jquery.js'), new GlobAsset('/path/to/js/core/*.js'), )); $core->load(); header('Content-Type: text/javascript'); echo $core->dump();
  21. 21. # /path/to/web/js/core.php $core = new AssetCollection(array( new FileAsset('/path/to/jquery.js'), new GlobAsset('/path/to/js/core/*.js'), )); $core->load();many files into one == fewer HTTP requests Merge header('Content-Type: text/javascript'); echo $core->dump();
  22. 22. # /path/to/web/js/core.php $core = new AssetCollection(array( new FileAsset('/path/to/jquery.js'), new GlobAsset('/path/to/js/core/*.js'), ), array( new YuiCompressorJsFilter('/path/to/yui.jar'), )); $core->load(); header('Content-Type: text/javascript'); echo $core->dump();
  23. 23. # /path/to/web/js/core.php $core = new AssetCollection(array( new FileAsset('/path/to/jquery.js'), new GlobAsset('/path/to/js/core/*.js'), ), array( new YuiCompressorJsFilter('/path/to/yui.jar'), )); $core->load(); Compress the merged asset == less data over the wire header('Content-Type: text/javascript'); echo $core->dump();
  24. 24. <script src="js/core.php"></script>
  25. 25. Assetic is Assets & Filters
  26. 26. Inspired by Python’s webassets https://github.com/miracle2k/webassets
  27. 27. Assets have lazy, mutable content
  28. 28. Filters act on asset contents during “load” and “dump”
  29. 29. Assets can be gathered in collections
  30. 30. A collection is an asset
  31. 31. Asset
  32. 32. Filter Asset
  33. 33. Filter Filter Asset
  34. 34. Load Filter Filter Asset
  35. 35. Filter Filter Asset Dump
  36. 36. Filter Filter Asset
  37. 37. Asset Collection Filter Filter Filter Filter Asset Asset
  38. 38. Asset Collection Filter Filter Asset Collection Asset Filter Filter Filter Filter Asset Asset Filter Filter Asset
  39. 39. # /path/to/web/css/styles.php $styles = new AssetCollection( array(new FileAsset('/path/to/main.sass')), array(new SassFilter()) ); header('Content-Type: text/css'); echo $styles->dump();
  40. 40. # /path/to/web/css/styles.php $styles = new AssetCollection(array( new AssetCollection( array(new FileAsset('/path/to/main.sass')), array(new SassFilter()) ), new FileAsset('/path/to/more.css'), )); header('Content-Type: text/css'); echo $styles->dump();
  41. 41. # /path/to/web/css/styles.php $styles = new AssetCollection(array( new AssetCollection( array(new FileAsset('/path/to/main.sass')), array(new SassFilter()) ), new FileAsset('/path/to/more.css'), ), array( new YuiCompressorCss('/path/to/yui.jar'), )); header('Content-Type: text/css'); echo $styles->dump();
  42. 42. # /path/to/web/css/styles.php $styles = new AssetCollection(array( new AssetCollection( array(new FileAsset('/path/to/main.sass')), array(new SassFilter()) ), new FileAsset('/path/to/more.css'), ), array( new YuiCompressorCss('/path/to/yui.jar'), )); Lazy! The filesystem isn't touched until now header('Content-Type: text/css'); echo $styles->dump();
  43. 43. Basic Asset Classes • AssetCollection • AssetReference • FileAsset • GlobAsset • StringAsset
  44. 44. Core Filter Classes • CallablesFilter • SassScssFilter • CoffeeScriptFilter • SprocketsFilter • CssRewriteFilter • StylusFilter • GoogleClosureCompilerApiFilter • YuiCssCompressorFilter • GoogleClosureCompilerJarFilter • YuiJsCompressorFilter • LessFilter • More to come… • SassSassFilter
  45. 45. Asset Manager
  46. 46. $am = new AssetManager(); $am->set('jquery', new FileAsset('/path/to/jquery.js'));
  47. 47. $plugin = new AssetCollection(array( new AssetReference($am, 'jquery'), new FileAsset('/path/to/jquery.plugin.js'), ));
  48. 48. $core = new AssetCollection(array( $jquery, $plugin1, $plugin2, )); header('text/javascript'); echo $core->dump();
  49. 49. jQuery will only be included once $core = new AssetCollection(array( $jquery, $plugin1, $plugin2, )); header('text/javascript'); echo $core->dump();
  50. 50. Filter Manager
  51. 51. $yui = new YuiCompressorJs(); $yui->setNomunge(true); $fm = new FilterManager(); $fm->set('yui_js', $yui);
  52. 52. $jquery = new FileAsset('/path/to/core.js'); $jquery->ensureFilter($fm->get('yui_js')); $core = new AssetCollection(array( $jquery, new GlobAsset('/path/to/js/core/*.js'), )); $core->ensureFilter($fm->get('yui_js'));
  53. 53. jQuery will only be compressed once $jquery = new FileAsset('/path/to/core.js'); $jquery->ensureFilter($fm->get('yui_js')); $core = new AssetCollection(array( $jquery, new GlobAsset('/path/to/js/core/*.js'), )); $core->ensureFilter($fm->get('yui_js'));
  54. 54. Asset Factory
  55. 55. # /path/to/asset_factory.php $fm = new FilterManager(); $fm->set('coffee', new CoffeeScriptFilter()); $fm->set('closure', new GoogleClosureCompilerApi()); $factory = new AssetFactory('/path/to/web'); $factory->setFilterManager($fm);
  56. 56. include '/path/to/asset_factory.php'; $asset = $factory->createAsset( array('js/src/*.coffee'), array('coffee', 'closure') ); header('Content-Type: text/javascript'); echo $asset->dump();
  57. 57. Debug Mode
  58. 58. Debugging compressed Javascript sucks
  59. 59. Mark filters for omission in debug mode using a “?”
  60. 60. // new AssetFactory('/path/to/web', true); include '/path/to/asset_factory.php'; $asset = $factory->createAsset( array('js/src/*.coffee'), array('coffee', 'closure') ); header('Content-Type: text/javascript'); echo $asset->dump();
  61. 61. // new AssetFactory('/path/to/web', true); include '/path/to/asset_factory.php'; $asset = $factory->createAsset( array('js/src/*.coffee'), array('coffee', '?closure') ); header('Content-Type: text/javascript'); echo $asset->dump();
  62. 62. // new AssetFactory('/path/to/web', false); include '/path/to/asset_factory.php'; $asset = $factory->createAsset( array('js/src/*.coffee'), array('coffee', '?closure'), array('debug' => true) ); header('Content-Type: text/javascript'); echo $asset->dump();
  63. 63. Factory Workers
  64. 64. Everything passes through the workers’ hands
  65. 65. $worker = new EnsureFilterWorker( '/.css$/', // the output pattern $fm->get('yui_css') // the filter ); $factory = new AssetFactory('/path/to/web'); $factory->addWorker($worker); // compressed $factory->createAsset('css/sass/*', 'sass', array( 'output' => 'css/*.css', ));
  66. 66. Good: Basic Caching
  67. 67. # /path/to/web/css/styles.php $styles = new AssetCollection( array(new FileAsset('/path/to/main.sass')), array(new SassFilter()) ); echo $styles->dump();
  68. 68. # /path/to/web/css/styles.php $styles = new AssetCache(new AssetCollection( array(new FileAsset('/path/to/main.sass')), array(new SassFilter()) ), new FilesystemCache('/path/to/cache')); echo $styles->dump();
  69. 69. # /path/to/web/css/styles.php $styles = new AssetCache(new AssetCollection( array(new FileAsset('/path/to/main.sass')), array(new SassFilter()) ), new FilesystemCache('/path/to/cache')); Run the filters once and cache the content echo $styles->dump();
  70. 70. Better: HTTP Caching
  71. 71. // $core = new AssetCache(... $mtime = gmdate('D, d M y H:i:s', $core->getLastModified()).' GMT'; if ($mtime == $_SERVER['HTTP_IF_MODIFIED_SINCE']) { header('HTTP/1.0 304 Not Modified'); exit(); } header('Content-Type: text/javascript'); header('Last-Modified: '.$mtime); echo $core->dump();
  72. 72. Best: Static Assets
  73. 73. # /path/to/scripts/dump_assets.php $am = new AssetManager(); $am->set('foo', $foo); // etc... $writer = new AssetWriter('/path/to/web'); $writer->writeManagerAssets($am);
  74. 74. Best-est: Content Distribution Network
  75. 75. new AssetWriter('s3://my-bucket')
  76. 76. new AssetWriter('s3://my-bucket') A CloudFront S3 bucket
  77. 77. Not Lazy Enough?
  78. 78. Asset Formulae and the Lazy Asset Manager
  79. 79. $asset = $factory->createAsset( array('js/src/*.coffee'), array('coffee', '?closure'), array('output' => 'js/*.js') );
  80. 80. $formula = array( array('js/src/*.coffee'), array('coffee', '?closure'), array('output' => 'js/*.js') );
  81. 81. $am = new LazyAssetManager($factory); $am->setFormula('core_js', $formula); header('Content-Type: text/javascript'); echo $am->get('core_js')->dump();
  82. 82. This will make more sense in a few minutes…
  83. 83. Thought… Assets are a part of the view layer and should be defined there.
  84. 84. <!-- header.php --> <?php foreach (assetic_javascripts( array('js/core.js', 'js/more.js'), array('?yui_js')) as $url): ?> <script src="<?php echo $url ?>"></script> <?php endforeach; ?>
  85. 85. # config/assetic.php require_once '/path/to/assetic/functions.php'; assetic_init($factory);
  86. 86. Issue… Assets defined in the view layer must actually exist somewhere
  87. 87. Option Bad... Lazily dump assets to the web directory
  88. 88. Option Good… Eagerly dump assets to the web directory
  89. 89. Formula Loaders
  90. 90. $loader = new FunctionCallsFormulaLoader(); $resource = new DirectoryResource( '/path/to/templates', '/.php$/' ); $formulae = $loader->load($resource);
  91. 91. $am = new LazyAssetManager($factory); $am->setLoader('php', $loader); $am->addResource($resource, 'php'); $writer = new AssetWriter('/path/to/web'); $writer->writeManagerAssets($am);
  92. 92. $am = new LazyAssetManager($factory); $am->setLoader('php', $loader); $am->addResource($resource, 'php'); Expensive every time $writer = new AssetWriter('/path/to/web'); $writer->writeManagerAssets($am);
  93. 93. $cache = new ConfigCache('/path/to/cache'); $loader = new CachedFormulaLoader( $loader, $cache, $debug );
  94. 94. Twig Integration
  95. 95. $twig->addExtension(new AsseticExtension($factory));
  96. 96. {% assetic 'js/*.coffee', filter='coffee' %} <script src="{{ asset_url }}"></script> {% endassetic %}
  97. 97. <script src="assets/92429d8"></script>
  98. 98. {% assetic 'js/*.coffee', filter='coffee' %} <script src="{{ asset_url }}"></script> {% endassetic %}
  99. 99. {% assetic 'js/*.coffee', filter='coffee', output='js/*.js' %} <script src="{{ asset_url }}"></script> {% endassetic %}
  100. 100. <script src="js/92429d8.js"></script>
  101. 101. {% assetic 'js/*.coffee', filter='coffee', output='js/*.js' %} <script src="{{ asset_url }}"></script> {% endassetic %}
  102. 102. {% assetic 'js/*.coffee', filter='coffee,?closure', output='js/*.js', name='core_js' %} <script src="{{ asset_url }}"></script> {% endassetic %}
  103. 103. AsseticBundle Symfony2 integration
  104. 104. {% assetic filter='scss,?yui_css', output='css/all.css', '@MainBundle/Resources/sass/main.scss', '@AnotherBundle/Resources/sass/more.scss' %} <link href="{{ asset_url }}" rel="stylesheet" /> {% endassetic %}
  105. 105. <link href="css/all.css" rel="stylesheet" />
  106. 106. {% assetic filter='scss,?yui_css', output='css/all.css', '@MainBundle/Resources/sass/main.scss', '@AnotherBundle/Resources/sass/more.scss' %} <link href="{{ asset_url }}" rel="stylesheet" /> {% endassetic %}
  107. 107. {% assetic filter='scss,?yui_css', output='css/all.css', '@MainBundle/Resources/sass/main.scss', debug=true, '@AnotherBundle/Resources/sass/more.scss' %} <link href="{{ asset_url }}" rel="stylesheet" /> {% endassetic %}
  108. 108. <link href="css/all_part1.css" rel="stylesheet" /> <link href="css/all_part2.css" rel="stylesheet" />
  109. 109. Each "leaf" asset is referenced individually <link href="css/all_part1.css" rel="stylesheet" /> <link href="css/all_part2.css" rel="stylesheet" />
  110. 110. Configuration
  111. 111. assetic: debug: %kernel.debug% use_controller: %kernel.debug% read_from: %kernel.root_dir%/../web write_to: s3://mybucket
  112. 112. {# when use_controller=true #} <script src="{{ path('assetic_foo') }}"...
  113. 113. # routing_dev.yml _assetic: resource: . type: assetic
  114. 114. {# when use_controller=false #} <script src="{{ asset('js/core.js') }}"></script>
  115. 115. {# when use_controller=false #} <script src="{{ asset('js/core.js') }}"></script> Lots for free
  116. 116. The Symfony2 Assets Helper • Multiple asset domains • Cache buster
  117. 117. framework: templating: assets_version: 1.2.3 assets_base_urls: - http://assets1.domain.com - http://assets2.domain.com - http://assets3.domain.com - http://assets4.domain.com
  118. 118. {% assetic filter='scss,?yui_css', output='css/all.css', '@MainBundle/Resources/sass/main.scss', '@AnotherBundle/Resources/sass/more.scss' %} <link href="{{ asset_url }}" rel="stylesheet" /> {% endassetic %}
  119. 119. <link href="http://assets3.domain.com/css/all.css?1.2.3" ...
  120. 120. assetic:dump
  121. 121. $ php app/console assetic:dump web/
  122. 122. $ php app/console assetic:dump s3://my-bucket
  123. 123. assetic:dump --watch Dump static assets in the background as you develop
  124. 124. Questions? http://github.com/kriswallsmith/assetic
  • TakashiMatsushita

    Jul. 10, 2014
  • byaur

    Feb. 27, 2014
  • WordpressDev

    Jan. 13, 2014
  • iambigd

    Jul. 29, 2013
  • userbiasa

    Jul. 22, 2013
  • akihito.koriyama

    Feb. 17, 2013
  • satooshi

    Jan. 31, 2013
  • pathstyle

    Jan. 13, 2013
  • elf2000

    Jan. 17, 2012
  • ninetails

    Nov. 18, 2011
  • dukeofgaming

    May. 29, 2011
  • linyows

    Mar. 4, 2011
  • chenphper

    Mar. 2, 2011
  • ivoaz

    Mar. 2, 2011

Views

Total views

7,993

On Slideshare

0

From embeds

0

Number of embeds

3,027

Actions

Downloads

44

Shares

0

Comments

0

Likes

14

×