Feeds

Author

Feb 08 2019
Feb 08

Welcome to the latest version of Lullabot.com! Over the years (since 2006!), the site has gone through at least seven iterations, with the most recent launching last week at the 2019 Lullabot team retreat in Palm Springs, California.

Back to a more traditional Drupal architecture

Our previous version of the site was one of the first (and probably the first) decoupled Drupal ReactJS websites. It launched in 2015.

Decoupling the front end of Drupal gives many benefits including easier multi-channel publishing, independent upgrades, and less reliance on Drupal specialists. However, in our case, we don’t need multi-channel publishing, and we don’t lack Drupal expertise.

One of the downsides of a decoupled architecture is increased complexity. Building blocks of our decoupled architecture included a Drupal 7 back end, a CouchDB middle-layer, ReactJS front end, and Node.js server-side application. Contrast this with a standard Drupal architecture where we only need to support a single Drupal 8 site.

The complexity engendered by decoupling a Drupal site means developers take longer to contribute certain types of features and fixes to the site. In the end, that was the catalyst for the re-platforming. Our developers only work on the site between client projects so they need to be able to easily understand the overall architecture and quickly spin up copies of the site.

Highlights of the new site

In addition to easily swapping in and out developers, the primary goals of the website were ease of use for our non-technical marketing team (hi Ellie!), a slight redesign, and to maintain or improve overall site speed.

Quickly rolling developers on and off

To aid developers quickly rolling on and off the project, we chose a traditional Drupal architecture and utilized as little custom back-end code as possible. When we found holes in functionality, we wrote modules and contributed them back to the Drupal ecosystem. 

We also standardized to Lando and created in-depth documentation on how to create a local environment. 

Ease of use

To enable our marketing team to easily build landing pages, we implemented Drupal’s new experimental Layout Builder module. This enables a slick drag-and-drop interface to quickly compose and control layouts and content.

We also simplified Drupal’s content-entry forms by removing and reorganizing fields (making heavy use of the Field Group module), providing useful descriptions for fields and content types, and sub-theming the Seven theme to make minor styling adjustments where necessary.

Making the front end lean and fast 

Normally, 80% of the delay between navigating to a webpage and being able to use the webpage is attributed to the front end. Browsers are optimized to quickly identify and pull in critical resources to render the page as soon as possible, but there are many enhancements that can be made to help it do so. To that end, we made a significant number of front-end performance optimizations to enable the rendering of the page in a half-second or less.

  • Using vanilla JavaScript instead of a framework such as jQuery enables the JS bundle size to be less than 27kb uncompressed (to compare, the previous version’s bundle size was over 1MB). Byte for byte, JavaScript impacts the performance of a webpage more than any other type of asset. 
  • We heavily componentize our stylesheets and load them only when necessary. Combined with the use of lean, semantic HTML, the browser can quickly generate the render-tree—a critical precursor to laying out the content.
  • We use HTTP2 to enable multiplexed downloads of assets while still keeping the number of HTTP requests low. Used with a CDN, this dramatically lowers the time-to-first-byte metric and time to download additional page assets.
  • We heavily utilize resource-hints to tell the browser to download render-blocking resources first, as well as instructing the browser to connect third-party services immediately.
  • We use the Quicklink module to pre-fetch linked pages when the browser is idle. This makes subsequent page loads nearly instantaneous.

There are still some performance @todos for us, including integrating WEBP images (now supported by Chrome and Firefox), and lazy-loading images. 

Contributing modules back to the Drupal ecosystem

During the development, we aimed to make use of contributed modules whenever it made sense. This allowed us to implement almost all of the features we needed. Only a tiny fraction of our needs was not covered by existing modules. One of Lullabot’s core values is to Collaborate Openly which is why we decided to spend a bit more time on our solutions so we could share them with the rest of the community as contributed modules.

Using Layouts with Views

Layout Builder builds upon the concept of layout regions. These layout regions are defined in custom modules and enable editors to use layout builder to insert these regions, and then insert content into them.

Early on, we realized that the Views module lacked the ability to output content into these layouts. Lullabot’s Director of Technology, Karen Stevenson, created the Views Layout module to solve this issue. This module creates a new Views row plugin that enables the Drupal site builder to easily select the layout they want to use, and select which regions to populate within that layout.

