Improving your website's page speed is important, but Google pushed the issue in July 2018 by officially making it a ranking factor. How do you stack up?
Check your speed score
We beleive in knowing as much as possible about your site. If you haven't already, take a moment to check your website's Google Speed Score. There are many tools out there, but we feel checking using Google's tool is important if search visibility is important to you.
We were able to improve our page speed score considerably from 50s-60s to 90+.
Optimizing Images
Image optimization is one of the easiest things you can do to improve your page speed. It starts with making sure you're serving the right sized images. We've seen many cases where full sized images are being served. We always encourage uploading high quality images, but then make sure we scale down automatically for specific uses, like headings, cards, thumbnails, etc.
Here are the 3 main ways we optimize images for speed.
Lazy Load
Lazy loading is delaying image loading until after the page has fully loaded and / or when the user scrolls near the image. This is especially important for users with metered connections.
There are a number of lazy loading plugins that can be used.
- jQuery.Lazy - Supports backgrounds as well traditional image tags
Resize
We use a tried and true php script called PHPThumb, the backbone of most CMS image resizing solutions.
Our MODX websites use this extensively with very granular control over size, format and quality.
- PThumb - Great documentation and options
Next Gen Formats
Where and when possible use, Next Gen Image formats, these include JPEG2000 and the new webp formats.
While not explicitly in this list, we also encourage use for SVG for the web when possible as it's much smaller than PNG or JPEG images as well.
To get the best user experience, we'll combine lazy loading with automated image resizing. The idea is to automatically build a small thumbnail that represents the image to be displayed so there is not a hole in the content for the image. Then lazy load in the higher resolution and quality image on scroll to keep the experience fast.
Here is an example for our website here of how we use Lazy Loading with phpthumb based image resizing for cards. Notice the two distinct pthumb instances.
<a href="/[[~[[+id]]]]" class="item-img img-hover lazy" title="[[+pagetitle]]" data-src="[[+tv.core-resource-image:pthumb=`&h=500&w=700&zc=T`]]" style="background-image: url([[+tv.core-resource-image:pthumb=`&h=50&w=70&zc=T`]])"> </a>
Static Resources Caching
.htaccess to the rescue!
Static resource caching tells the browser to not load files over and over again and use previously downloaded copies. This helps both the user and the web server as the transfer never needs to take place for subsequent page loads.
Many web servers use Apache and it uses a file called .htaccess to control how it reponds in many situations, think of it as a per-site configuration file.
Below is an except from our .htaccess file, you can find many other examples by searching for the term ".htaccess browser cache"
# ######################## # Leverage browser caching # ######################## <IfModule mod_expires.c> ExpiresActive On ExpiresByType image/gif A2592000 ExpiresByType image/jpeg A2592000 ExpiresByType image/jpg A2592000 ExpiresByType image/png A2592000 ExpiresByType image/x-icon A2592000 ExpiresByType text/css A86400 ExpiresByType text/javascript A86400 ExpiresByType application/x-shockwave-flash A2592000 # <FilesMatch "\.(gif¦jpe?g¦png¦ico¦css¦js¦swf)$"> # Header set Cache-Control "public" # </FilesMatch> #</IfModule> <FilesMatch "\.(ico|pdf|jpg|jpeg|svg|png|gif|html|htm|xml|txt|woff2|js|css|xsl)$"> Header set Cache-Control "max-age=31536050" </FilesMatch> # ######################## # Enable compression # ######################## <IfModule mod_deflate.c> AddOutputFilterByType DEFLATE application/javascript AddOutputFilterByType DEFLATE application/rss+xml AddOutputFilterByType DEFLATE application/vnd.ms-fontobject AddOutputFilterByType DEFLATE application/x-font AddOutputFilterByType DEFLATE application/x-font-opentype AddOutputFilterByType DEFLATE application/x-font-otf AddOutputFilterByType DEFLATE application/x-font-truetype AddOutputFilterByType DEFLATE application/x-font-ttf AddOutputFilterByType DEFLATE application/x-javascript AddOutputFilterByType DEFLATE application/xhtml+xml AddOutputFilterByType DEFLATE application/xml AddOutputFilterByType DEFLATE font/opentype AddOutputFilterByType DEFLATE font/otf AddOutputFilterByType DEFLATE font/ttf AddOutputFilterByType DEFLATE image/svg+xml AddOutputFilterByType DEFLATE image/x-icon AddOutputFilterByType DEFLATE text/css AddOutputFilterByType DEFLATE text/html AddOutputFilterByType DEFLATE text/javascript AddOutputFilterByType DEFLATE text/plain AddType x-font/otf .otf AddType x-font/ttf .ttf AddType x-font/eot .eot AddType x-font/woff .woff AddType image/x-icon .ico </IfModule>
Combine and Minify
Faster together
Many websites that use 3rd party plugins will just keep adding and adding javascript and css resources to be loaded with little thought given to page speed. It's important to try and combine those files into one, and minify or compress them. This reduces the number of requests the web browser needs to make, improving page speed.
We use a MODX Extra called MinifyX for combining Javascript and CSS into separate files as well as compression. During site development we'll often turn this off so they are not constantly being combined, but once in production we use it.
[[MinifyX? &minifyCss=`1` &minifyJs=`1` &jsSources=` /assets/templates/crewframe/js/modernizr-2.6.2.min.js, /assets/templates/crewframe/js/jquery.easing.1.3.js, /assets/templates/crewframe/js/bootstrap.min.js, /assets/templates/crewframe/js/jquery.waypoints.min.js, /assets/templates/crewframe/js/slick.min.js, /assets/templates/crewframe/js/jquery.simpleWeather.min.js, /assets/templates/crewframe/js/ekko-lightbox.min.js, /assets/templates/crewframe/js/main.js ` &cssSources=` /assets/templates/crewframe/css/animate.css, /assets/templates/bootstrap/css/ekko-lightbox.min.css, /assets/templates/crewframe/css/style.css ` ]]
In this example use the palceholders and respectivly for where to place those files in the markup
Content Delivry and Asynchronus Loading
It's all in the cloud
We try and use Content Delivery networks for things like:
- Bootstrap CSS and JS
- JQuery
- Google Fonts
- Font Awesome
For loading local stylesheets you can use the rel="preload" in the link tag keep it from blocking rendering. However not all browsers support this attribute.
<link rel="preload" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.css">
A more clever method is loadCSS
The last bit we finally tracked down was asynchronously loading in the Google Font Loader with the help from Locked Down Design.
<!--- Old Slow Code--> <script async src="https://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"></script> <script> WebFont.load({ google: { families: ['Source+Sans+Pro:400,300,600,400italic,700', 'Roboto Condensed:400,700','Roboto+Slab'] } }); </script>
<!--- Locked Down Fast Code--> <script type="text/javascript"> WebFontConfig = { google: { families: ['Source+Sans+Pro:400,300,600,400italic,700', 'Roboto Condensed:400,700','Roboto+Slab'] } }; (function() { var wf = document.createElement('script'); wf.src = ('https:' == document.location.protocol ? 'https' : 'http') + '://ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js'; wf.type = 'text/javascript'; wf.async = 'true'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(wf, s); })(); </script>