Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough
Dec 14 2018
Dec 14

A lot of people have been jumping on the headless CMS bandwagon over the past few years, but I’ve never been entirely convinced. Maybe it’s partly because I don’t want to give up on the sunk costs of what I’ve learned about Drupal theming, and partly because I’m proud to be a boring developer, but I haven’t been fully sold on the benefits of decoupling.

On our current project, we’ve continued to take an approach that Dries Buytaert has described as “progressively decoupled Drupal”. Drupal handles routing, navigation, access control, and page rendering, while rich interactive functionality is provided by a JavaScript application sitting on top of the Drupal page. In the past, we’d taken a similar approach, with AngularJS applications on top of Drupal 6 or 7, getting their configuration from Drupal.settings, and for this project we decided to use React on top of Drupal 8.

There are a lot of advantages to this approach, in my view. There are several discrete interactive applications on the site, but the bulk of the site is static content, so it definitely makes sense for that content to be rendered by the server rather than constructed in the browser. This brings a lot of value in terms of accessibility, search engine optimisation, and performance.

A decoupled system is almost inevitably more complex, with more potential points of failure.

The application can be developed independently of the CMS, so specialist JavaScript developers can work without needing to worry about having a local Drupal build process.

If at some later date, the client decides to move away from Drupal, or at the point where we upgrade to Drupal 9, the applications aren’t so tightly coupled, so the effort of moving them should be smaller.

Having made the decision to use this architecture, we wanted a consistent framework for managing application configuration, to make sure we wouldn’t need to keep reinventing the wheel for every application, and to keep things easy for the content team to manage.

The client’s content team want to be able to control all of the text within the application (across multiple languages), and be able to preview changes before putting them live.

There didn’t seem to be an established approach for this, so we’ve built a module for it.

As we’ve previously mentioned, the team at Capgemini are strongly committed to supporting the open source communities whose work we depend on, and we try to contribute back whenever we can, whether that’s patches to fix bugs and add new features, or creating new modules to fill gaps where nothing appropriate already exists. For instance, a recent client requirement to promote their native applications led us to build the App Banners module.

Aiming to make our modules open source wherever possible helps us to think in systems, considering the specific requirements of this client as an example of a range of other potential use cases. This helps to future-proof our code, because it’s more likely that evolving requirements can be met by a configuration change, rather than needing a code change.

So, guided by these principles, I’m very pleased to announce the Single Page Application Landing Page module for Drupal 8, or to use the terrible acronym that it has unfortunately but inevitably acquired, SPALP.

On its own, the module doesn’t do much other than provide an App Landing Page content type. Each application needs its own module to declare a dependency on SPALP, define a library, and include its configuration as JSON (with associated schema). When a module which does that is installed, SPALP takes care of creating a landing page node for it, and importing the initial configuration onto the node. When that node is viewed, SPALP adds the library, and a link to an endpoint serving the JSON configuration.

Deciding how to store the app configuration and make all the text editable was one of the main questions, and we ended up answering it in a slightly “un-Drupally” way.

On our old Drupal 6 projects, the text was stored in a separate ‘Messages’ node type. This was a bit unwieldy, and it was always quite tricky to figure out what was the right node to edit.

For our Drupal 7 projects, we used the translation interface, even on a monolingual site, where we translated from English to British English. It seemed like a great idea to the development team, but the content editors always found it unintuitive, struggling to find the right string to edit, especially for common strings like button labels. It also didn’t allow the content team to preview changes to the app text.

We wanted to maintain everything related to the application in one place, in order to keep things simpler for developers and content editors. This, along with the need to manage revisions of the app configuration, led us down the route of using a single node to manage each application.

This approach makes it easy to integrate the applications with any of the good stuff that Drupal provides, whether that’s managing meta tags, translation, revisions, or something else that we haven’t thought of.

The SPALP module also provides event dispatchers to allow configuration to be altered. For instance, we set different API endpoints in test environments.

Another nice feature is that in the node edit form, the JSON object is converted into a usable set of form fields using the JSON forms library. This generic approach means that we don’t need to spend time copying boilerplate Form API code to build configuration forms when we build a new application - instead the developers working on the JavaScript code write their configuration as JSON in a way that makes sense for their application, and generate a schema from that. When new configuration items need to be added, we only need to update the JSON and the schema.

Each application only needs a very simple Drupal module to define its library, so we’re able to build the React code independently, and bring it into Drupal as a Composer dependency.

The repository includes a small example module to show how to implement these patterns, and hopefully other teams will be able to use it on other projects.

As with any project, it’s not complete. So far we’ve only built one application following this approach, and it seems to be working pretty well. Among the items in the issue queue is better integration with configuration management system, so that we can make it clear if a setting has been overridden for the current environment.

I hope that this module will be useful for other teams - if you’re building JavaScript applications that work with Drupal, please try it out, and if you use it on your project, I’d love to hear about it. Also, if you spot any problems, or have any ideas for improvements, please get in touch via the issue queue.

Jan 18 2018
Jan 18

One of the things we do on an annual basis for our clients at Advomatic is an annual site audit – a high level kick-the-tires kind of site inspection. For Drupal sites, we check the logs for any glaring errors, check for overrides in Features, run some SEO and accessibility testing, and, of course, take it for a speed test.

