assetic (oscon)

Download Assetic (OSCON)

Post on 15-Jan-2015

2.036 views

Category:

Technology

2 download

Embed Size (px)

DESCRIPTION

 

TRANSCRIPT

  • 1. Introducing AsseticAsset Management for PHP 5.3Kris Wallsmith (OpenSky)July 29, 2011

2. @kriswallsmith Symfony Guru at Symfony core team member Doctrine contributor Author of Assetic 10+ years experience with PHP and web development Open source evangelist and international speaker 3. OpenSky connects you with innovators,trendsetters and tastemakers.You choose the ones you like and each week theyinvite you to their private online sales. 4. OpenSky connects you with innovators,trendsetters and tastemakers.You choose the ones you like and each week theyinvite you to their private online sales. 5. opensky.com PHP 5.3 + Symfony2 MongoDB + Doctrine MongoDB ODM MySQL + Doctrine2 ORM Less CSS jQuery 6. We all want to be FAST 7. We use good open source tools that encourage best practices 8. Best practices like Dependency injection (DI) Proper caching, edge side includes (ESI) Test-driven development (TDD) Dont repeat yourself (DRY) Keep it simple, SVP (KISS) Performance 9. If you havent optimized yourfrontend, you havent optimized 10. Get your assets in line. 11. A poorly optimized frontend can destroy UX 12. and SEO!http://googlewebmastercentral.blogspot.com/2010/04/using-site-speed-in-web-search-ranking.html 13. Asset Management 14. Lots of awesome tools: 15. Lots of awesome tools: CoffeeScript OptiPNG Compass Framework Packager CSSEmbed SASS & SCSS Google Closure Compiler Sprockets jpegoptim Stylus JSMin YUI Compressor LESS 16. Integrating these tools cleanly is a difcult problem 17. Assetic makes it easy 18. asceticismdescribes a lifestyle characterized by abstinence from various sorts of worldly pleasures often with the aim of pursuing religious and spiritual goals 19. No B.S. 20. Enough talk 21. # /path/to/web/js/core.php$core = new FileAsset(/path/to/jquery.js);$core->load();header(Content-Type: text/javascript);echo $core->dump(); 22. # /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(); 23. # /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 les into one == fewer HTTP requests Mergeheader(Content-Type: text/javascript);echo $core->dump(); 24. # /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(); 25. # /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 wireheader(Content-Type: text/javascript);echo $core->dump(); 26. 27. Assetic isAssets & Filters 28. Inspired by Pythons webassetshttps://github.com/miracle2k/webassets 29. Assets have lazy, mutable content 30. A lter acts on an assets contentsduring load and dump 31. Assets can be gathered in collections 32. A collection is an asset 33. Asset 34. FilterAsset 35. FilterFilterAsset 36. Load Filter Filter Asset 37. FilterFilterAsset Dump 38. FilterFilterAsset 39. Asset CollectionFilterFilterFilterFilterAsset Asset 40. Asset Collection Filter Filter Asset CollectionAssetFilterFilterFilterFilterAsset Asset Filter Filter Asset 41. # /path/to/web/css/styles.php$styles = new FileAsset(/path/to/main.sass, array(new SassFilter(),));header(Content-Type: text/css);echo $styles->dump(); 42. # /path/to/web/css/styles.php$styles = 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(); 43. # /path/to/web/css/styles.php$styles = 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(); 44. # /path/to/web/css/styles.php$styles = 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 lesystem isnt touched until nowheader(Content-Type: text/css);echo $styles->dump(); 45. Basic Asset Classes AssetCollection AssetReference FileAsset GlobAsset HttpAsset StringAsset 46. Core Filter Classes CoffeeScriptFilter GoogleClosureCompilerJarFilter CompassFilter JpegoptimFilter CssEmbedFilter JpegtranFilter CssImportFilter LessFilter CssMinFilter LessphpFilter CssRewriteFilter OptiPngFilter GoogleClosureCompilerApiFilter PackagerFilter 47. Core Filter Classes PngoutFilter More to come SassSassFilter SassScssFilter SprocketsFilter StylusFilter YuiCssCompressorFilter YuiJsCompressorFilter 48. Asset Manager 49. $am = new AssetManager();$am->set(jquery,new FileAsset(/path/to/jquery.js)); 50. $plugin = new AssetCollection(array(new AssetReference($am, jquery),new FileAsset(/path/to/jquery.plugin.js),)); 51. $core = new AssetCollection(array($jquery,$plugin1,$plugin2,));header(text/javascript);echo $core->dump(); 52. jQuery will only be included once $core = new AssetCollection(array( $jquery, $plugin1, $plugin2, )); header(text/javascript); echo $core->dump(); 53. Filter Manager 54. $yui = new YuiCompressorJs();$yui->setNomunge(true);$fm = new FilterManager();$fm->set(yui_js, $yui); 55. $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)); 56. 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)); 57. Asset Factory 58. $fm = new FilterManager();$fm->set(coffee, new CoffeeScriptFilter());$fm->set(closure, new ClosureFilter());$factory = new AssetFactory(/path/to/web);$factory->setFilterManager($fm); 59. $asset = $factory->createAsset(array(js/src/*.coffee),array(coffee, closure));header(Content-Type: text/javascript);echo $asset->dump(); 60. Debug Mode 61. Debugging compressed Javascript sucks 62. Mark lters for omissionin debug mode using a ? 63. // new AssetFactory(/path/to/web, $debug = true);$asset = $factory->createAsset(array(js/src/*.coffee),array(coffee, closure));header(Content-Type: text/javascript);echo $asset->dump(); 64. // new AssetFactory(/path/to/web, true);$asset = $factory->createAsset(array(js/src/*.coffee),array(coffee, ?closure));header(Content-Type: text/javascript);echo $asset->dump(); 65. // new AssetFactory(/path/to/web, false);$asset = $factory->createAsset(array(js/src/*.coffee),array(coffee, ?closure),array(debug => true));header(Content-Type: text/javascript);echo $asset->dump(); 66. Good: Basic Caching 67. # /path/to/web/css/styles.php$styles = new AssetCollection(array(new FileAsset(/path/to/main.sass)),array(new SassFilter()));echo $styles->dump(); 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. # /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 lters once and cache the contentecho $styles->dump(); 70. Better: HTTP Caching 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. Best: Static Assets 73. # /path/to/deploy/scripts/dump_assets.php$am = new AssetManager();$am->set(foo, $foo);// etc...$writer = new AssetWriter(/path/to/web);$writer->writeManagerAssets($am); 74. Best-est:Content Distribution Network 75. new AssetWriter(s3://my-bucket) 76. new AssetWriter(s3://my-bucket) A CloudFront S3 bucket 77. Custom Stream Wrappers$s3 = new Zend_Service_Amazon_S3($key, $secret);$s3->registerStreamWrapper(); 78. Not Lazy Enough? 79. Asset Formulae and the Lazy Asset Manager 80. $asset = $factory->createAsset(array(js/src/*.coffee),array(coffee, ?closure),array(output => js/all.js)); 81. $formula = array(array(js/src/*.coffee),array(coffee, ?closure),array(output => js/all.js)); 82. $am = new LazyAssetManager($factory);$am->setFormula(all_js, $formula);header(Content-Type: text/javascript);echo $am->get(all_js)->dump(); 83. A ThoughtAssets are a part of the view layerand should be dened there. 84. 85. An IssueAssets dened in the view layermust actually exist somewhere 86. Option Number BadLazily dump assets to theweb directory 87. Option Number GoodEagerly dump assets to theweb directory 88. A template is a conguration le 89. Formula Loadersextract asset formulae from templates 90. $loader = new FunctionCallsFormulaLoader();$resource = new DirectoryResource(/path/to/templates,/.php$/);$formulae = $loader->load($resource); 91. $am = new LazyAssetManager($factory);$am->setLoader(php, $loader);$am->addResource($resource, php);$writer = new AssetWriter(/path/to/web);$writer->writeManagerAssets($am); 92. $am = new LazyAssetManager($factory);$am->setLoader(php, $loader);$am->addResource($resource, php