Generating podcast feeds with Drupal 8

Drupal can generate RSS feeds out of the box, but podcast feeds are not supported. To get around this limitation, Senior Developer Mateu Aguiló Bosch created the Podcast module, which complies with podcast standards and iTunes requirements.

This module utilizes the Views interface to map your site’s custom Drupal fields to the necessary podcast and iTunes fields. For more information on this, checkout Mateu’s tutorial video here.

Speeding up Layout Builder’s user interface

As stated earlier, Layout Builder still has “experimental” status. One of the issues that we identified is that the settings tray can take a long time to appear when adding a block into layout builder.

Lullabot Hawkeye Tenderwolf identified the bottleneck as the time it takes Drupal to iterate through the complete list of blocks in the system. To work around this, Karen Stevenson created the Block Blacklist module, in which you can specify which blocks to remove from loading. The result is a dramatically improved load time for the list of blocks.

Making subsequent page loads instantaneous 

A newer pattern on the web (called the PRPL pattern) includes pre-fetching linked pages and storing them in a browser cache. As a result, subsequent page requests return almost instantly, making for an amazing user experience. 

Bringing this pattern into Drupal, Senior Front-end Dev Mike Herchel created the Quicklink module using Google’s Quicklink JavaScript library. You can view the result of this by viewing this site’s network requests in your developer tool of choice. 

Keeping users in sync using the Simple LDAP module

Lullabot stores employee credentials in an internal LDAP server. We want all the new hires to gain immediate access to as many services as possible, including Lullabot.com. To facilitate this, we use the Simple LDAP module (which several bots maintain) to keep our website in sync with our LDAP directory.

This iteration of Lullabot.com required the development of some new features and some performance improvements for the D8 version of the module.

Want to learn more?

Built by Bots

While the site was definitely a team effort, special thanks go to Karen Stevenson, Mike Herchel, Wes Ruvalcaba, Putra Bonaccorsi, David Burns, Mateu Aguiló Bosch, James Sansbury, and, last but not least, Jared Ponchot for the beautiful designs.

Aug 01 2018
Aug 01

BigPipe is a technique pioneered by Facebook that’s used to lazy-load content into a webpage. From the user’s perspective, the “frame” of a webpage will appear immediately, and then the content will pop in place when it’s ready. BigPipe has been included as a module in Drupal core since 8.1.x, and is very simple— just enable the module.

On my latest project, I'm using it to lazy-load content that’s generated from a very slow API call. The functionality works great out of the box, but we noticed a user-experience problem where the end-user would see a big blank area while the API call was waiting on a response. This behavior made the website seem broken. To fix this, we decided to implement a simple loading animation.

Finding the CSS selector to attach the animation to wasn’t as simple as I hoped it would be.

Spoiler: Let’s see the code

Looking for the code, and not the process? The CSS selector to target is below. Note that you’ll want to qualify this within a parent selector, so the loader doesn’t appear everywhere.


.parent-selector [data-big-pipe-placeholder-id] {
  /* Loading animation CSS */
}

BigPipe’s placeholder markup is only one <span> element, which makes styling tricky. Luckily, we can make use of CSS pseudo-selectors to make a Facebook-style throbber animation.

Here is some Sass with easy-to-use variables:


$pulse-duration: 0.2s;
$pulse-color: rebeccaPurple;

@keyframes pulse-throbber {
  0% { 
    opacity: 1;
    transform: scaley(1);
  }

  100% { 
    opacity: 0.2; 
    transform: scaley(0.5);
  }
}


[data-big-pipe-placeholder-id] {
  position: relative;
  display: block;
  margin: 20px auto;
  width: 6px;
  height: 30px;
  background: $pulse-color;
  animation: pulse-throbber $pulse-duration infinite;
  animation-delay: ($pulse-duration / 3);
  animation-direction: alternate;

  &:before,
  &:after {
    content: '';
    position: absolute;
    display: block;
    width: 100%;
    height: 100%;
    background: $pulse-color;
    top: 0;
    animation: pulse-throbber $pulse-duration infinite;
    animation-direction: alternate;
  }

  &:before {
    left: -12px;
  }

  &:after {
    left: 12px;
    animation-delay: ($pulse-duration / 1.5);
  }
}

