Any Magento 2 page requested from a browser is processed by a web server. Magento 2 loads 170 scripts per page on average. All incoming requests add an additional load for a server CPU and Memory. As a result, it increases infrastructure costs to maintain an acceptable level of page load time.

I’ve installed Magento 2.2.0 release with a sample data in order to get a number of requests processed. The following table shows the number of static and media files and the size requested on the different Magento 2 pages.

Page Number of Requests Size, KB
Homepage 164 968.91
Category Page 173 764.81
Product Page (Configurable) 180 850.05
CMS Page (Contact Us) 157 671.39


There are different content delivery network services available on the market. Such services speed up content distribution across the world faster edge locations available to distribute the content to different pricing options. This tutorial is based on the AWS CloudFront service.

AWS CloudFront

As I am a big fan of AWS services, my attention for the last couple of years has been attracting by the AWS CloudFront. In order to use AWS CloudFront you should have an AWS Account. In case you don’t have the AWS Account, read the How do I create and activate a new Amazon Web Services account?

Once you are logged into the AWS Console, open Services tab and type “CloudFront”. Select CloudFront Global Content Delivery Network suggestion from the popup.

AWS Console

On the AWS CloudFront Distributions page we are going to create our first distribution location for Magento static files. Click a Create Distribution button to create a web distribution. There are 2 steps involved into the creation. First step gives us 2 delivery method options: Web and RTMP. Click a Get Started button under Web delivery method.

Choose a Web distribution

Static Content Distribution

On the Create Distribution page we have to set the distribution for static files. There are a set of required settings needed to be provided in order to create the static content distribution. Some settings should not be changed. Below is a list of recommended settings to be used for this tutorial.

Setting Value
Origin Domain Name magento22.pronkoconsulting.com
Origin Path /static
Origin ID static-magento22.pronkoconsulting.com
Origin Protocol Policy HTTPS Only
Viewer Protocol Policy Redirect HTTP to HTTPS
Allowed HTTP Methods GET, HEAD, OPTIONS
Cached HTTP Methods GET, HEAD, OPTIONS
Cache Based on Selected Request Headers Whitelist
Whitelist Headers Accept, Host, Origin
Price Class Use Only US, Canada, Europe
SSL Certificate Default CloudFront Certificate (*.cloudfront.net)
Distributed State Enabled


As you can see the Origin Protocol Policy and Viewer Protocol Policy settings are set to HTTPS only because the magento22.pronkoconsulting.com domain is configured to use a secure connection. In case you have the non-secure connection configured make sure to set these settings to HTTP.

Please also note the Price Class setting is set to Use Only US, Canada, Europe. It gives the great distribution coverage and a lower pricing for AWS CloudFront usage.

For the Whitelist Headers setting select the Accept, Host, and Origin values as it is shown below.

AWS Whitelist Headers

Once all settings are provided for the static distribution, click a Create Distribution button.

The OPTIONS HTTP method is used for the Fonts, HTML templates files requested from the JavaScript files.

It takes about 15 minutes for the AWS CloudFront to create the new Distribution.

AWS CloudFont created a new Distribution

After the distribution has been successfully created the Magento 2 static files should be accessible via the new CloudFront distribution.

“Static” part is not provided

Media Content Distribution

Same steps should be performed to create the distribution for Magento 2 media files. From the AWS CloudFront Distributions page click the “Create Distribution” button, then “Get Started” under a Web delivery method.

Setting Value
Origin Domain Name magento22.pronkoconsulting.com
Origin Path /media
Origin ID media-magento22.pronkoconsulting.com
Origin Protocol Policy HTTPS Only
Viewer Protocol Policy Redirect HTTP to HTTPS
Allowed HTTP Methods GET, HEAD
Cached HTTP Methods GET, HEAD
Cache Based on Selected Request Headers None
Price Class Use Only US, Canada, Europe
SSL Certificate Default CloudFront Certificate (*.cloudfront.net)
Distributed State Enabled


Once all settings are provided for the static distribution, click the Create Distribution button. As a result, the 2 distributions should be listed on the AWS CloudFront Distributions page.

Static and Media distributions in AWS CloudFront

Media files should be accessible via the new CloudFront Distribution.

Media files are accessible

Apache Configuration

For the content delivery network service Magento 2 should send proper response headersto allow requests for static and media files from different domains. Before the new AWS CloudFront Distributions can be used together with Magento 2, additional Apache instructions should be provided.

Without additional response headers it leads to the Access-Control-Allow-Origin error for all static and media files requested from the AWS CloudFront or other content delivery network.

Access-Control-Allow-Origin error for all static and media files

Apache Headers Module

Apache headers module should be enabled to use mod_headers module in .htaccess files.
To enable the Apache headers module, enter the following command (Ubuntu):

$ a2enmod rewrite

Restart Apache (Ubuntu):

$ service apache2 restart

The pub/static Instructions

The pub/static/.htaccess file provides default response headers for the static files. These headers should be adjusted to allow requests from other domains.
The pub/static/.htaccess before:


<IfModule mod_headers.c>
   <FilesMatch .*\.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$>
       Header append Cache-Control public
   </FilesMatch>

   <FilesMatch .*\.(zip|gz|gzip|bz2|csv|xml)$>
       Header append Cache-Control no-store
   </FilesMatch>