If you run speed tests (like Google’s Page Speed Insights), you have probably seen a common, vexing error: “Render-blocking javascript and CSS.” What’s that?

Optimize Images, Eliminate render-blocking Javascript and CSS in above-the-fold content. Your page has 4 blocking script resources and 6 blocking CSS resources. This causes a delay in rendering your page. None of the above-the-fold content on your page could be rendered without waiting for the following resources to load. Try to defer or asynchronously load blocking resources, or inline the critical portions of these resources directly in the HTML.

Pagespeed Insight’s error message for render blocking assets.

Large CSS/JS assets can block rendering “above-the-fold” content. Modern browsers tend to allow concurrent downloading of 6 to 8 files at any given time (a few offer more, now). So developers aggregate and compress CSS and JS files so we have less to load, but that also means front-loading large — though compressed — styles and javascript files. This is a recipe for a log jam.

Here’s how to beat this speed bump. Using the methods described below, I’ve seen Pagespeed Insight scores on Drupal sites increase by 30% or more.

Javascript

For javascript, the solution is fairly easy: ensure the files are in the footer. In Drupal 8, this is already the standard, unless you have added some elsewhere. For your javascript to load in the header, you actually have to set: header: true in your theme’s library.yml file. (Also, be sure you are not loading any javascript that is not needed on the page.) In Drupal 7, you will need to move the files, perhaps using Advanced CSS/JS Aggregation or manually.

If there is specific JS that needs to be there as the page loads, you may want to defer it instead. Again, AdvAgg can help you do that, or you can defer it manually.

CSS

While moving files to the footer technically works for CSS as well, it introduces a new problem: the dreaded FOUC, or “flash of unstyled content.” Put plainly, the content is loading before the styles, so users – especially on slower connections – will see a very ugly site until the page is completely done loading. While not the end of the world, it makes for an unpleasant user experience.

What we do to counter FOUC is load a “Critical CSS” file first. Critical CSS is, as it sounds, any CSS that is crucial to making above-the-fold content appear close to the final product. Think layout, position, readability, sizing – particularly in the header … anything that will smooth a transition to the full CSS loading. These styles will be put in their own file (as straight CSS) and loaded inline, in the page’s .

Place this in your html.html.twig file, in the :

When you view your site, those styles will now load directly .

Now, sifting through your CSS to figure out what is critical is a challenge in and of itself. I’ve tried using automated grunt/gulp tasks (critical, grunt-critical, grunt-criticalcss), that will take “snapshots” of styles that have been called for above-the-fold content only on a specific page, but those tools have their limitations. (For instance, you may build your critical CSS file from a snapshot of a wide view of your page, but then it may miss styles needed for a mobile version of the page. Or there are just too many variations page-to-page with a site with dynamic content.) It’s possible some of these projects have improved since I last checked, so it still may be worth looking into.

If you have (wisely) built your styles using discrete files for base, regions, components, etc, you *could* do a compile just of the your base, layout, header, and header component styles and that would put you in a good position to start building your critical CSS file. You could use a tool like Sassmeister to compile outside your normal workflow.

If you haven’t (or you have inherited a site will less precision), you may just end up taking that final, compiled CSS file, un-compressing it, and doing your best to grab styles for the header and top part of the body (taking special care for the homepage.) Like I said, it’s an imprecise science.

Once the critical CSS is in place, you can try moving the rest of the CSS in the footer. In Drupal 8, this means moving this line in html.html.twig:

Move it down to before the closing   tag.

In most cases, fine tuning what should be in the Critical CSS file takes a little trial and error.

Like with any style changes, make sure you review in a variety of browsers, devices and widths. Also, be sure to try throttling your page speed, under the Google Chrome web inspector’s Network tab. This allows you to simulate a slower network. 

Network tab of Chrome's web inspector

Network tab of Chrome’s web inspector

Note that you will need to maintain this new file. Any time you make changes to things included in the Critical CSS file, you will need to manually adjust it. 

A final word of caution: you may very well be shifting around some structural stuff, and regressions can happen, especially at that level. Testing is very important – by you, and by the client, particularly on inherited sites. In a dream world, we’d have ubiquitous and comprehensive visual regression testing tools to catch anything that might have changed in the underlying load order of styles – but that level of safety netting is rare!

With all this in mind, you can plan for a critical CSS file for the next project that requires stellar performance: start out with all the javascript in the footer, prepare your CSS in compartmentalized Sass files that can be funneled to a critical CSS file, run speed tests throughout the project to see where problems are introduced, and, since you won’t want to maintain it during development, hold off until near-launch to generate your inline critical CSS file. 

Apr 12 2010
Apr 12

jQuery for Designers and Themers is a fun interactive session at DrupalCon San francisco on getting started with jQuery. It is targeted at designers and themers but is suitable for anyone with a decent understanding of HTML and CSS — no programming experience is necessary. It doesn't include any PHP, and only basic programming concepts are introduced.

The session is early on Tuesday 20 April in room 307 (Commerce guys) at DrupalCon SF at 8:30am.

The sample code is available at Drupal.org/Project/jQ4DaT and slides are available at TinyURL.com/jQuery-Designers (Google Docs).

Some other related or similar sessions include;

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web