├── LICENSE.txt └── README.md /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2019 TheodorosPloumis, www.TheodorosPloumis.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Frontend Performance Checklist for Drupal websites 2 | > A checklist & guide to make sure you (Drupal 8.x) website will be fast! Made for Drupal frontend developers and site builders. 3 | 4 | # Table of Contents 5 | - [Frontend Performance Checklist for Drupal websites](#frontend-performance-checklist-for-drupal-websites) 6 | - [1. Checklist](#1-checklist) 7 | * [1.1 HTML](#11-html) 8 | * [1.2 Images](#12-images) 9 | * [1.3 CSS](#13-css) 10 | * [1.4 JS](#14-js) 11 | * [1.5 Assets](#15-assets) 12 | * [1.6 Fonts](#16-fonts) 13 | * [1.7 PWA](#17-pwa) 14 | * [1.8 Network](#18-network) 15 | * [1.9 Server](#19-server) 16 | - [2. Drupal modules](#2-drupal-modules) 17 | * [2.1 Development related](#21-development-related) 18 | * [2.2 Caching related](#22-caching-related) 19 | * [2.3 Image optimmizations](#23-image-optimmizations) 20 | * [2.4 Other](#24-other) 21 | - [3. Tools](#3-tools) 22 | * [3.1 Performance scoring - Online](#31-performance-scoring---online) 23 | * [3.2 Performance scoring - Offline (local installed)](#32-performance-scoring---offline-local-installed) 24 | * [3.3 Sprite Generators](#33-sprite-generators) 25 | * [3.4 Unused CSS - Online](#34-unused-css---online) 26 | * [3.5 Unused CSS - Offline](#35-unused-css---offline) 27 | * [3.6 Critical CSS/AboveTheFold CSS - Online](#36-critical-css-abovethefold-css---online) 28 | * [3.7 Critical CSS/AboveTheFold CSS - Offline](#37-critical-css-abovethefold-css---offline) 29 | * [3.8 Image optimization - Online](#38-image-optimization---online) 30 | * [3.9 Image optimization - Offline CLI](#39-image-optimization---offline-cli) 31 | * [3.10 Image optimization - Offline GUI](#310-image-optimization---offline-gui) 32 | * [3.11 Minify CSS/JS](#311-minify-css-js) 33 | * [3.12 CDN with free tiers](#312-cdn-with-free-tiers) 34 | * [3.13 Other tools](#313-other-tools) 35 | - [4. Guides & Resources](#4-guides---resources) 36 | * [4.1 Collections of tools, posts etc](#41-collections-of-tools--posts-etc) 37 | * [4.2 Image Optimization](#42-image-optimization) 38 | * [4.3 Drupal related articles](#43-drupal-related-articles) 39 | - [5. Similar projects](#5-similar-projects) 40 | - [6. Licence](#6-licence) 41 | 42 | Table of contents generated with markdown-toc 43 | 44 | 45 | # 1. Checklist 46 | ## 1.1 HTML 47 | 48 | - [ ] Core theme [Classy](https://git.drupalcode.org/project/drupal/tree/8.8.x/core/themes/classy) is your friend. Most of the times you could use this a the **base theme** and its templates to make overrides. 49 | - [ ] Mobile first design except if there is no need 50 | - [ ] Critical link (aka css) tags are in head 51 | - [ ] Less critical link tags are end of body 52 | - [ ] Less critical link tags lazy load 53 | - [ ] `` 54 | - [ ] JS loads with the async property 55 | - [ ] `` 56 | - [ ] or `defer` when scripts need to be loaded in order, or require the DOMContentLoaded Event 57 | - [ ] Keep DOM simple and small (Maximum DOM Depth < 12). Must "kill" some of the default Drupal wrappers 58 | - [ ] Create custom and simple 404, 403 error pages using twig template suggestions 59 | 60 | ## 1.2 Images 61 | 62 | - [ ] Always use next gen formats 63 | - [ ] webp -> chrome/firefox (Also use https://modernizr.com to inspect WebP support) 64 | - [ ] jpeg xr -> ie11/edge 65 | - [ ] jpeg 2000 -> safari 66 | - [ ] Use jpg for photography, not png 67 | - [ ] Size images properly 68 | - [ ] Use srcsets for multiple image sizes 69 | - [ ] Use the `` element to let the browser select the right image for a scenario 70 | - [ ] Lazy load images below the fold (see [1](https://developers.google.com/web/fundamentals/performance/lazy-loading-guidance/images-and-video), [2](https://imagekit.io/blog/lazy-loading-images-complete-guide)) 71 | 72 | ## 1.3 CSS 73 | 74 | - [ ] Avoid using `!important` 75 | - [ ] Use svg instead of icon fonts like fontawesome 76 | - [ ] Create svg sprites (or png sprites if svg are not available) 77 | - [ ] Do not support olb browsers (remove too old prefixes) 78 | - [ ] Avoid expensive selectors when possible 79 | - [ ] `border-radius` 80 | - [ ] `box-shadow` 81 | - [ ] `transform` 82 | - [ ] `filter` 83 | - [ ] `:nth-child` 84 | - [ ] `position: fixed;` 85 | - [ ] Partial matching: `[class^="wrap"]` 86 | - [ ] Don't use universal selectors 87 | - [ ] 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. 88 | - [ ] Avoid deeply nested dependent selectors 89 | - [ ] 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. 90 | - [ ] Use media queries to load files based on use case 91 | 92 | ```css 93 | 94 | 95 | 96 | 97 | ``` 98 | - [ ] Investigate using functional css instead of custom styles (eg [Tailwind](https://tailwindcss.com), [Tachyons](https://tachyons.io) etc. See more at https://css-tricks.com/need-css-utility-library) 99 | - [ ] If you are able to run (automated) builds do not include compiled css or js in your vcs code but only their sources 100 | 101 | 102 | ## 1.4 JS 103 | 104 | - [ ] Bundles should always be minified 105 | - [ ] Bundles should have 0 comments, and all license text extracted to a separate file 106 | - [ ] Use [Google Tag Manager](https://tagmanager.google.com) for 3rd party scripts like Google Analytics, FB Pixel etc 107 | - [ ] Move js on bottom of the html page 108 | 109 | ## 1.5 Assets 110 | 111 | - [ ] All assets should be fingerprinted 112 | - [ ] All assets should have `Cache-Control: max-age=365000000, immutable` as a header 113 | - [ ] Assets should be served over http/2 114 | - [ ] Assets should only be served on a cookieless domain 115 | - [ ] All files should be cached by a CDN 116 | - [ ] Support Brotli compression if able 117 | - [ ] 15-30% smaller than gzip 118 | - [ ] Compress with gzip, or zopfli as a fallback to brotli 119 | - [ ] Do not ship unused css, js 120 | - [ ] Try to clone external js/css to local server and load them from there (eg Google Analytics script) 121 | 122 | ## 1.6 Fonts 123 | 124 | - [ ] Fonts should always load `woff2` first 125 | - [ ] `woff` for fallback 126 | - [ ] Use `font-display: swap;` to allow the browser to use a fallback font while custom font files are being downloaded. 127 | - [ ] eot or truetype is only needed for `IE < 10` 128 | 129 | ## 1.7 PWA 130 | 131 | - [ ] Use a service worker to cache assets 132 | - [ ] Use a service worker to prefetch pages users will most likely navigate to next 133 | - [ ] Support offline, and spotty networks 134 | - [ ] Make sure that the tracking or other third party js/css files (eg Google Analytics etc) are not included on the PWA 135 | 136 | ## 1.8 Network 137 | 138 | - [ ] Test site with Network Throttling. See a [list of common Network speed](https://gist.github.com/theodorosploumis/fd4086ee58369b68aea6b0782dc96a2e) 139 | 140 | ## 1.9 Server 141 | - [ ] Prefer Nginx over Apache2 (at least as a proxy) 142 | 143 | 144 | --- 145 | 146 | # 2. Drupal modules 147 | ## 2.1 Development related 148 | - https://www.drupal.org/project/seo_checklist 149 | - https://www.drupal.org/project/html_checker 150 | - https://www.drupal.org/project/healthcheck 151 | - https://www.drupal.org/project/blackfire 152 | - https://www.drupal.org/project/devel (webprofiler) 153 | - https://www.drupal.org/project/performance_budget 154 | - https://www.drupal.org/project/perfmon 155 | 156 | ## 2.2 Caching related 157 | - **https://www.drupal.org/project/advagg** 158 | - https://www.drupal.org/project/http_cache_control 159 | - https://www.drupal.org/project/big_pipe_sessionless 160 | - https://www.drupal.org/project/prefetch_cache 161 | - https://www.drupal.org/project/cdn (and other CDN related modules) 162 | - https://www.drupal.org/project/fastly 163 | - https://www.drupal.org/project/stackpath 164 | 165 | ## 2.3 Image optimizations 166 | - https://www.drupal.org/docs/8/mobile-guide/responsive-images-in-drupal-8 167 | - https://www.drupal.org/project/lazy 168 | - https://www.drupal.org/project/blazy 169 | - https://www.drupal.org/project/lazyloader 170 | - https://www.drupal.org/project/fancyload 171 | - https://www.drupal.org/project/drimage 172 | - https://www.drupal.org/project/imageapi_optimize 173 | - https://www.drupal.org/project/imageapi_optimize_webp 174 | - https://www.drupal.org/project/imageapi_optimize_binaries 175 | - https://www.drupal.org/project/imagemagick 176 | - https://www.drupal.org/project/webp 177 | 178 | ## 2.4 Other 179 | - **https://www.drupal.org/project/quicklink** 180 | - **https://www.drupal.org/project/minifyhtml** 181 | - https://www.drupal.org/project/critical_css 182 | - https://www.drupal.org/project/amp 183 | - https://www.drupal.org/project/amp_cts 184 | - https://github.com/Drupal-Jedi/css-tree-shaking 185 | - https://www.drupal.org/project/pwa 186 | - https://www.drupal.org/project/fast_404 187 | - https://www.drupal.org/project/refreshless 188 | 189 | --- 190 | 191 | # 3. Tools 192 | ## 3.1 Performance scoring - Online 193 | - https://developers.google.com/speed/pagespeed/insights 194 | - https://www.thinkwithgoogle.com/feature/testmysite 195 | - https://yellowlab.tools 196 | - https://www.webpagetest.org 197 | - https://tools.pingdom.com 198 | - https://search.google.com/test/mobile-friendly 199 | - https://web.dev/measure 200 | - https://gtmetrix.com 201 | - https://www.uptrends.com/tools/website-speed-test 202 | - https://gf.dev/website-audit 203 | - https://www.giftofspeed.com 204 | - https://varvy.com/pagespeed 205 | - https://www.gumlet.com/analyzer 206 | - https://www.dareboost.com 207 | - https://www.checkbot.io 208 | - https://whatdoesmysitecost.com 209 | - https://compare.sitespeed.io (Beta) 210 | - https://www.drupalaudit.com 211 | - https://webhint.io 212 | - https://waterfaller.dev 213 | 214 | ## 3.2 Performance scoring - Offline (local installed) 215 | - https://www.sitespeed.io 216 | - https://github.com/sitespeedio/coach 217 | - https://www.sitespeed.io/documentation/throttle 218 | - https://developers.google.com/web/tools/lighthouse 219 | - https://github.com/gmetais/YellowLabTools 220 | - https://github.com/sitespeedio/browsertime 221 | - http://devbridge.github.io/Performance 222 | - https://github.com/GoogleChromeLabs/psi 223 | - https://github.com/paulirish/pwmetrics 224 | - https://github.com/desktoppr/wbench 225 | - http://yslow.org/command-line-har 226 | 227 | ## 3.3 Sprite Generators 228 | - https://instantsprite.com (online - png/gif export) 229 | - https://github.com/frexy/svg-sprite-generator 230 | - https://github.com/sprity/sprity 231 | - https://github.com/itsjavi/spritesheet-generator 232 | - https://github.com/selaux/node-sprite-generator 233 | 234 | ## 3.4 Unused CSS - Online 235 | - https://unused-css.com 236 | - https://uncss-online.com 237 | - https://www.jitbit.com/unusedcss 238 | - https://purifycss.online 239 | - https://cssstats.com 240 | 241 | ## 3.5 Unused CSS - Offline 242 | - **https://github.com/Drupal-Jedi/css-tree-shaking** 243 | - https://github.com/uncss/uncss 244 | - https://www.purgecss.com 245 | - https://github.com/probosckie/cssTreeShaking 246 | - https://github.com/AlanJenkinsVS/css-tree-shaking 247 | - https://github.com/purifycss/purifycss 248 | - https://github.com/leeoniya/dropcss 249 | 250 | ## 3.6 Critical CSS/AboveTheFold CSS - Online 251 | - https://criticalcss.com 252 | - https://jonassebastianohlsson.com/criticalpathcssgenerator 253 | - https://www.sitelocity.com/critical-path-css-generator 254 | 255 | ## 3.7 Critical CSS/AboveTheFold CSS - Offline 256 | - **https://github.com/stefspakman/drupal-critical** 257 | - https://github.com/addyosmani/critical 258 | - https://github.com/filamentgroup/criticalCSS 259 | - https://github.com/pocketjoso/penthouse 260 | - https://github.com/finkinfridom/kant.io 261 | - https://github.com/bezoerb/inline-critical 262 | - https://github.com/hummal/crittr 263 | - https://github.com/GoogleChromeLabs/critters 264 | - https://github.com/theKashey/used-styles 265 | - https://github.com/filamentgroup/loadCSS 266 | 267 | ## 3.8 Image optimization - Online 268 | - https://resmush.it 269 | - https://convertio.co/jpg-webp 270 | - https://kraken.io 271 | - https://www.gumlet.com 272 | - https://imageoptim.com 273 | - https://imagekit.io 274 | - https://tinypng.com 275 | - https://tinyjpg.com 276 | - https://compressjpeg.com 277 | - https://compresspng.com 278 | - https://way2enjoy.com/compress-jpeg 279 | - https://shortpixel.com 280 | - https://imagify.io 281 | - https://optimole.com 282 | - https://compressor.io/compress 283 | - https://squoosh.app 284 | - https://imageengine.io 285 | - https://blinkloader.com 286 | - https://www.jpegmini.com 287 | - http://thumborize.me 288 | - https://rokka.io 289 | 290 | ## 3.9 Image optimization - Offline CLI 291 | **WebP** 292 | - https://github.com/imagemin/imagemin-webp 293 | 294 | **JPEG** 295 | - https://github.com/tjko/jpegoptim 296 | - https://github.com/danielgtaylor/jpeg-archive 297 | - https://github.com/technopagan/adept-jpg-compressor 298 | - https://github.com/imagemin/jpeg-recompress-bin 299 | - https://github.com/mozilla/mozjpeg 300 | - https://github.com/google/butteraugli 301 | - https://github.com/google/guetzli 302 | 303 | **PNG** 304 | - https://pngquant.org 305 | - https://github.com/shssoichiro/oxipng 306 | 307 | **SVG** 308 | - https://github.com/svg/svgo 309 | - https://github.com/jkphl/svg-sprite 310 | 311 | **GIF** 312 | - https://github.com/kohler/gifsicle 313 | 314 | **General** 315 | - https://github.com/ravgeetdhillon/create-optimize-images (bash wrapper) 316 | - https://github.com/libvips/libvips 317 | - https://github.com/imagemin/imagemin 318 | - https://github.com/imagemin/imagemin-cli 319 | - https://github.com/lovell/sharp 320 | - https://github.com/google/zopfli 321 | - https://github.com/charlyie/resmushit-cli 322 | - https://github.com/psliwa/image-optimizer (PHP library) 323 | - https://github.com/avalanche123/Imagine (PHP library) 324 | - https://glide.thephpleague.com (PHP library) 325 | - http://image.intervention.io (PHP library) 326 | - https://github.com/joedicastro/img4web (Python script) 327 | - https://fengyuanchen.github.io/compressorjs (JS library) 328 | 329 | ## 3.10 Image optimization - Offline GUI 330 | - https://www.xnview.com/en/xnconvert 331 | - https://trimage.org 332 | - https://pnggauntlet.com 333 | - https://jakearchibald.github.io/svgomg 334 | - https://hvdwolf.github.io/pyExifToolGUI 335 | - https://github.com/imagemin/imagemin-app 336 | 337 | ## 3.11 Minify CSS/JS 338 | - https://github.com/mishoo/UglifyJS2 339 | - https://github.com/cssnano/cssnano 340 | 341 | ## 3.12 CDN with free tiers 342 | - https://anyone.cdn.biz.id 343 | - https://jetpack.com/pricing 344 | - https://www.cloudflare.com/plans 345 | - https://shift8cdn.com 346 | - https://www.coralcdn.org 347 | - https://cloudinary.com 348 | - **https://github.com/thumbor/thumbor** (OS, self-hosted) 349 | 350 | ## 3.13 Other tools 351 | - **https://instant.page** 352 | - https://github.com/turbolinks/turbolinks 353 | - https://polyfill.io 354 | - [CodePen - Performance Budget Builder](https://codepen.io/bradfrost/pen/EPQVBp) 355 | - https://github.com/tkadlec/grunt-perfbudget 356 | - https://micmro.github.io/PerfCascade 357 | - https://github.com/filamentgroup/glyphhanger 358 | 359 | --- 360 | 361 | # 4. Guides & Resources 362 | ## 4.1 Collections of tools, posts etc 363 | - https://github.com/fabkrum/web-performance-resources 364 | - https://developer.yahoo.com/performance/rules.html 365 | - https://perf.rocks 366 | - https://www.perf-tooling.today 367 | - https://web.dev 368 | - https://browserdiet.com 369 | - https://css-tricks.com/tools-for-optimizing-svg 370 | - https://moz.com/learn/seo/page-speed 371 | 372 | ## 4.2 Image Optimization 373 | - https://images.guide 374 | - https://css-tricks.com/converting-and-optimizing-images-from-the-command-line 375 | - https://jeremy.codes/blog/bulk-image-optimization-in-bash 376 | - https://jeremy.codes/blog/faster-bulk-image-optimization-in-bash 377 | - https://guides.wp-bullet.com/batch-optimize-jpg-lossy-linux-command-line-with-jpeg-recompress 378 | 379 | ## 4.3 Drupal related articles 380 | - https://www.drupal.org/docs/8/modules/advanced-cssjs-aggregation/advanced-aggregates 381 | - https://www.drupal.org/docs/8/mobile/front-end-performance 382 | - https://www.fourkitchens.com/blog/article/use-grunt-and-advagg-inline-critical-css-drupal-7-theme 383 | - https://pantheon.io/docs/guides/frontend-performance 384 | - https://thinktandem.io/blog/2020/02/04/drupal-8-performance-tips-and-tricks-for-2020 385 | - https://www.srijan.net/blog/performance-optimization-for-drupal-websites-intermediate-level 386 | - [Debug Site Performance Using Web Profiler in Drupal 8 - Youtube, 2016](https://www.youtube.com/watch?v=pHf128w-1QQ) 387 | 388 | --- 389 | 390 | # 5. Similar projects 391 | - https://frontendchecklist.io 392 | - https://github.com/thedaviddias/Front-End-Performance-Checklist 393 | - https://web.dev/fast 394 | - https://www.taskade.com/v/H1XaaoP0Ab 395 | - https://jonyablonski.com/designers-wpo-checklist 396 | - https://github.com/TerribleDev/WebPerformanceChecklist 397 | - https://docs.google.com/spreadsheets/d/1PQTsn_A24CCSXtp8NcXg3ciL6IVa9LVJ_fG_e9oEH_0 398 | 399 | --- 400 | # 6. Licence 401 | [MIT](LICENSE.txt) 402 | --------------------------------------------------------------------------------