Tracking down the placeholder’s CSS selector

Finding this selector wasn’t as simple as I initially hoped. The first technique that I tried was setting a DOM breakpoint in Chrome Developer Tools. This functionality allows you to pause the execution of JavaScript when a DOM element’s attributes change, the element gets removed, or any descendant DOM elements are modified.

In our case, we want to set a breakpoint when any descendant element is modified and then reload the page. Hopefully, when BigPipe inserts the rendered HTML, the breakpoint will trigger, and we can then inspect the placeholder HTML to find the appropriate CSS selector.

Setting DOM breakpoints within Chrome Developer ToolsSetting DOM breakpoints within Chrome Developer Tools

Unfortunately, this didn’t work. Why? I’m still not sure. This appears to be a bug within Google Chrome. I created an issue within the Chromium bug tracker and will update this article when there’s progress.

PHP Breakpoints to the rescue!

Because I know I’m using the BigPipe module to stream the content in, the next step is setting a PHP breakpoint within the BigPipe module within PHPStorm. I ended up setting a breakpoint within the sendContent() function within BigPipeResponse.php. This had the expected result of pausing the lazy-loading of the content, which enabled me to easily inspect the HTML (by halting the injection of the BigPipe content) so I could find the placeholder’s selector.

PHP breakpoint within the BigPipe modulePHP breakpoint within the BigPipe module Yay! We can finally see the placeholder HTMLYay! We can finally see the placeholder HTML

Conclusion

Sometimes a seemingly simple theming task ends up being tricky. It’s important to understand proper front-end and backend debugging techniques because you never know when you’re going to need them in a pinch. Hopefully, this article will save someone from having to go through this process.

Photo by Jonny Caspari on Unsplash

May 25 2018
May 25

Earlier this year Lullabot was engaged to do a redesign of Pantheon’s homepage and several landing pages. If you’re not familiar with Pantheon, they’re one of the leading hosting companies in the Drupal and WordPress space. The timeline for this project was very ambitious—a rollout needed to happen before Drupalcon Nashville. Being longtime partners in the Drupal community, we were excited to take this on.

The front-end development team joined while our design team was still hard at work. Our tasks were to 1) get familiar with the current Drupal 7 codebase, and 2) make performance improvements where possible. All of this came with the caveat that when the designs landed, we were expected to move on them immediately.

Jumping into Pantheon’s codebase was interesting. It’s a situation that we’ve seen hundreds of times: the codebase starts off modularly, but as time progresses and multiple developers work on it, the codebase grows larger, slower, and more unwieldy. This problem isn’t specific to Drupal – it’s a common pandemic across many technologies.

Defining website speed

Website speed is a combination of back-end speed and browser rendering speed, which is determined by the front-end code. Pantheon’s back-end speed is pretty impressive. In addition to being built atop Pantheon’s infrastructure, they have integrated Fastly CDN with HTTP/2.

80-90% of the end-user response time is spent on the front-end. Start there. – Steve Souders

In a normal situation, the front-end accounts for 80% of the time it takes for the browser to render a website. In our situation, it was more like 90%.

What this means is that there are a lot of optimizations we can make to make the website even faster. Exciting!

Identifying the metrics we’ll use

For this article, we’re going to concentrate on four major website speed metrics:

  1. Time to First Byte – This is the time it takes for the server to get the first byte of the HTML to you. In our case, Pantheon’s infrastructure has this handled extremely well.
  2. Time to First Paint – This is when the browser has initially finished layout of the DOM and begins to paint the screen.
  3. Time to Last Hero Paint – This is the time it takes for the browser to finish painting the hero in the initial viewport.
  4. Time to First Interactive – This is the most important metric. This is when the website is painted and becomes usable (buttons clickable, JavaScript working, etc.).

We’re going to be looking at Chrome Developer Tools’ Performance Panel throughout this article. This profile was taken on the pre-design version of the site and identifies these metrics.

Devtools performance panel annotated

Front-end Performance with H2

