Drupalcamp performance
Upcoming SlideShare
Loading in...5

Drupalcamp performance



What Would Lucky Luke Code?

What Would Lucky Luke Code?

A walkthrough of the tools and tricks we use to maximize performance when building Drupal sites, both backend and frontend



Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

Drupalcamp performance Drupalcamp performance Presentation Transcript

  • WWLLC What Would Lucky Luke Code? Create Drupal sites with good performance
  • Henrik Developer Mostly backend @FrontHenrik
  • Frank Web designer Mostly front-end @fragje View slide
  • The frontkom family Per André Rønsen Marco Fernandes CIO/Chief Innovation Officer Senior Web developer Fredrik Paus Élio Cró Jan-Helge Hansen COO/Project Manager Web Developer Infrastructure / support Thor André Gretland Roberto Ornelas Support & Training CTO Senior developer Fábio Neves Geir Gulland Hélder Mendes Bruno Campos CEO / Web strategist Web Designer Web developer Frank Gjertsen Elisabeth Gulland Wilma Web Designer Accountant QA Engineer ;) Henrik Akselsen JS/Mobile UX Web developer View slide
  • Fredrikstad | Madeira
  • Agenda ● ● ● ● ● ● Why performance? Analysis Frontend Server configuration Backend Your inputs
  • Why performance now? ● We got fast internet connections ● Powerful computers ● Shiny large screens …but wait, we got mobile. …and bad mobile connections. …and emerging markets which are mobile only.
  • Web pages are getting FAT 1.5MB Expect to increase by 21% the next year ● Today the average page is ● ● Oakley released their new site. 80MB
  • When to start? ● Post-optimization is the root of all evil ● Lack of performance = Lack of planning ● Bad performance is bad business ● ● ● ● We need our clients interest in performance Show visually how a page loads Make a performance budget Plan performance from the beginning
  • We need to analyze this
  • “Yeah, it’s slow, but it’s probably just [insert wild speculation here]”
  • Hold your assumptions ● A lot of the time your assumption will be wrong and cause a lot of wasted effort ● Let the data guide the optimizing process ● Use the 80/20 rule => find low hanging fruit
  • Tools ● ● ● ● Web developer tools in your browsers PageSpeed (Google) Yslow (Yahoo) Quicksprout http://www.quicksprout.com/ ● WebPageTest http://www.webpagetest.org/
  • Indepth analysis Chrome Dev Tools XHProf (Backend) Frontend Introduction to dev tools http://bit.ly/discover-devtools Find out which functions that are using memory and processor time “The Breakpoint” Paul Irish / Addy Osmani
  • Mobile first
  • Mobile first ● Start small. Add style and content as you get more space, without limiting the user experience. http://bradfrostweb.com/demo/mobile-first ● Build systems instead of individual pages ● Write reusable code
  • Mobile first ● ● ● ● Download as few MB as possible Reduce requested files. Images, css, js. Concatenate and minify css and js Make sprites ○ Compass does this in a smart way… ● Or use icon fonts ○ http://iconmoon.io ○ or even better http://fontastic.me
  • HTML ● Take control over your markup ● Customize markup in your tpl.php ● Find design patterns and add classes to similar elements. ● In views it can be customized directly, on other output use template.php
  • <section class="panel-pane paneviews-panes pane-commons-featuredpanel-pane-1 block">...</section> <section class="panel-pane paneviews-panes pane-commons-activitystreams-activity-panel-pane-1 block">...</section>
  • function theme_preprocess_panels_pane(&$vars) { switch ($vars['pane']->pid) { case '14': $vars['classes_array'][] = 'box-default'; break; case '8': $vars['classes_array'] = array('box-default'); break; } }
  • <section class="panel-pane paneviews-panes pane-commons-featuredpanel-pane-1 block box-default"> ... </section> <section class="box-default"> ... </section>
  • Useful gh-repo http://bit.ly/template-php by Jesper Wøldiche Rahkonen
  • Clean markup ● Modules ○ Clean Markup - Blocks, Panel panes, Panel regions, Panel layouts https://drupal.org/project/clean_markup ○ Fences - clean fields markup globaly. https://drupal.org/project/fences
  • Default fields markup <div class="field field-name-field-test field-type-text field-label-above"> <div class="field-label">Foobar field: &nbsp;</div> <div class="field-items"> <div class="field-item even">Drupal default fields markup.</div> </div> </div>
  • After fences config <h3 class="field-label">Foobar field</h3> <div class="field-foobar">Leaner markup means better front-end performance. </div>
  • Clean markup ● Modules ○ Clean Markup - Blocks, Panel panes, Panel regions, Panel layouts https://drupal.org/project/clean_markup ○ Fences - clean fields markup globaly. https://drupal.org/project/fences ● Themes ○ Mothership https://drupal.org/project/mothership ○ Aurora https://drupal.org/project/aurora
  • CSS ● Write as little as possible ● Use classes instad of tags ○ ul li a {} ○ .nav-main .nav-item {} ○ http://bit.ly/quick-selectors ● Css can get out of control and hard to manage when a page scales
  • .btn-default, .btn-cta { text-align: center; display: inline-block; background-color: gray; padding: 5px 10px; color: white; } .btn-cta { background-color: dodgerblue; }
  • SMACSS ● A must read for all working with css ● Part of the book is available online for free http://smacss.com
  • http://pattern-lab.info by Brad Frost
  • Preprocess that CSS ● LESS ● Stylus ● Sass ○ ○ ○ ○ WARNING! Compass - Sass mixins library and much more Breakpoint - Really Simple Media Queries with Sass Toolkit - swiss army knife for PE and RWD Singularity - Grids withoutyour output Always check limits
  • .btn-default { text-align: center; display: inline-block; background-color: gray; padding: 5px 10px; color: white; } .btn-cta { @extend .btn-default; background-color: dodgerblue; }
  • .btn-default, .btn-cta { text-align: center; display: inline-block; background-color: gray; padding: 5px 10px; color: white; } .btn-cta { background-color: dodgerblue; }
  • Javascript ● Don’t load js before css ● Don’t load libraries you don’t need, and if possible make custom builds to your needs. E.g. Modernizr. ● Try to move most of your js at the bottom of your page, just before </body>. There is a special Drupal module for this. ● Avoid unnecessary dom manipulations
  • MAGIC https://drupal.org/project/magic
  • Avoid calculations in loops var div = document.getElementById("to-measure"), lis = document.getElementsByTagName('li'), i, len; for (i = 0, len = lis.length; i < len; i++) { lis[i].style.width = div.offsetWidth + 'px'; }
  • Improve Perceived performance ● Edge side includes ● Image lazy loading
  • Configuration Tweak it up
  • Hosting ● Geography - Closer is better. ○ (Sorry New Zealand) ● SSD is awesome ● Quick and good support ○ (Sorry New Zealand) ● Consider dedicated Drupal hosting ○ Fx Pantheon (has great workflow)
  • PHP & MySQL PHP version: newer is better InnoDB > Myisam
  • APC - Opcode cache - Easy setup, huge performance win - See https://drupal.org/node/1777090 for configuration tips for Drupal - Remember to assign enough memory, or the cache will not have any effect
  • Memcache(d) Improves editor experience + faster site building Memcache module not needed, just include in settings.php Alternative: Redis
  • // the path to the core cache file include_once('./includes/cache.inc'); // the path to the memcache cache file include_once ('./sites/all/modules/contrib/memcache/memcache.inc'); // make MemCacheDrupal the default cache class $conf['cache_default_class'] = 'MemCacheDrupal'; $conf['memcache_servers'] = array('' => 'default'); $conf['memcache_bins'] = array('cache' => 'default'); $conf['memcache_key_prefix'] = 'mysite';
  • First time using memcache
  • Varnish Boost (poor man’s Varnish) Gzip
  • High performance with cloud ● CDN ● Amazon AWS for static files and images ● Web Application Streaming ○ new tech, possible “CDN killer”) ○ from InstartLogic
  • Drupal
  • Good places to hang out ● high performance group on d.o ● Contrib modules
  • Module strategy ● As few modules as possible ○ Avoid the buffet syndrome ● Check which hooks are used. ○ hook_init() is more important to watch than hook_openid_normalization_method_info_alter() ● Preferred: Measure before/after install ○ Dive into xhprof ○ Disable suspected performance hogs
  • Module strategy ● Check that page cache is not being disabled ○ ○ ○ ○ ○ drupal_page_is_cacheable(FALSE); $GLOBALS['conf']['cache'] = 0; $GLOBALS['conf']['cache'] = CACHE_DISABLED; $conf['cache'] = FALSE; flags module, captcha module (This may have to be necessary, but at least know that it is happening)
  • Watch the Logs ● Keep an eye on the dblogs ● May slow down disk if constantly logging errors ● May point to underlying errors ● Bad Karma ● Tip: Get sent an email on each log error
  • Cache ● ● ● ● Views Cache! PHP blocks breaks cache D7: contrib provides a lot D8: Much more flexible out of the box ○ pluggable CSS and JavaScript optimization ○ personalize through JavaScript ○ Entity Cache
  • Be kind to the theme layer ● Avoid logic in the theme layer ○ hurts page cache ● Avoid heavy processes in the theme layer ○ node_load ○ sql queries ● Tip: Switch to another theme and do performance tests again
  • Views queries
  • Find candidates for optimizing [mysqld] log_slow_queries=/Applications/MAMP/logs/mys ql_sql_slow.log long_query_time=0.5 LOTS OF JOINS SELECT * FROM mother_of_all_huge_tables
  • Optimize Views Queries Battle plan: Find JOINS and see if you can do the same within SELECT Tip: use EXPLAIN on views sql How many evaluations
  • No JOIN select nid FROM node; 200005 rows in set (0.08 sec) Data from astonishdesign.com
  • 1 JOIN select n.nid, s. field_school_name_format FROM node n LEFT JOIN field_data_field_school_name s ON n.nid = s.entity_id; 200005 rows in set (1.09 sec)
  • 2 JOINS select n.nid, s.field_school_name_format, si.field_school_id_value FROM node n LEFT JOIN field_data_field_school_name s ON n.nid = s.entity_id LEFT JOIN field_data_field_school_id si on n.nid = si.entity_id; 200005 rows in set (2.03 sec)
  • 3 JOINS select n.nid, s.field_school_name_format, si. field_school_id_value, sp.field_school_phone_value FROM node n LEFT JOIN field_data_field_school_name s ON n.nid = s. entity_id LEFT JOIN field_data_field_school_id si on n.nid = si. entity_id LEFT JOIN field_data_field_school_phone sp on n.nid = sp. entity_id; 200005 rows in set ( 5.03 sec)
  • Optimize Views Queries ● Optimize in hook_views_query_alter() and hook_view_query_substitutions() ● Consider making views into a module ○ Easier to optimize + easier version control
  • Specific use cases ● Defer heavy tasks ○ Push heavy tasks to cron ○ Batch API ● Fast 404
  • Good PHP habits http://www.phpbench.com/
  • Stats Performance module New Relic Load testing with jMeter (+Blazemeter)
  • Bring out the big guns ● Ditch the theme layer ● Example: NewsFront
  • Now it’s your turn ;-)