On Github shaekuronen / building-performant-expressionengine-sites
For e-commerce sites, a .1 second increase will decrease conversions by 1%. A 1 second increase will reduce conversions by 15%. A 5 second increase will reduce conversions by 75%.
AutoMin is an ExpressionEngine module and extension that automates the combination and compression of your source files and currently supports CSS, JavaScript, LESS, and HTML compression.
<!-- HEAD --> <!-- css --> {exp:automin:css attribute:rel="stylesheet" } <!-- reset --> <link rel="stylesheet" href="/assets/css/vendor/reset/base.css"> <!-- end reset --> <!-- vendor --> <link rel="stylesheet" href="/assets/css/vendor/flexslider.css"> <!-- end vendor --> <!-- site --> <link rel="stylesheet" href="/assets/css/site/global/globals.css"> <link rel="stylesheet" href="/assets/css/site/global/header.css"> <link rel="stylesheet" href="/assets/css/site/global/footer.css"> <link rel="stylesheet" href="/assets/css/site/global/hero_image.css"> <link rel="stylesheet" href="/assets/css/site/global/callouts.css"> <link rel="stylesheet" href="/assets/css/site/global/featured_games.css"> <link rel="stylesheet" href="/assets/css/site/global/flip_animation.css"> <link rel="stylesheet" href="/assets/css/site/global/diagonal_lines_bg.css"> <link rel="stylesheet" href="/assets/css/site/pages/home.css"> <link rel="stylesheet" href="/assets/css/site/pages/team.css"> <link rel="stylesheet" href="/assets/css/site/pages/games.css"> <link rel="stylesheet" href="/assets/css/site/pages/careers.css"> <link rel="stylesheet" href="/assets/css/site/pages/press.css"> <link rel="stylesheet" href="/assets/css/site/pages/santa.css"> <!-- end site --> <!-- responsive --> <link rel="stylesheet" href="/assets/css/site/responsive/skeleton.css"> <link rel="stylesheet" href="/assets/css/site/responsive/0_500px.css"> <link rel="stylesheet" href="/assets/css/site/responsive/500_750px.css"> <link rel="stylesheet" href="/assets/css/site/responsive/750_1000px.css"> <link rel="stylesheet" href="/assets/css/site/responsive/1000_1250px.css"> <link rel="stylesheet" href="/assets/css/site/responsive/1250_infinity.css"> <link rel="stylesheet" href="/assets/css/site/responsive/retina_display.css"> <!-- end responsive --> {/exp:automin:css} <!-- end css --> <!-- END HEAD --> <!-- FOOTER --> <!-- js --> {exp:automin:js} <!-- vendor --> <script type="text/javascript" src="/assets/js/vendor/jquery-1.10.1.min.js"></script> <script type="text/javascript" src="/assets/js/vendor/jquery-migrate-1.2.1.min.js"></script> <script type="text/javascript" src="/assets/js/vendor/jquery.flexslider-min.js"></script> <script type="text/javascript" src="/assets/js/vendor/matchMedia.js"></script> <script type="text/javascript" src="/assets/js/vendor/picturefill.js"></script> <script type="text/javascript" src="/assets/js/vendor/jquery.lazyload.js"></script> <script type="text/javascript" src="/assets/js/vendor/prevent_console_errors.js"></script> <script type="text/javascript" src="/assets/js/vendor/ios-orientationchange-fix.js"></script> <!-- end vendor --> <!-- site --> <script type="text/javascript" src="/assets/js/site/global_object.js"></script> <script type="text/javascript" src="/assets/js/site/lazyload_init.js"></script> <script type="text/javascript" src="/assets/js/site/thought_bubbles.js"></script> <script type="text/javascript" src="/assets/js/site/flexslider_init.js"></script> <script type="text/javascript" src="/assets/js/site/header_nav_mobile.js"></script> <script type="text/javascript" src="/assets/js/site/featured_games.js"></script> <script type="text/javascript" src="/assets/js/site/nav_hover.js"></script> <script type="text/javascript" src="/assets/js/site/remove_empty_text_nodes.js"></script> <script type="text/javascript" src="/assets/js/site/scroll_to_element.js"></script> <script type="text/javascript" src="/assets/js/site/modal.js"></script> <script type="text/javascript" src="/assets/js/site/vertically_center.js"></script> <!-- end site --> {/exp:automin:js} <!-- page specific js --> {if embed:page_specific_js} {embed:page_specific_js} {/if} <!-- end page specific js --> <!-- end js --> <!-- END FOOTER --> <!-- LAYOUT --> {embed="globals/head" page_body_class="page-careers" } {embed="globals/header"} {embed="globals/hero_image"} {embed="careers/callout1"} {embed="careers/benefits_and_perks"} {embed="careers/open_positions"} {embed="globals/footer"} {embed="globals/scripts" page_specific_js='<script type="text/javascript" src="path/to/file.js"></script>' } {embed="globals/foot"}
<!-- HEAD --> <link href="/assets/cache/94c0ef419b3fbad19c8228a5c90d54cc.css?modified=1385405187" rel="stylesheet"> <!-- END HEAD --> <!-- FOOTER --> <script src="/assets/cache/600f856bb79d1db6ada3688551fb830f.js?modified=1372887497"></script> <!-- END FOOTER -->
Picturefill allows you to specify different src attributes for an image, each image file corresponding to a different media query. Thus a large image will be fetched if – and only if – the screen size requires it, and likewise a mobile-optimised version of an image will be fetched and displayed as appropriate.
<!-- hero image --> <div class="hero-image-wrapper"> <div class="container"> {exp:channel:entries channel="hero_images" search:hero_image_page_visibility="{segment_1}" limit="1" disable="categories|category_fields|member_data|pagination" dynamic="no" } <a href="{hero_image_url}" class="hero-image-link"> <!-- responsive images using picturefill.js --> <span data-picture="" data-alt="" class="hero-image"> <!-- for browsers that don't support media queries fallback to full size image --> <span class="hero-image" data-src="{hero_image:1000px}"></span> <!-- end for browsers that don't support media queries fallback to full size image --> <span class="hero-image" data-src="{hero_image:500px}" data-media="(max-width: 499px)"></span> <span class="hero-image" data-src="{hero_image:750px}" data-media="(min-width: 500px) and (max-width: 749px)"></span> <span class="hero-image" data-src="{hero_image:1000px}" data-media="(min-width: 750px)"></span> <!-- fallback for non-js browsers --> <noscript> <img src="{hero_image:thumbs}" alt=""> </noscript> <!-- end fallback for non-js browsers --> </span> <!-- end responsive images using picturefill.js --> </a> {/exp:channel:entries} </div> </div> <!-- end hero image -->
<div class="hero-image-wrapper"> <div class="container"> <a href="/careers" class="hero-image-link"> <span data-picture="" data-alt="" class="hero-image"> <span class="hero-image" data-src="http://www.example.com/images/uploads/hero_images/_1000px/image.jpg"></span> <span class="hero-image" data-src="http://www.example.com/images/uploads/hero_images/_500px/image.jpg" data-media="(max-width: 499px)"></span> <span class="hero-image" data-src="http://www.example.com/images/uploads/hero_images/_750px/image.jpg" data-media="(min-width: 500px) and (max-width: 749px)"></span> <span class="hero-image" data-src="http://www.example.com/images/uploads/hero_images/_1000px/image.jpg" data-media="(min-width: 750px)"> <img alt="" src="http://www.example.com/images/uploads/hero_images/_1000px/image.jpg"> </span> <noscript><img src="http://www.example.com/images/uploads/hero_images/_thumbs/image.jpg" alt=""></noscript> </span> </a> </div> </div>
Lazy Load delays loading of images in long web pages. Images outside of viewport will not be loaded before user scrolls to them.
Using Lazy Load on long web pages containing many large images makes the page load faster. Browser will be in ready state after loading visible images.
<!-- callout1 --> <div class="callout-copy-left-image-right gradient-border"> {exp:channel:entries channel="callouts" url_title="games-page-callout-1" disable="categories|category_fields|member_data|pagination" dynamic="no" } <div class="container"> <div class="two-thirds column"> <h1>{callout_heading}</h1> <p>{callout_body_copy}</p> </div> <div class="callout-image one-third column"> <a href="{callout_link_url}" target="_blank"> <img class="lazyload" src="/assets/img/global/lazyload/transparent.gif" data-original="{callout_image}" width="280" height="280"> </a> </div> </div> {/exp:channel:entries} </div> <!-- end callout1 -->
<div class="callout-copy-left-image-right gradient-border"> <div class="container"> <div class="two-thirds column"> <h1>Cosby sweater American Apparel</h1> <p>Cray craft beer sint, in keytar gluten-free PBR&B flannel blog stumptown. Trust fund VHS leggings mumblecore swag McSweeney's post-ironic, Brooklyn Shoreditch quis sartorial. Dolore meggings plaid, blog Vice accusamus forage dolor trust fund cornhole squid.</p> </div> <div class="callout-image one-third column"> <a href="http://www.example.com" target="_blank"> <img class="lazyload" src="http://www.example.com/images/uploads/image.png" data-original="http://www.example.com/images/uploads/image.png" width="280" height="280" style="display: inline;"> </a> </div> </div> </div>
CE Cache allows you to store and retrieve parts of your templates (fragment caching) so they don’t have to be run each time the page is loaded. Since much of the heavy lifting doesn’t have to be run on each page-load, your performance increases can be astonishing.
CE Cache also supports full-page (static) caching. The static driver, which caches entire pages, uses a combination of file-based caching and .htaccess magic to serve your pages. This allows the cached files to completely circumvent ExpressionEngine®, and to render very quickly.
<ifmodule mod_rewrite.c=""> RewriteEngine On #------------------- remove trailing slash ------------------- RewriteCond %{REQUEST_URI} !^/system [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+)/$ /$1 [R=301,L,QSA] #------------------- index.php ------------------- #strip index.php from the URL if that is all that is given RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.php\ HTTP/ RewriteRule ^(([^/]+/)*)index\.php$ http://%{HTTP_HOST}/ [R=301,NS,L,QSA] #strip index.php/* from the URL RewriteCond %{THE_REQUEST} ^[^/]*/index\.php/ [NC] RewriteRule ^index\.php/(.+) http://%{HTTP_HOST}/$1 [R=301,L,QSA] #------------------- CE Cache Static Driver ------------------- RewriteCond %{REQUEST_URI} !^/system [NC] RewriteCond %{QUERY_STRING} !ACT|URL [NC] RewriteCond %{REQUEST_METHOD} !=POST [NC] RewriteCond %{DOCUMENT_ROOT}/static/ce_cache/e24b65/static%{REQUEST_URI}/index\.html -f RewriteRule (.*) /_static_cache_handler.php%{REQUEST_URI}/index\.html [L,QSA] #------------------- EE ------------------- #rewrite all non-image/js/css urls back to index.php if they are not files or directories RewriteCond $1 !\.(css|js|gif|jpe?g|png) [NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.php/$1 [L,QSA] </ifmodule>
$config['ce_cache_static_enabled'] = 'yes'; $config['ce_cache_static_path'] = '/path/to/web/content/static'; $config['ce_cache_seconds'] = 0;
Ilya Grigorik
Jakob Nielsen
Jatinder Mann, W3C Web Performance Working Group
Lukas White