Statistics from a fairly recent Comscore report show that mobile usage now represents 65 percent of all digital media time. Nonetheless mobile data plans still come with a steep price tag and are limited in data volume. At the same time modern web design for the last couple of years has been focussing on establishing a story telling approach, building brand worlds and delivering real life experiences online. This relies on an enormous amount of pictures, videos, sounds and graphics. Delivering as much high quality content as possible with the least of amount of data therefore seems to be more important than ever. Google has reacted early on by figuring in page load times as one of their many ranking factors.

Our front-end developer Marcin Krzemiński has taken the time and compiled some interesting statistics regarding file sizes and delivery times. He also shows in detail how the front-end team has optimized the performance of our Symfony based shop. They are also interesting for content sites using eZ Platform/eZ Enterprise.

Intro

As web developers we are responsible for delivering content fast, keeping in mind the balance between speed and quality of all the assets including text. As of June 2016 an average page size is 2.4 mB (2486 kB) which is quite a lot considering considering the above mentioned 65% digital media time and the still expensive mobile data plans.

  • HTML – 58 kB
  • CSS – 76 kB
  • Scripts – 402 kB
  • Fonts – 74 kB
  • Videos – 302 kB
  • Other – 11 kB
  • Images – 1522 kB (1.5MB!)

Source: http://httparchive.org/interesting.php?a=All&l=Jun%201%202016

Comparison of asset sizes over the last years

Jun 2015 – 2087 kB / http://httparchive.org/interesting.php?a=All&l=Jun%201%202015

  • HTML – 55 kB
  • CSS – 63 kB
  • Scripts – 334 kB
  • Fonts – 98 kB
  • Video – 208 kB
  • Other – 4 kB
  • Images – 1312 kB

Jun 2014 – 1783 kB / http://httparchive.org/interesting.php?a=All&l=Jun%201%202014

  • HTML – 56 kB
  • CSS – 51 kB
  • Scripts – 287 kB
  • Fonts – 62 kB
  • Other – 123 kB
  • Images – 1128 kb
all assets size in last 3 years

Average Page Size

assets size in last 3 years

Here’s a chart with last 3 years compared. As you can see every year amount of data per asset type is growing. No matter if it’s CSS, JavaScript and especially images. Look how big number is taken by images.

assets-size

Comparing those stats we can clearly see that as developers we write more CSS, JavaScript but the biggest numbers comes to images size which is about 200 kB bigger every year. These numbers show clearly how important performance optimisation is.

In order to improve performance there is a lot factors including:

  • compress (uglify) CSS and JavaScript files
  • concatenate (merge multiple into one) CSS and JavaScript files
  • reduce number of HTTP requests (CSS, JavaScript, images, Fonts, etc)
  • Gzip / deflate data over the wire
  • image optimisation

Performance optimisations for silver.eShop and eZ Platform/eZ Studio based sites

Assetic

Assetic helps us compress and concat CSS and JavaScript files. Using assetic is beneficial for reducing number of HTTP request as well as number of data that is transferred during request / response tango. Here’s how we keep it:

CSS
{% block stylesheets %}
 {% stylesheets
 'bundles/silversolutionseshop/css/style.css'
 %}
 {% endstylesheets %}
{% endblock %}

Note: We use Sass to manage our Stylesheets

JavaScript
{% block javascripts %}
 {% javascripts
 ...
 'bundles/silversolutionseshop/vendor/jquery-2.1.3.min/index.js'
 'bundles/silversolutionseshop/vendor/foundation/js/foundation/foundation.js'
 'bundles/silversolutionseshop/vendor/underscore/underscore.js'
 'bundles/silversolutionseshop/vendor/backbone/backbone.js'
 ...
 'bundles/silversolutionseshop/js/app.js'
 %}
 {% endjavascripts %}
{% endblock %}

In order to compress files we use some useful and well known NPM packages:

We keep those packages inside ezpublish/Resources/node_modules directory and here’s how our config_prod.yml file is configured:

assetic:
    filters:
        uglifycss:
            bin: '%kernel.root_dir%/Resources/node_modules/.bin/uglifycss'
            node: '%siso_eshop.nodejs%'
            apply_to: \.css$
        uglifyjs:
            bin: '%kernel.root_dir%/Resources/node_modules/.bin/uglifyjs'
            node: '%siso_eshop.nodejs%'
            apply_to: \.js$

As you may notice NPM has a dependancy of Node.js which also needs to be installed on the environment where our shop instance is running.

Related links:

Charts

Before / after assetic filters

Before and after assetic filters

Asset type Before After % saved
JavaScript 751 kB 486 kB ~35%
CSS 414 kB 325 kB ~22%

data excluding third party assets like Facebook, Olark chat, etc

Number of HTTP requests

Number of HTTP Requests saved using Assetic

For CSS number is the same since we use Sass. On the output we always have one CSS file. When it comes to JavaScript the difference is huge. Using assetic and server configuration properly we reduced number of HTTP request from 48 to 3 in production mode.

Sass and Gulp