HTTP/2 (aka H2) is a new-ish technology on the web that governs how servers transfer data back and forth between the browser. With the previous version of HTTP (1.1), each resource request required an entire TCP handshake that introduced additional latency per request. To mitigate this, front-end developers would aggregate resources into as few files as possible. For example, front-end developers would combine multiple CSS files into one monolithic file. We would also combine multiple small images, into one “sprite” image, and display only parts of it at a time. These “hacks” cut down on the number of HTTP requests.

With H2, these concerns are largely mitigated by the protocol itself, leaving the front-end developer to split resources into their own logical files. H2 allows multiplexing of multiple files under one TCP stream.  Because Pantheon has H2 integrated with its global CDN, we were able to make use of these new optimizations.

Identifying the problem(s)

The frontend was not optimized. Let’s take a look at the network tab in Chrome Developer Tools:

Network tab showing 1.4MB CSS file

The first thing to notice is that the aggregated CSS bundle is 1.4MB decompressed. This is extremely large for a CSS file, and merited further investigation.

The second thing to observe: the site is loading some JavaScript files that may not be in use on the homepage.

Performance tab showing flame chart of JavaScript execution

Let's optimize the CSS bundle first

A CSS bundle of 1.4MB is mongongous and hurts our Time to First Paint metric, as well as all metrics that occur afterward. In addition to having to download a larger file, the browser must also parse and interpret it.

Looking deeper into this CSS bundle, we found some embedded base64 and encoded SVG images. When using HTTP/1.1, this saved the round-trip request to the server for that resource but means the browser downloads the image regardless of whether it's needed for that page. Furthermore, we discovered many of these images belonged to components that weren’t in use anymore.

Similarly, various landing pages were only using a small portion of the monolithic CSS file. To decrease the CSS bundle size, we initially took a two-pronged approach:

  1. Extract the embedded images, and reference them via a standard CSS background-image property. Because Pantheon comes with integrated HTTP/2, there’s virtually no performance penalty to load these as separate files.
  2. Split the monolithic CSS file into multiple files, and load those smaller files as needed, similar to the approach taken by modern “code splitting” tools.

Removing the embedded images dropped the bundle to about 700KB—a big improvement, but still a very large CSS file. The next step was “code splitting” the CSS bundle into multiple files. Pantheon’s codebase makes use of various Sass partials that could have made this relatively simple. Unfortunately, the Sass codebase had very large partials and limited in-code documentation.

It’s hard to write maintainable Sass. CSS by its very nature “cascades” down the DOM tree into various components. It’s also next-to-impossible to know where exactly in the HTML codebase a specific CSS selector exists. Pantheon’s Sass codebase was a perfect example of these common problems. When moving code around, we couldn't anticipate all the potential visual modifications.

Writing maintainable Sass

Writing maintainable Sass is hard, but it’s not impossible. To do it effectively, you need to make your code easy to delete. You can accomplish this through a combination of methods:

  • Keep your Sass partials small and modular. Start thinking about splitting them up when they reach over 300 lines.
  • Detailed comments on each component detailing what it is, what it looks like, and when it’s used.
  • Use a naming convention like BEM—and stick to it.
  • Inline comments detailing anything that’s not standard, such as !important declarations, magic numbers, hacks, etc.

Refactoring the Sass codebase

Refactoring a tangled Sass codebase takes a bit of trial and error, but it wouldn’t have been possible without a visual regression system built into the continuous integration (CI) system.

Fortunately, Pantheon had BackstopJS integrated within their CI pipeline. This system looks at a list of representative URLs at multiple viewport widths. When a pull request is submitted, it uses headless Chrome to reach out to the reference site, and compare it with a Pantheon Multidev environment that contains the code from the pull request. If it detects a difference, it will flag this and show the differences in pink.

Visual Regression diff with pink highlighting changes

Through blood, sweat, and tears, we were able to significantly refactor the Sass codebase into 13 separate files. Then in Drupal, we wrote a custom preprocess function that only loads CSS for each content type.

From this, we were able to bring the primary CSS file down to a manageable 400KB (and only 70KB over the wire). While still massive, it’s no longer technically mongongous. There are still some optimizations that can be made, but through these methods, we decreased the size of this file to a third of its original size.

Optimizing the JavaScript stack