</IfModule>

The pub/static/.htaccess after changes:


<IfModule mod_headers.c>
<FilesMatch .*\.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|html|json)$>
   Header set Cache-Control "max-age=604800, public"
   Header set Access-Control-Allow-Origin "*"
   Header set Access-Control-Allow-Methods "GET, OPTIONS"
   Header set Access-Control-Max-Age "604800"
   Header set Access-Control-Allow-Headers "Host, Content-Type, Origin, Accept"
</FilesMatch>

   <FilesMatch .*\.(zip|gz|gzip|bz2|csv|xml)$>
       Header append Cache-Control no-store
   </FilesMatch>
</IfModule>

Note that the file extensions list in the FilesMatch section has been modified and 2 additional extensions are added: html and json. As for the html extension, the Catalog Store settings should be revisited due to a .html URL suffix usage for Products and Categories.

The pub/media Instructions

The pub/media/.htaccess file should also include response headers for images.
The mod_headers.c section from the pub/media/.htaccess before:


<IfModule mod_headers.c>
   <FilesMatch .*\.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$>
       Header append Cache-Control public
   </FilesMatch>

   <FilesMatch .*\.(zip|gz|gzip|bz2|csv|xml)$>
       Header append Cache-Control no-store
   </FilesMatch>
</IfModule>

The mod_headers.c section from the pub/media/.htaccess after:


<FilesMatch .*\.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$>
   Header append Cache-Control max-age=604800
   Header set Access-Control-Allow-Origin "*"
</FilesMatch>

After both .htaccess files are updated with additional response headers Magento 2 is ready to serve static and media files from an alternative distributions.

Magento 2 Configuration

Magento 2 has additional configuration settings to control static and media URLs. Navigate to the Magento Admin -> Stores -> Configuration page. From the Configuration page select General -> Web -> Base URLs (Secure) section.

AWS CLoudFront - Magento 2 Configuration

In case you have multiple stores, change the Store View so the configuration changes will affect the specific store.

AWS CloudFront configuration for multiple store view on Magento 2

Add AWS CloudFront URLs to the Secure Base URL for Static View Files and the Secure Base URL for User Media Files as it is shown below.

Add AWS CloudFront URLs

Click a Save Config button to make changes in the configuration. Navigate to the System -> Cache Management page and refresh the Configuration and Page Cache cache types.

Navigate to Magento 2 frontend and observe domain names changes of the static and media files.

Magento 2 Frontend with AWS CloudFront domains

Magento 2 website has been configured to use CDN for media and static files.

CNAME for CDN

If you would like to have friendly URLs for the CloudFront distributions the CNAME records should be configured for AWS CloudFront. CNAME records creation should not take much time to configure as part of your Domain provider.

As for domain names I prefer to have the following names:

  • static.magento22.pronkoconsulting.com points to d2m7s9s7o7k75u.cloudfront.net
  • media.magento22.pronkoconsulting.com points to d3id53ssc4jfal.cloudfront.net

AWS CloudFront Changes

New CNAME record should be added to the AWS CloudFront Distribution. From the AWS CloudFront Distributions list click on the distribution and supply with the Alternative Domain Names (CNAMEs). Also, select a Custom SSL Certificate for the SSL Certificate settings.

Edit distribution settings

You may need to create new the SSL Certificate for the custom domain. The AWS Certificate Manager allows to create SSL Certificate in a couple of minutes. Click a Yes, Edit button to save changes. It may take up to 15 minutes for changes to be propagated for the distribution.

Magento 2 Configuration Changes

With the new friendly domain names for static and media URLs Magento 2 configuration can be adjusted. Navigate to the Navigate to the Magento Admin -> Stores -> Configuration page and update URLs as it shown below.

Adjust AWS CloduFront configuration settings

Once you performed necessary changes the domain names should be changed on the Magento 2 frontend.

Applied changed on Magento 2 frontend

Performance Results

The performance metrics are based on the built-in Full Page Cache. Page Load Time metrics has been taken from Pingdom. The page load time includes rendering of all scripts loaded on a page. The minification of the static content is disabled for the test.

Page Page Load Time,
Without CDN
Page Load Time,
With CDN
Homepage 1.2 sec 0.6 sec
Category Page (Men -> Tops) 1.35 sec 0.66 sec
Configurable Product Page (Logan HeatTec® Tee) 1.35 sec 0.6 sec
CMS Page (Contact Us) 1.3 sec 0.6 sec


Number of incoming HTTP GET requests to the web server with the CDN configured has been decreased. It allows to decrease CPU and Memory usage on the server and serve more incoming requests from users.

Summary

Content Delivery Network for an ecommerce store is a must have nowadays. Especially, when the business grows and number of customers increases year-to-year. The AWS CloudFront is a great service for the reasonable pricing and edge locations coverage.

This post was written for Atwix blog by Max Pronko, CEO & Founder of Pronko Consulting, Chief Technical Officer at TheIrishStore and GiftsDirect.

Max with his team of Magento enthusiasts won the Best Magento 1 to Magento 2 Migration Award at the Magento Imagine 2017. As one of the most active developers on a market and in the Magento Community, he launched Magento 2 blog, and Magento DevChannel, where he shares his knowledge, experience and the best practices in the Magento field.