A checklist & guide to make sure you (Drupal 8.x+) website will be fast! Made for Drupal frontend developers and site builders.
- Frontend Performance Checklist for Drupal websites
- 1. Checklist
- 2. Drupal modules
- 3. Tools
- 3.1 Performance scoring - Online
- 3.2 Performance scoring - Offline (local installed)
- 3.3 Sprite Generators
- 3.4 Unused CSS - Online
- 3.5 Unused CSS - Offline
- 3.6 Critical CSS/AboveTheFold CSS - Online
- 3.7 Critical CSS/AboveTheFold CSS - Offline
- 3.8 Image optimization - Online
- 3.9 Image optimization - Offline CLI
- 3.10 Image optimization - Offline GUI
- 3.11 Minify CSS/JS
- 3.12 CDN with free tiers
- 3.13 Other tools
- 4. Guides & Resources
- 5. Similar projects
- 6. Licence
Table of contents generated with markdown-toc
- Core theme Classy is your friend. Most of the times you could use this a the base theme and its templates to make overrides.
- Mobile first design except if there is no need
- Critical link (aka css) tags are in head
- Less critical link tags are end of body
- Less critical link tags lazy load
-
<link rel="preload" as="style" onload="this.rel='stylesheet'" id='dashicons-css' >
-
- JS loads with the async property
-
<script async src="https://hi.js"></script>
- or
defer
when scripts need to be loaded in order, or require the DOMContentLoaded Event
-
- Keep DOM simple and small (Maximum DOM Depth < 32 HTML Nodes, Total HTML Nodes by page < 800, Childs of a parent < 60). See https://web.dev/dom-size.
- Create custom and simple 404, 403 error pages using twig template suggestions
- Always use next gen formats
- webp -> chrome/firefox (Also use https://modernizr.com to inspect WebP support)
- jpeg xr -> ie11/edge
- jpeg 2000 -> safari
- Use jpg for photography, not png
- Size images properly
- Use srcsets for multiple image sizes
- Use the
<picture>
element to let the browser select the right image for a scenario - Lazy load images below the fold (see 1, 2)
- Avoid using
!important
- Use svg instead of icon fonts like fontawesome
- Create svg sprites (or png sprites if svg are not available)
- Do not support olb browsers (remove too old prefixes)
- Avoid expensive selectors when possible
-
border-radius
-
box-shadow
-
transform
-
filter
-
:nth-child
-
position: fixed;
- Partial matching:
[class^="wrap"]
-
- Don't use universal selectors
- Avoid universal selectors like
*, [disabled], [type=“text”]
, etc. They are very expensive for the browser to match, as every element in the DOM must be checked.
- Avoid universal selectors like
- Avoid deeply nested dependent selectors
- The descendant selector is very costly, as the browser must check for a match with every descendant element. On a complex web page, this can result in thousands and thousands (perhaps even more) of descendant selector searches.
- Use media queries to load files based on use case
<link href="style.css" rel="stylesheet" media="all">
<link href="portrait.css" rel="stylesheet" media="orientation:portrait">
<link href="print.css" rel="stylesheet" media="print">
<link href="desktop.css" rel="stylesheet" media="(min-width: 720px)">
- Investigate using functional css instead of custom styles (eg Tailwind, Tachyons etc. See more at https://css-tricks.com/need-css-utility-library)
- If you are able to run (automated) builds do not include compiled css or js in your vcs code but only their sources
- Bundles should always be minified
- Bundles should have 0 comments, and all license text extracted to a separate file
- Use Google Tag Manager for 3rd party scripts like Google Analytics, FB Pixel etc
- Move js on bottom of the html page
- All assets should be fingerprinted
- All assets should have
Cache-Control: max-age=365000000, immutable
as a header - Assets should be served over http/2
- Assets should only be served on a cookieless domain
- All files should be cached by a CDN
- Support Brotli compression if able
- 15-30% smaller than gzip
- Compress with gzip, or zopfli as a fallback to brotli
- Do not ship unused css, js
- Try to clone external js/css to local server and load them from there (eg Google Analytics script)
- Fonts should always load
woff2
first -
woff
for fallback - Use
font-display: swap;
to allow the browser to use a fallback font while custom font files are being downloaded. - eot or truetype is only needed for
IE < 10
- Use a service worker to cache assets
- Use a service worker to prefetch pages users will most likely navigate to next
- Support offline, and spotty networks
- Make sure that the tracking or other third party js/css files (eg Google Analytics etc) are not included on the PWA
- Test site with Network Throttling. See a list of common Network speed
- Prefer Nginx over Apache2 (at least as a proxy)
- https://www.drupal.org/project/seo_checklist
- https://www.drupal.org/project/html_checker
- https://www.drupal.org/project/healthcheck
- https://www.drupal.org/project/blackfire
- https://www.drupal.org/project/devel (webprofiler)
- https://www.drupal.org/project/performance_budget
- https://www.drupal.org/project/perfmon
- https://www.drupal.org/project/advagg
- https://www.drupal.org/project/http_cache_control
- https://www.drupal.org/project/big_pipe_sessionless
- https://www.drupal.org/project/prefetch_cache
- https://www.drupal.org/project/cdn (and other CDN related modules)
- https://www.drupal.org/project/fastly
- https://www.drupal.org/project/stackpath
- https://www.drupal.org/docs/8/mobile-guide/responsive-images-in-drupal-8
- https://www.drupal.org/project/lazy
- https://www.drupal.org/project/blazy
- https://www.drupal.org/project/lazyloader
- https://www.drupal.org/project/fancyload
- https://www.drupal.org/project/drimage
- https://www.drupal.org/project/imageapi_optimize
- https://www.drupal.org/project/imageapi_optimize_webp
- https://www.drupal.org/project/imageapi_optimize_binaries
- https://www.drupal.org/project/imagemagick
- https://www.drupal.org/project/webp
- https://www.drupal.org/project/quicklink
- https://www.drupal.org/project/minifyhtml
- https://www.drupal.org/project/critical_css
- https://www.drupal.org/project/amp
- https://www.drupal.org/project/amp_cts
- https://github.com/Drupal-Jedi/css-tree-shaking
- https://www.drupal.org/project/pwa
- https://www.drupal.org/project/fast_404
- https://www.drupal.org/project/refreshless
- https://pagespeed.web.dev
- https://www.thinkwithgoogle.com/feature/testmysite
- https://yellowlab.tools
- https://www.webpagetest.org
- https://tools.pingdom.com
- https://search.google.com/test/mobile-friendly
- https://web.dev/measure
- https://gtmetrix.com
- https://www.uptrends.com/tools/website-speed-test
- https://gf.dev/website-audit
- https://www.giftofspeed.com
- https://varvy.com/pagespeed
- https://www.gumlet.com/analyzer
- https://www.dareboost.com
- https://www.checkbot.io
- https://whatdoesmysitecost.com
- https://compare.sitespeed.io (Beta)
- https://www.drupalaudit.com
- https://webhint.io
- https://waterfaller.dev
- https://www.sitespeed.io
- https://github.com/sitespeedio/coach
- https://www.sitespeed.io/documentation/throttle
- https://developers.google.com/web/tools/lighthouse
- https://github.com/gmetais/YellowLabTools
- https://github.com/sitespeedio/browsertime
- http://devbridge.github.io/Performance
- https://github.com/GoogleChromeLabs/psi
- https://github.com/paulirish/pwmetrics
- https://github.com/desktoppr/wbench
- http://yslow.org/command-line-har
- https://instantsprite.com (online - png/gif export)
- https://github.com/frexy/svg-sprite-generator
- https://github.com/sprity/sprity
- https://github.com/itsjavi/spritesheet-generator
- https://github.com/selaux/node-sprite-generator
- https://unused-css.com
- https://uncss-online.com
- https://www.jitbit.com/unusedcss
- https://purifycss.online
- https://cssstats.com
- https://github.com/Drupal-Jedi/css-tree-shaking
- https://github.com/uncss/uncss
- https://www.purgecss.com
- https://github.com/probosckie/cssTreeShaking
- https://github.com/AlanJenkinsVS/css-tree-shaking
- https://github.com/purifycss/purifycss
- https://github.com/leeoniya/dropcss
- https://criticalcss.com
- https://jonassebastianohlsson.com/criticalpathcssgenerator
- https://www.sitelocity.com/critical-path-css-generator
- https://github.com/stefspakman/drupal-critical
- https://github.com/addyosmani/critical
- https://github.com/filamentgroup/criticalCSS
- https://github.com/pocketjoso/penthouse
- https://github.com/finkinfridom/kant.io
- https://github.com/bezoerb/inline-critical
- https://github.com/hummal/crittr
- https://github.com/GoogleChromeLabs/critters
- https://github.com/theKashey/used-styles
- https://github.com/filamentgroup/loadCSS
- https://resmush.it
- https://convertio.co/jpg-webp
- https://kraken.io
- https://www.gumlet.com
- https://imageoptim.com
- https://imagekit.io
- https://tinypng.com
- https://tinyjpg.com
- https://compressjpeg.com
- https://compresspng.com
- https://way2enjoy.com/compress-jpeg
- https://shortpixel.com
- https://imagify.io
- https://optimole.com
- https://compressor.io/compress
- https://squoosh.app
- https://imageengine.io
- https://blinkloader.com
- https://www.jpegmini.com
- http://thumborize.me
- https://rokka.io
WebP
JPEG
- https://github.com/tjko/jpegoptim
- https://github.com/danielgtaylor/jpeg-archive
- https://github.com/technopagan/adept-jpg-compressor
- https://github.com/imagemin/jpeg-recompress-bin
- https://github.com/mozilla/mozjpeg
- https://github.com/google/butteraugli
- https://github.com/google/guetzli
PNG
SVG
GIF
General
- https://github.com/ravgeetdhillon/create-optimize-images (bash wrapper)
- https://github.com/libvips/libvips
- https://github.com/imagemin/imagemin
- https://github.com/imagemin/imagemin-cli
- https://github.com/lovell/sharp
- https://github.com/google/zopfli
- https://github.com/charlyie/resmushit-cli
- https://github.com/psliwa/image-optimizer (PHP library)
- https://github.com/avalanche123/Imagine (PHP library)
- https://glide.thephpleague.com (PHP library)
- http://image.intervention.io (PHP library)
- https://github.com/joedicastro/img4web (Python script)
- https://fengyuanchen.github.io/compressorjs (JS library)
- https://www.xnview.com/en/xnconvert
- https://trimage.org
- https://pnggauntlet.com
- https://jakearchibald.github.io/svgomg
- https://hvdwolf.github.io/pyExifToolGUI
- https://github.com/imagemin/imagemin-app
- https://anyone.cdn.biz.id
- https://jetpack.com/features/design/content-delivery-network
- https://www.cloudflare.com/plans
- https://shift8cdn.com
- https://cloudinary.com
- https://github.com/thumbor/thumbor (OS, self-hosted)
See also https://speedvitals.com/cdn-performance-tracker.
- https://instant.page
- https://github.com/turbolinks/turbolinks
- https://polyfill.io
- CodePen - Performance Budget Builder
- https://github.com/tkadlec/grunt-perfbudget
- https://micmro.github.io/PerfCascade
- https://github.com/filamentgroup/glyphhanger
- https://github.com/davidsonfellipe/awesome-wpo
- https://github.com/pajaydev/awesome-web-performance-budget
- https://github.com/fabkrum/web-performance-resources
- https://developer.yahoo.com/performance/rules.html
- https://perf.rocks
- https://www.perf-tooling.today
- https://web.dev
- https://browserdiet.com
- https://css-tricks.com/tools-for-optimizing-svg
- https://moz.com/learn/seo/page-speed
- https://images.guide
- https://css-tricks.com/converting-and-optimizing-images-from-the-command-line
- https://jeremy.codes/blog/bulk-image-optimization-in-bash
- https://jeremy.codes/blog/faster-bulk-image-optimization-in-bash
- https://guides.wp-bullet.com/batch-optimize-jpg-lossy-linux-command-line-with-jpeg-recompress
- https://www.drupal.org/docs/8/modules/advanced-cssjs-aggregation/advanced-aggregates
- https://www.drupal.org/docs/8/mobile/front-end-performance
- salsa.digital | Drupal performance - a complete Drupal self-help guide to ensuring your website's performance | 2023
- https://www.fourkitchens.com/blog/article/use-grunt-and-advagg-inline-critical-css-drupal-7-theme
- https://pantheon.io/docs/guides/frontend-performance
- https://thinktandem.io/blog/2020/02/04/drupal-8-performance-tips-and-tricks-for-2020
- https://www.srijan.net/blog/performance-optimization-for-drupal-websites-intermediate-level
- Debug Site Performance Using Web Profiler in Drupal 8 - Youtube, 2016
- https://frontendchecklist.io
- https://github.com/thedaviddias/Front-End-Performance-Checklist
- https://www.toptal.com/developers/webdevchecklist
- https://web.dev/fast
- https://www.taskade.com/v/H1XaaoP0Ab
- https://jonyablonski.com/designers-wpo-checklist
- https://github.com/TerribleDev/WebPerformanceChecklist
- https://docs.google.com/spreadsheets/d/1PQTsn_A24CCSXtp8NcXg3ciL6IVa9LVJ_fG_e9oEH_0