Pantheon’s theme was created in 2015 and made heavy use of jQuery, which was a common practice at the time. While we didn’t have the time or budget to refactor jQuery out of the site, we did have time to make some simple, yet significant, optimizations.

JavaScript files take much more effort for the browser to interpret than a similarly sized image or media file. Each JavaScript file has to be compiled on the fly and then executed, which utilizes up the main thread and delays the Time to Interactive metric. This causes the browser to become unresponsive and lock up and is very common on low-powered devices such as mobile phones.

Also, JavaScript files that are included in the header will also block rendering of the layout, which delays the Time to First Paint metric.

Devtools performance panel with main thread utilization hightlightedJavaScript main thread utilization

The easiest trick to avoid delaying these metrics is simple: remove unneeded JavaScript. To do this, we inventoried the current libraries being used and made a list of the selectors that were instantiating the various methods. Next, we scraped the entirety of the HTML of the website using Wget, and cross-referenced the scraped HTML for these selectors.

# Recursively scrape the site, ignore specific extensions, and append .html extension.
wget http://panther.local -r -R gif,jpg,pdf,css,js,svg,png –adjust-extension

Once we had a list of where and when we needed each library, we modified Drupal’s preprocess layer to load them only when necessary. Through this, we reduced the JavaScript bundle size by several hundred kilobytes! In addition, we moved as many JavaScript files into the footer as possible (thus improving Time to First Paint).

Additional front-end performance wins

After the new designs were rolled out, we took an additional look at the site from a performance standpoint.

Devtools performance tab showing a late layout operation* Note third party scripts (that contribute to more relayouts) are being blocked in this screenshot.

You can see in the image above that there’s an additional layout operation happening late in the rendering process. If we look closely, Chrome Developer Tools allows us to track this down.

The cause of this late layout operation down is a combination of factors: First, we’re using the font-display: swap; declaration. This declaration tells the browser to render the page using system fonts first, but then re-render when the web fonts are downloaded. This is good practice because it can dramatically decrease the Time to First Paint metric on slow connections.

Here, the primary cause of this late layout operation is that the web fonts were downloaded late. The browser has to first download and parse the CSS bundle and then reconcile that with the DOM in order to begin downloading the web fonts. This eats up vital microseconds.

Devtools network tab showing fonts downloading late

In the image above, note the low priority images being downloaded before the high priority web fonts. In this case, the first web font to download was the 52nd resource to download!

Preloading web fonts via resource hints

What we really need to do is get our web fonts loaded earlier. Fortunately, we can preload our web fonts with resource hints!

<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_3_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_2_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_4_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic/360074_1_0.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/sites/all/themes/zeus/fonts/tablet_gothic_condensed/360074_5_0.woff2" as="font" type="font/woff2" crossorigin>
Devtools network tab showing fonts downloading immediately after document

Yes! With resource hints, the browser knows about the files immediately and will download the files as soon as it is able to. This eliminates the re-layout and associated flash of unstyled content (FOUT). It also decreases the time to the Time to Last Hero Paint metric.

Devtools performance tab without a late layout operation

Preloading responsive images via resource hints

Let’s look at the Film Strip View within Chrome Developer Tools’ Network Tab. To do this, you click the toolbar icon that looks like a camera. When we refresh, we can see that everything is loading quickly—except for the hero’s background image. This affects the Last Hero Paint metric.

Devtools network tab showing hero background image loading late

If you we hop over to the Network tab, we see that the hero image was the 65th resource to be downloaded. This is because the image is being referenced via the CSS background-image property. To download the image, the browser must first download and interpret the CSS bundle and then cross-reference that with the DOM.

We need to figure out a way to do resource hinting for this image. However, to save bandwidth, we load different versions of the background image dependent on the screen width. To make sure we download the correct image, we include the media attribute on the link element.

We need to make sure we don’t load multiple versions of the same background image, and we certainly do not want to fetch the unneeded resources.

  <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary--small.jpg" as="image" media="(max-width: 640px)">
  <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary--med.jpg" as="image" media="(min-width: 640px) and (max-width: 980px)">
  <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary--med-large.jpg" as="image" media="(min-width: 980px) and (max-width: 1200px)">
  <link rel="preload" href="/<?php print $zeus_theme_path; ?>/images/new-design/homepage/hero-image-primary.jpg" as="image" media="(min-width: 1200px)">

