In our 4 part series on “Faster Drupal”, we have so far published three different articles on:
- Faster Drupal: Part 1: Caching
- Faster Drupal: Part 2: Aggregation, CDN and Image Optimization
- Faster Drupal: Part 3: Theming
If you haven’t already read those parts, go ahead and check them out! Now let’s get to our beloved CSS/JS stuff!
Faster Drupal – Part 4: CSS/JS Tips
We’ve come to find this amazing blog post by Charlie Gerard, The first three items are from her blog post, I added the TL;DR version that we need for this guide but it’s worth checking:
CSS: Avoid modifying layout wherever possible: Changes to some CSS properties will require the whole layout to be updated. For example, properties like width, height, top, left (also referred to as “geometric properties”), require the layout to be calculated and the render tree to be updated.
CSS: The descendant selector can be expensive: in an example like this: #nav a The browser is going to assess all the links on the page before settling to the ones actually inside our #nav section. A more performant way to do this would be to add a specific selector of .navigation-link on each <a> inside our #nav element. CSS: Browser reads selectors from right to left, so less selector the better
- CSS: Some CSS properties are more expensive than others. What this means is that they take longer to paint.
Some of these expensive properties include:border-radius
box-shadow
filter
:nth-child
position: fixed
- Check to see if you are overriding your CSS selectors, there are IDE tools for that
- Avoid duplicated CSS selectors, in large scale websites I’m pretty sure you can find a lot of them
- Avoid !important declaration
- Avoid DOM manipulation in javascript. If you really have toi do that (and often we do) keep the DOM updates to the bare minimum
- The Drupal core will call attached behaviors when the DOM (the object representation of the HTML) is fully loaded and on each AJAX response altering the DOM.
- Conditionally load assets where necessary! You have some JS or CSS only being used for certain nodes/content-types/pages? Load those files for those necessary pages only
- Consider component-based themes that handle assets per component such as bootstrap_storybook
- Use one of the methods below to defer parsing for external JavaScript files:
- Use the
async
attribute - Use the
defer
attribute
- Use the
- Append the script to the DOM in JavaScript during the onload event
- Make sure your scripts are placed at the bottom of the page (ideally at the end of the body) unless you really need it to be in the head..
- Be sure to deliver the lightest possible font format. And also note the order of fonts loading is important as well. The preferred order of web font formats are as follows:
- EOT
- WOFF2
- WOFF
- TTF
- SVG
- Try vanilla JS instead of jQuery: I mean we all love jQuery and it has saved us a lot of time and headache in the past, however nowadays you might not need jQuery for most of day-to-day operations.
That said.. Sometimes you gotta do what you gotta do, but even then: do yourself a favour and use the latest jQuery available, not the default which comes with Drupal core to get the most updated library.- In Drupal 8 you can go one step further: Since D8 jQuery is not automatically loaded in the frontend so you can remove the jquery dependency from your theme’s libraries and just use Vanilla JS!
- Consider making a CSS/Image sprite out of your icons, especially if your users are still heavily using HTTP1.1.
On the other hand if most of your traffic si via HTTP2 the number of your requests to the server are not really an issue (but don’t go crazy)!
Are we done with this list? Never! We would like to continuously improve it.
We would also love to have your comments and suggestions!
Written by Sohail Lajevardi
Developer at Ramsalt Lab