├── 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 |
--------------------------------------------------------------------------------