At this point, the correct background image for the viewport is being downloaded immediately after the fonts, and this completely removes the FOUT (flash of unstyled content)—at least on fast connections.

Conclusion

Front-end website performance is a constantly moving target but is critical to the overall speed of your site. Best practices evolve constantly. Also, modern browsers bring constant updates to performance techniques and tools needed to identify problems and optimize rendering. These optimizations don’t have to be difficult, and can typically be done in hours.

Devtools performance panel showing before/after optimizations

Special thanks

Special thanks to my kickass coworkers on this project: Marc Drummond, Jerad Bitner, Nate Lampton, and Helena McCabe. And to Lullabot’s awesome designers Maggie Griner, Marissa Epstein, and Jared Ponchot.

Also special thanks to our amazing counterparts at Pantheon: Matt Stodolnic, Sarah Fruy, Michelle Buggy, Nikita Tselovalnikov, and Steve Persch.

Apr 19 2017
Apr 19

WordPress controls a whopping 27% of the CMS market share on the web. Although it grew out of a blogging platform, it can now can handle advanced functionality similar to Drupal and is a major (yet friendly) competitor to Drupal. Like Drupal, it’s open source and has an amazing community. Both communities learn from each other, but there is still much more to share between the two platforms.

Recently I had the opportunity to speak at WordCamp Miami on the topic of Drupal. WordCamp Miami is one of the larger WordCamps in the world, with a sold-out attendance of approximately 800 people.

Venn diagram showing Drupal and WordPress overlap.

What makes Drupal so great?

Drupal commands somewhere in the neighborhood of 2% of the CMS market share of the web. It makes complex data models easy, and much of this can be accomplished through the user interface. It has very robust APIs and enables modules to share one another’s APIs. Taken together, you can develop very complex functionality with little to no custom code.

So, what can WordPress take away from Drupal?

Developer Experience: More and better APIs included in WordPress Core

The WordPress plugin ecosystem could dramatically benefit from standardizing API’s in core.

  • Something analogous to Drupal’s Render API and Form API would make it possible for WordPress plugins to standardize and integrate their markup, which in turn would allow plugins to work together without stepping on each other’s toes.
  • WordPress could benefit from a way to create a custom post type in the core UI. Drupal has this functionality out the the box. WordPress has the functionality available, but only to the developer. This results in WordPress site builders searching for very specific plugins that create a specific post type, and hoping it does what they want.
  • WordPress already has plugins similar to Drupal’s Field API. Plugins such as Advanced Custom Fields and CMB2 go along way to allowing WordPress developers to easily create custom fields. Integrating something similar to this into WordPress core would allow plugin developers to count on a stable API and easily extend it.
  • An API for plugins to set dependencies on other plugins is something that Drupal has done since its beginning. It enables mini-ecosystems to develop that extend more complex modules. In Drupal, we see a module ecosystems built around Views, Fields, Commerce, Organic Groups, and more. WordPress would benefit greatly from this.
  • A go-to solution for custom query/list building would be wonderful for WordPress. Drupal has Views, but WordPress does not, so site builders end up using plugins that create very specific queries with output according to a very specific need. When a user needs to make a list of “popular posts,” they end up looking through multiple plugins dedicated to this single task.

A potential issue with including new APIs in WordPress core is that it could possibly break WordPress’ commitment to backwards compatibility, and would also dramatically affect their plugin ecosystem (much of this functionality is for sale right now).

WordPress Security Improvements

WordPress has a much-maligned security reputation. Because it commands a significant portion of the web, it’s a large attack vector. WordPress sites are also frequently set up by non-technical users, who don’t have the experience to keep it (and all of its plugins) updated, and/or lock down the site properly.

That being said, WordPress has some low-hanging fruit that would go a long way to help the platform’s reputation.

  • Brute force password protection (flood control) would prevent bots from repeatedly connecting to wp-login.php. How often do you see attempted connections to wp-login.php in your server logs?.
  • Raise the minimum supported PHP version from 5.2 (which does not receive security updates). Various WordPress plugins are already doing this, and there’s also talk about changing the ‘recommended’ version of PHP to 7.0.
  • An official public mailing list for all WordPress core and plugin vulnerabilities would be an easy way to alert developers to potential security issues. Note that there are third-party vendors that offer mailing lists like this.