This is not directly related to the performance topic but it’s worth to mention that we use Sass in order to keep our stylesheets nice and organised. Thanks to Gulp and some packages we are able to deliver well organised CSS including always up to date vendor prefixes.

Components driven front-end

When working on a complete redesign and rework of our front-end layer both technically and visually we had to take a lot of things into the consideration. On of them was if we should help ourselves and use one of the popular frameworks out there. We decided to go with ZURB’s Foundation for Sites which is really nice to work with. One of the nicest things about it is that we can create a custom build out of components we really need. Having this principal in mind we have extend a lot of Foundation’s components as well as created a bunch of our own which are missing. Thanks to this approach our standard design is divided into small components which is beneficial in terms of file size for client’s work. We can easily enable / disable a component when it’s required. This leads to smaller file size on the end which is beneficial from the performance perspective.

Headers

Each type of assets wheatear it’s an HTML file, JavaScript, CSS or image should have different expiration time. It means that over certain amount of time the asset should be taken from the server, not from browser cache. It can have huge impact on the site performance and that’s why it so important. For files that are not changed often you should set long expiration time. We recommend using longer expiration for files like images, fonts.

This is usually done in the VirtualHost configuration and may look like:

ExpiresActive On
ExpiresByType application/x-javascript "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-shockwave-flash "access plus 1 hour"
ExpiresByType application/shockwave-flash "access plus 1 hour"
ExpiresByType text/css "access plus 1 year"
<LocationMatch "^/var/[^/]+/storage/images/.*">
# eZ Publish appends the version number to image URL (ezimage
# datatype) so when an image is updated, its URL changes to
ExpiresActive on
ExpiresDefault "now plus 10 years"
...

Mod deflate

Apache configuration can be powered by a mode_deflate module which can be used to compress data using gzip compression before the data is send to the user. Having data compressed on the server means there is less data to transfer which results into faster page lead. Here’s how you can configure this in your Virtual Host:

AddOutputFilterByType DEFLATE text/css application/x-javascript application/javascript text/plain text/html text/xml application/xml

Using this approach we can gzip all CSS, JavaScript, HTML as well ass XML files.

Related reading:

Image optimisation

As mentioned at the beginning of this blog post images is the asset that is growing every year in terms of file size. That’s why it is super important to approach images topic the right way. In terms of project from front-end perspective there are two types of images.

First we have all static images like logo, favicon, spinners etc. To optimise these kind of images we use tools like ImageOptim (https://imageoptim.com/mac) or TinyPNG (https://tinypng.com/). If you’re not fan of these just Google for „optimise images“ or any similar search term and I bet you’ll find the right tool for your needs.

Second we have product photos. We tend to use a few image sizes for these files. In order not to load one huge file for each product or article we have couple of different configurations and serve proper files based on the view requirement. For example we might need different file for product list than for product detail page. Our team has developed and image converter tool that is using ImageMagick (http://www.imagemagick.org/script/index.php) and some .yml configuration. On top of it it’s important to set the quality for the output image. We suggest to set the quality between 60-75% in terms of JPEG compression.

Example of .yml configuration:

image_variations:
    thumb_smallest:
        reference: null
        filters:
            - { name: geometry/scalefillarea, params: [81, 61] }
            - { name: geometry/crop, params: [81, 61, 0, 0] }
    thumb_small:
        reference: null
        filters:
            - { name: resize/both, params: [150, 113] }
            - { name: background/white, params: [] }
            - { name: gravity/center, params: [] }
            - { name: extent, params: [150, 113] }
    image_zoom:
        reference: null
        filters:
            - { name: geometry/scaledownonly, params: [1600, 1200] }

Here’s how we use it in Twig:

<img src="/{{ st_imageconverter(product_image, 'thumb_small') }}" alt="Product name">

Conclusion

As an e-commerce platform manufacturer we feel responsible for delivering products that loads fast on every device. We make sure that mobile experience is as pleasant as desktop. In order to make it work as we expect we optimise performance on each layer: front-end, backend, server. Here’s what you should think about in terms front-end performance optimisation:

  • Reduce number of HTTP request by merging (concatenation) multiple files into one.
  • Reduce the number to bytes that are send over the wire by compressing files.
  • Optimise images for different views.
  • Enable gzip for CSS, JavaScript, HTML.
  • Set proper expiration time for files.
https://blog.silversolutions.de/wp-content/uploads/2016/07/racing-246134_1920-1024x768.jpghttps://blog.silversolutions.de/wp-content/uploads/2016/07/racing-246134_1920-150x150.jpgMarcin KrzemińskiB2B.praxisB2B.technologieHow-to,Javascript,Performance,Symfony,Tipps & TricksStatistics from a fairly recent Comscore report show that mobile usage now represents 65 percent of all digital media time. Nonetheless mobile data plans still come with a steep price tag and are limited in data volume. At the same time modern web design for the last couple of years has been...Die e-Commerce B2B Experten bloggen über Händler-Shops, ERP, PIM und das integrierte CMS eZ Publish