Why is WordPress’ market share so large?

Easy: It can be set up and operated by non-developers—and there are a lot more non-developers than developers! Installing both Drupal and WordPress is dead simple, but once you’re up and running, WordPress becomes much easier.

Case in Point: Changing Your Site's Appearance

Changing what your site looks like is often the first thing that a new owner will want to do. With WordPress, you go to Appearance > Themes > Add New, and can easily browse themes from within your admin UI. To enable the theme, click Install, then click Activate.

WordPress user interface to download and install themesWordPress makes downloading and installing themes easy-peasy.

With Drupal, you go to Appearance, but you only see core themes that are installed. If you happen to look at the top text, you read in small text that "alternative themes are available." Below that there is a button to “Install a New Theme.”

Drupal user interface for enabling themesWith Drupal, you navigate through these links for the ability to download, then upload your themes.

Clicking the button takes you to a page where you can either 1) paste in a URL to the tarball/zip, or upload a downloaded tarball/zip. You still have to know how to to download the zip or tarball, and where to extract it, and then browse to appearance, and enable the theme.

So it goes with Drupal. The same process goes with modules and more. Drupal makes things much more difficult. 

So, what can Drupal learn from WordPress?

To continue to grow, Drupal needs to enable non-developers. New non-developers can eventually turn into developers, and will become “new blood” in the community. Here’s how Drupal can do it:

  • A built in theme and module browser would do wonders for enabling users to discover new functionality and ways to change their site’s appearance. A working attempt at this is the Project Browser module (available only for Drupal 7). The catch 22 of this is that you have to download this the old-fashioned way in order to use it.
  • The ability to download vetted install profiles during the Drupal installation process would be amazing. This would go a long way to enable the “casual explorers," and show them the power of Drupal. A discussion of this can be found here.
  • Automatic security updates is a feature that would be used by many smaller sites. Projects have been steered toward WordPress specifically because smaller clients don’t have the budget to pay developers to keep up with updates. This feature has been conceptually signed off on by Drupal’s core committers, but significant work has yet to be done.

Mitigating Security Risks

The downside for this functionality is that Drupal would need to have a writable file-system, which at it’s core, is less secure. Whether that balances out with automatic updates is debatable.

Automatic security updates and theme/module installation would not have to be enabled out of the box. The functionality could be provided in core modules that could be enabled only when needed.

What has Drupal already learned from WordPress?

Cross-pollination has already been happening for a while. Let’s take a look at what the Drupal community has already, or is in the process of, implementing:

  • Semantic versioning is one of the most important changes in Drupal 8. With semantic versioning, bug fixes and new features can be added at a regular cadence. Prior to this, Drupal developers had to wait a few years for the next major version. WordPress has been doing this for a long time.
  • A better authoring experience is something that Drupal has been working on for years (remember when there was no admin theme?). With Drupal 8, the default authoring experience is finally on par with WordPress and even surpasses it in many areas.
  • Media management is the ability to upload images and video, and easily reference them from multiple pieces of content. There’s currently a media initiative to finally put this functionality in core.
  • Easier major version upgrades is something that WordPress has been doing since it’s inception.

Drupal has traditionally required significant development work in between major versions. That however, is changing. In a recent blog post, the lead of the Drupal project, Dries Buytaert said,

Updating from Drupal 8's latest version to Drupal 9.0.0 should be as easy as updating between minor versions of Drupal 8.

This is a very big deal, as it drastically limits the technical debt of Drupal as new versions of Drupal appear.

Conclusion

Drupal and WordPress have extremely intelligent people contributing to their respective platforms. And, because of the GPL, both platforms have the opportunity to use vetted and proven approaches that are shortcuts to increased usability and usage. This, in turn, can lead to a more open (and usable) web.

Special thanks to Jonathan Daggerhart, John TuckerMatthew Tift, and Juampy NR for reviewing and contributing to this article.

Wapuu hugging a Druplicon

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