<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Nicolás J. Engler</title>
    <description>The latest articles on Forem by Nicolás J. Engler (@nicolasjengler).</description>
    <link>https://forem.com/nicolasjengler</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F32677%2F5c0aa071-2871-40a8-bf67-d8732853a37b.jpeg</url>
      <title>Forem: Nicolás J. Engler</title>
      <link>https://forem.com/nicolasjengler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/nicolasjengler"/>
    <language>en</language>
    <item>
      <title>From development and into product management, yet another tale</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Mon, 28 Mar 2022 02:22:39 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/from-development-and-into-product-management-yet-another-tale-29aj</link>
      <guid>https://forem.com/nicolasjengler/from-development-and-into-product-management-yet-another-tale-29aj</guid>
      <description>&lt;p&gt;It is a rather common path for developers, no matter what branch they're located in, to go from &lt;strong&gt;development&lt;/strong&gt; to &lt;strong&gt;technical leadership&lt;/strong&gt;, and eventually –sometimes– into &lt;strong&gt;management&lt;/strong&gt;. As I've already stated frequently in the past, my career path has been traversed mostly solo, not in the sense of freelancing on my own but rather in the sense of never having a clear mentor to guide me through the muddy waters of the tech industry, an industry I decided to become a part of more than 10 years ago.&lt;/p&gt;

&lt;p&gt;When I first started as a developer, considering that moment to be after having my first real freelancing gig, my boyfriend and mentor passed away, and ever since I've been doing my best to absorb the experience of others to understand what is the best way to conduct myself in whichever role I'm currently situated. My experience with an in-house role was fairly limited and lasted only about 6 months when I moved to Buenos Aires, but every instance before and after my attempt at working in a "traditional" physical office were done from a small town, giving me zero access to a face-to-face dev community, and thus limiting me to, again, getting all my knowledge and third-party experiences only from the wonderous world of the Internet.&lt;/p&gt;

&lt;p&gt;I always considered myself to have a keen eye for organization and attention to detail, which gave me a great advantage not only when it came to translating designs into HTML and CSS, but also to organize my work without too much hardship. Kanban boards, ToDo lists, excerpts for clients, Gantt charts, they were never really something strange to me, and they indeed came super handy when first starting freelance jobs. This is a quality I assume naturally helped me take somewhat of a management role while developing the sites or apps I was working on, no matter if independently or as part of a team. When collaborating with a group, most project managers were thankful of this capacity, which is why I decided to value it and kept on nourishing it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Even if organizing the tasks in the project isn't your main responsibility, helping your team have a clear vision of the current status and next steps is always desired. Same goes for proposals for features and approaches to solving different problems, for example.
&lt;/h4&gt;

&lt;p&gt;As my responsibilities naturally grew when I kept on expanding my skillset as a developer, I eventually started freelancing for &lt;a href="https://waytoodigital.com/" rel="noopener noreferrer"&gt;WayTooDigital&lt;/a&gt;, and I induce that my contractor, Agustín, found the capacity of a developer to be able manage a team from a technical standpoint valuable, since he offered me to join in a somewhat more solid manner soon after a couple of projects. Accepting was one of the best decisions I've ever made, as it opened up the possibility to get my hands dirty directly with clients and the product design process altogether, and this was mostly enabled by Agustín's trust that I was up for the task from beginning to end.&lt;/p&gt;

&lt;p&gt;Meanwhile, I kept getting more involved in the lifecycle of a product and I was able to add my, and my team's, own touch to the ideation and execution of each project, allowing us to grow both in the management department and in the latest technologies used for different types of requirements. Navigating this stage while trying to excel in both engineering and the arrangements of instructions to get a product to life is incredibly challenging, and this is where I had to make a decision on which front I wanted to be the most involved in. I eventually decided that my interest leaned towards management and this is where I steered into properly organizing what I needed on my end to provide my team with the best tools and processes for them to work and focus on their expertise areas. I was rather inexperienced in this front, so I ran through a list of what I was able to grasp were the areas that successful product managers focused on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Helping the team in a "cross-functional" approach, considering each step of the way as a key part of a whole so they can collaborate holistically&lt;/li&gt;
&lt;li&gt;Accompanying designers and developers in depth when reviewing feature proposals or deliveries to properly prioritize and stage releases&lt;/li&gt;
&lt;li&gt;Helping clients, product owners and stakeholders understand already set realistic roadmaps with input from all parts of the team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As I kept on getting deeper and deeper into this, I struggled to keep up with the requirements &lt;em&gt;I&lt;/em&gt; considered were needed for my team to be successful, especially having a hard time with Proof of Worth and impostor syndrome on my end. &lt;a href="https://twitter.com/shreyas/" rel="noopener noreferrer"&gt;Shreyas Doshi&lt;/a&gt; helped me a great bunch with this when I read the following Twitter thread:&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;Proof of Worth, a gentle product management rant:&lt;br&gt;&lt;br&gt;When an early-career PM starts on a team, they might be told that they must build credibility with the builders (eng, design, analytics…)&lt;br&gt;&lt;br&gt;They must prove their worth.&lt;br&gt;&lt;br&gt;Fine advice, but it can go wrong long-term.&lt;br&gt;&lt;br&gt;1/11&lt;/p&gt;— Shreyas Doshi (&lt;a class="mentioned-user" href="https://dev.to/shreyas"&gt;@shreyas&lt;/a&gt;) &lt;a href="https://twitter.com/shreyas/status/1266797669088804865?ref_src=twsrc%5Etfw" rel="noopener noreferrer"&gt;May 30, 2020&lt;/a&gt;
&lt;/blockquote&gt; 

&lt;p&gt;I know I'm cutting this short, and there isn't exactly a conclusion to this entry, as this role for me is still an active living and breathing ongoing process, but I thought that sharing how it went so far might help other people in the same place as me, who might not exactly have a mentor or someone to lean on to explore an unconventional road to an already established role in the industry. &lt;/p&gt;

&lt;p&gt;Best of luck to all new managers out there! It's a wild wild world, but we got what it takes to make the best of it.&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>My typical day</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Sun, 14 Feb 2021 12:56:52 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/my-typical-day-4mp3</link>
      <guid>https://forem.com/nicolasjengler/my-typical-day-4mp3</guid>
      <description>&lt;p&gt;This post was somewhat influenced by &lt;a href="https://css-irl.info/my-typical-day/" rel="noopener noreferrer"&gt;Michelle Barker’s post&lt;/a&gt;, which in turn was encouraged by &lt;a href="http://cdevroe.com/2021/01/07/my-typical-day/" rel="noopener noreferrer"&gt;Colin Devroe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Routine is good for me as long as I can keep a straight score, but as soon as something ruptures those habits everything falls into chaos, which is why the last couple of years (and I mean that literally, it must be around 2 years or a little bit less) that I ended up finding a system that works for me and has a decent amount of structure but still is flexible enough to allow interruptions without throwing everything into disarray. &lt;/p&gt;

&lt;p&gt;Because of everything I’ve written in the previous paragraph I won’t be using hours but rather chunks of the day to describe what I do daily:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Early morning:&lt;/strong&gt; I wake up, do my skin care routine, and prepare some quick breakfast (it usually is a banana smoothie with strawberries or blueberries, peanut butter and honey. It can also be eggs, toasts and coffee). Once breakfast is ready I head over to my desk -lately that means the living room table of my apartment- to either read emails or organize the day. If there are bills to pay or I need to settle something, this is the moment where I try to be as productive as possible: concise answers, resolutive approaches.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mid-morning:&lt;/strong&gt; Once those early morning tasks are done, I start by prioritizing what part of my work needs to be done with more urgency. Said work can either be bug fixing, feature work or documentation (depends on the client I’m working for at the moment). Some days are harder than others when it comes to having the drive to get to business, which is why I’ve been setting goals as a way to fuel my motivation. So far it’s been working good enough. At this time, if I get hungry this is the moment where I’d grab some cookies, yogurt or an apple.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Middle of the day:&lt;/strong&gt; Munch munch, crunch crunch. This is where I take a little time to, only lately, prepare a home-cooked meal with my boyfriend and sit and watch a short YouTube video while we have lunch together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Early afternoon:&lt;/strong&gt; Where my energy is at its lowest, which I why I use this time to answer Slack messages, set up calls, and check for new emails. I try to keep all activities that don’t require much focus in this timespan so I don’t, for example, code mindlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Late afternoon:&lt;/strong&gt; Sometimes this means 6pm, other times this means 1am. It all depends on the task I’ve been working on, how much I procrastinated or how complex it is. I been trying to keep it to 7pm at maximum, and that’s mainly because I head to the gym at the end of the day to catch a quick 50-minutes crossfit lesson (or an acting lesson if it is Tuesday) and be back home by 8 or 9pm. Once back home I take a shower, cook something with my boyfriend and our roommate, watch a TV show episode (lately that is Ryan Murphy’s “Pose”, but a couple of weeks ago it was Attack On Titan so we could catch up to the fourth season), and if possible be in bed by midnight. I used to read a decent amount a couple of years ago and I’ve been trying to get back to that but I have to admit I’ve been failing miserably (which is sad because with the whole Twilight Renaissance the internet has seen lately I would very much like to read the entirety of Midnight Sun).&lt;/p&gt;

&lt;p&gt;Aaand that is a &lt;strong&gt;typical day for me&lt;/strong&gt;. I obviously switch it up whenever something new comes up, like having to babysit my nephew (I became an uncle like 4 months ago, yay!) or go to a doctor’s appointment, but the overall succession of events looks like the list above.&lt;/p&gt;

&lt;p&gt;Looking forward to read your typical days!&lt;/p&gt;

</description>
      <category>routine</category>
      <category>development</category>
      <category>work</category>
      <category>life</category>
    </item>
    <item>
      <title>How to fix unexpected gaps when printing flex-based elements in Safari</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Wed, 10 Feb 2021 15:10:35 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/how-to-fix-unexpected-gaps-when-printing-flex-based-elements-in-safari-1hk1</link>
      <guid>https://forem.com/nicolasjengler/how-to-fix-unexpected-gaps-when-printing-flex-based-elements-in-safari-1hk1</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; if possible, switch all your Flexbox containers for block-level elements. Changing &lt;code&gt;display: flex&lt;/code&gt; for &lt;code&gt;display: block&lt;/code&gt; should do the trick as long as you don’t mind stacked content when printing (otherwise you’ll need to tinker around to rearrange your print layout)&lt;/p&gt;

&lt;p&gt;I’ve been working for a client for almost 3 years now, his project involves students and teachers that usually &lt;em&gt;require printing&lt;/em&gt; guides to use whenever &lt;em&gt;they don’t have an internet connection&lt;/em&gt; to use on their devices.&lt;/p&gt;

&lt;p&gt;The platform uses different modular types of content (some of that is video along text, other are images in a grid, and other components are just plain text), which is why whenever building the print styles I decided to remove any extra whitespace along with background images, plain images, iframes etcetera. When testing said print styles, everything seemed in order in major browsers like Chrome, Firefox and Edge, but Safari, for some reason, included weird large gaps in between paragraphs and/or titles and content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Theory 1:&lt;/strong&gt; hidden images, iframes and grids were causing these gaps. Seemed unlikely given those elements all had the &lt;code&gt;display&lt;/code&gt; property value set to &lt;code&gt;none&lt;/code&gt;. After checking out these elements in the devtools, manually removing them from the DOM and printing a PDF, it was obvious this wasn’t the solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Theory 2:&lt;/strong&gt; CSS &lt;a href="https://css-tricks.com/almanac/properties/p/page-break/" rel="noopener noreferrer"&gt;page breaks&lt;/a&gt; needed to be set in order to get this page printing properly. After setting up &lt;code&gt;page-break-before&lt;/code&gt;, &lt;code&gt;page-break-after&lt;/code&gt; and &lt;code&gt;page-break-inside&lt;/code&gt; property values wherever the issues arised, I tried to print a PDF using Safari but none of these changes gave me the expected results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Theory 3:&lt;/strong&gt; Similar to what happens with some older JavaScript plugins when combined with Flexbox, there might be sizing issues when printing, causing large computed numbers for widths or heights. After switching all my &lt;code&gt;display&lt;/code&gt; properties to use a &lt;code&gt;block&lt;/code&gt; value rather than &lt;code&gt;flex&lt;/code&gt;, everything showed up as it should in the generated print PDF file using Safari.&lt;/p&gt;

&lt;p&gt;I was lucky enough that the print layout for this use case was simple, and stacked content was the inteded result. If you need to print layouts that are a bit more complex, you are most likely going to have to dedicate some time to rearrange your components so they play nicely.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>safari</category>
      <category>flexbox</category>
      <category>css</category>
    </item>
    <item>
      <title>I can still see it: a case for graceful degradation</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Wed, 13 Jan 2021 22:57:27 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/i-can-still-see-it-a-case-for-graceful-degradation-5ef1</link>
      <guid>https://forem.com/nicolasjengler/i-can-still-see-it-a-case-for-graceful-degradation-5ef1</guid>
      <description>&lt;p&gt;There are plenty of pieces written about how we should &lt;strong&gt;strive for progressive enhancement and leave graceful degradation behind&lt;/strong&gt;, and I understand the case for that given how the current front-end development ecosystem works, and the status of the tools we're currently given to work on a day-to-day basis. &lt;/p&gt;

&lt;p&gt;One of the main reasons I'm so uncomfortable working with junior developers is that they are at a loss when you start explaining to them how package managers work, since &lt;strong&gt;we're no longer toying with just HTML, CSS and JavaScript files&lt;/strong&gt;. Third-party dependencies are often needed for progressive enhancement to be achieved. Juniors are unaware of what Node.js and npm are, how to get them (don't even get me started on the differences between OSes), how to use them on their project. &lt;strong&gt;The learning curve is steep and progressive enhancement requires fully-fledged scripts that understand the bells and whistles of a product&lt;/strong&gt;, or an entire dependency that takes care of that. &lt;/p&gt;

&lt;p&gt;It's understandable for larger companies or larger teams to have the time to train their juniors to apply this approach, or have a dedicated developer working on it, but for smaller team it is additional pressure on deadlines and there's an awful lot of guilt-tripping from peers when you decide to go for graceful degradation rather than take the time to progressively enhance a feature or product.&lt;/p&gt;

&lt;p&gt;If we head over to the &lt;a href="https://www.w3.org/wiki/Graceful_degradation_versus_progressive_enhancement" rel="noopener noreferrer"&gt;W3 Wiki&lt;/a&gt; on &lt;strong&gt;Graceful Degradation vs Progressive Enhancement&lt;/strong&gt;: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your product by definition is so dependent on scripting that it makes more sense to maintain a “basic” version rather than enhancing one (Maps, email clients, feed readers)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's how it works for smaller teams. I realized this while talking to a client that needed to ship ASAP in order to meet a hard deadline. The case was the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Have an accordion that is able to expand and contract on click&lt;/li&gt;
&lt;li&gt;Have it be fully accessible, critical importance on keyboard accesibility and semantics&lt;/li&gt;
&lt;li&gt;Make it readable even in older browsers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I had a tough time balancing my options: create a small script from scratch to make this happen, include an external library, OR use &lt;strong&gt;a native HTML element that degrades gracefully and is fully readable in unsupported browsers&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Enter HTML &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details" rel="noopener noreferrer"&gt;details&lt;/a&gt;
&lt;/h4&gt;

&lt;p&gt;After some discussion of time vs. maintainability, accesibility, and other factors, the client decided that it was best to go for the native &lt;em&gt;details&lt;/em&gt; element, fully supported in the latest version of most browsers, almost-entirely customizable, and gracefully degrading to a list on older browsers. This was the perfect solution when considering our timeframe and feature requirement. Check out &lt;a href="https://codepen.io/nicolasjengler/pen/qBaMaVJ" rel="noopener noreferrer"&gt;this pen on CodePen&lt;/a&gt; that I worked on and helped me decide what approach to pick.&lt;/p&gt;

&lt;p&gt;The bare HTML end result looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;details&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"warning"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Facts and knowledge about COVID-19&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Some text to be hidden.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;/details&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;details&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"info"&lt;/span&gt; &lt;span class="na"&gt;open&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;For the public&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Social distance, quarantine and isolation&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Hand hygiene, cough etiquette, cleaning and laundry&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;When children have acute respiratory tract infections&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Risk groups and their relatives&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/details&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;details&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;Facts and knowledge about COVID-19&lt;span class="nt"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Some text to be hidden.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;/details&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty straightforward, right? You can wrap around that snippet in a tag of your choice to put it in a specific predefined context that's semantic, and both &lt;code&gt;details&lt;/code&gt; and &lt;code&gt;summary&lt;/code&gt; elements are customizable via CSS without much complexity.&lt;/p&gt;

&lt;p&gt;The W3 Wiki is pretty biased towards Progressive Enhancement, but cases like this introduce a simple question: &lt;strong&gt;is it worth overengineering something that requires a minimal investment of time and LITERALLY zero effort to maintain?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lea Verou &lt;a href="https://lea.verou.me/2020/05/todays-javascript-from-an-outsiders-perspective/" rel="noopener noreferrer"&gt;wrote an article&lt;/a&gt; that isn't entirely related to this, but presents another question that is worth asking: do we need to keep overcomplicating stuff for developers whenever it isn't needed or crucial? &lt;strong&gt;How do we plan to keep introducing folks to front-end development given how fast the requirements list is growing?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>accesibility</category>
      <category>html</category>
      <category>native</category>
    </item>
    <item>
      <title>How to improve loading time performance with Gulp and Puppeteer on a Drupal site</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Tue, 30 Jun 2020 04:05:34 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/how-to-improve-loading-time-performance-with-gulp-and-puppeteer-on-a-drupal-site-653</link>
      <guid>https://forem.com/nicolasjengler/how-to-improve-loading-time-performance-with-gulp-and-puppeteer-on-a-drupal-site-653</guid>
      <description>&lt;p&gt;By now &lt;strong&gt;Drupal&lt;/strong&gt; is a fairly known content management framework, which is why some companies choose to build their site using it given its history and how robust it is. &lt;/p&gt;

&lt;p&gt;I've been working for a client for about 2 years now, and they have a rather large Drupal site with multiple dependencies. For this client in particular I'm in charge of front-end development and some back-end integrations, and currently we're using a &lt;strong&gt;Gulp&lt;/strong&gt;-based workflow to manage static assets. This process involves &lt;strong&gt;Sass&lt;/strong&gt; compilation, image compression, and JS minification/concatenation, among other stuff.&lt;/p&gt;

&lt;p&gt;In a routine check, a member of the client's team decided to run the site through Google's &lt;strong&gt;PageSpeed Insights&lt;/strong&gt; and to my dismay our initial score was pretty low, ranging between 20 and 30. After this report I decided to dig in a bit deeper and see how we could improve our PSI score which led to some interesting takeaways. Not only we were using a bunch of third party scripts for different tasks (some scripts weren't even necessary anymore) but we also realised that Drupal tends to position render-blocking content at the top of the page, inside the &lt;code&gt;head&lt;/code&gt; tag, that could be either deferred, preloaded or moved to the bottom of the DOM right before the closing &lt;code&gt;body&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5cgbdewtxjecs7jqll93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5cgbdewtxjecs7jqll93.png" alt="Low PageSpeed Insights score" width="512" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But moving our render-blocking content to the bottom of the document wasn't enough, since we were now getting pretty awful performance on metrics like our &lt;strong&gt;First Meaningful Paint&lt;/strong&gt;. Based on this we decided to see if there was a proper way to create critical CSS and include said declarations inline in the head of the DOM, this would help us improve our FMP and &lt;strong&gt;perceived loading times&lt;/strong&gt; keeping the benefits of moving the rest of our render blocking resources to the end.&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach No. 1: Hand-picked critical CSS
&lt;/h2&gt;

&lt;p&gt;Our first thought when moving forward to create critical CSS rules to include on the site was to generate a hand-crafted separate file. This process was running smoothly until we tried to import some partial Sass that depended on &lt;strong&gt;Bootstrap&lt;/strong&gt; mixins and variables, which eventually led to dependency hell defeating the purpose of critical CSS. We were unable to create a critical CSS file since we were including a bunch of unneeded declarations because of dependencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbe6fi3sygxhu4gvepr0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbe6fi3sygxhu4gvepr0r.png" alt="Dependency hell using custom Sass file" width="430" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Approach No. 2: Fetch the homepage critical CSS using a tool like Chrome/Chromium DevTools' Code Coverage
&lt;/h2&gt;

&lt;p&gt;After learning about Chrome/Chromium DevTools' Code Coverage we thought &lt;em&gt;"What if we could run a headless browser when the build process runs and use the DevTools to fetch our homepage's actually used CSS which also includes stuff like navbar, menu, text sizing and color, etcetera?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Enter &lt;strong&gt;Puppeteer&lt;/strong&gt;: Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol. Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.&lt;/p&gt;

&lt;p&gt;The first step to include Puppeteer in our workflow was to add it as a dependency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; puppeteer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then we include the dependency in our &lt;code&gt;gulpfile.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;puppeteer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After Puppeteer is available to work within our Gulpfile we proceed to create a new task (named &lt;code&gt;css-critical&lt;/code&gt;) in charge of generating the critical CSS file and declare a variable to hold the URL from which Puppeteer will fetch our critical CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;gulp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-critical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://exampleurl.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With that in place, we now need to declare a new empty string variable to hold whatever we gather as critical CSS, and launch a headless browser with a viewport of 1440x900 pixels:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;gulp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-critical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://exampleurl.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;criticalCSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;headless&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`--window-size=1440,900`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;defaultViewport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our next step is to open a new page, start the CSS Coverage tool, load our site, store the results in a variable called &lt;code&gt;cssCoverage&lt;/code&gt; and finally stop the CSS coverage tool.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;gulp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-critical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://exampleurl.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;criticalCSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;headless&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`--window-size=1440,900`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;defaultViewport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startCSSCoverage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cssCoverage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stopCSSCoverage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we'll need to select the used data ranges returned by the Coverage tool in order to compose our final CSS file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;gulp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-critical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://exampleurl.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;criticalCSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;headless&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`--window-size=1440,900`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;defaultViewport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startCSSCoverage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cssCoverage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stopCSSCoverage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;cssCoverage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ranges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;criticalCSS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6lwtt6gt15qhvqh1prpg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6lwtt6gt15qhvqh1prpg.png" alt="Example of Chrome's DevTools CSS Coverage" width="512" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After this is done and ready, we'll proceed to close the page, close the browser and dump the content of our &lt;code&gt;criticalCSS&lt;/code&gt; into an actual file, that will later be inlined into our Drupal &lt;code&gt;html.html.twig&lt;/code&gt; template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;gulp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css-critical&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://exampleurl.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;criticalCSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;headless&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`--window-size=1440,900`&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="na"&gt;defaultViewport&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startCSSCoverage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;goto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;load&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cssCoverage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;coverage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stopCSSCoverage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;cssCoverage&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ranges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;criticalCSS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;range&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;writeFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css/critical.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;criticalCSS&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With everything in place, all that's left to do is to inject our critical CSS file into our template and move all render-blocking CSS and JS to the bottom of our DOM. &lt;code&gt;html.html.twig&lt;/code&gt; should end up looking something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;
  &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="n"&gt;body_classes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;logged_in&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'user-logged-in'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'path-frontpage'&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'path-'&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt; &lt;span class="n"&gt;root_path&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;clean_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;node_type&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'node--type-'&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt; &lt;span class="n"&gt;node_type&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;clean_class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;db_offline&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;'db-offline'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;!&lt;/span&gt;&lt;span class="no"&gt;DOCTYPE&lt;/span&gt; &lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;html_attributes&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{{ placeholder_token|raw }}"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;head_title&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nf"&gt;safe_join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' | '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"screen"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="k"&gt;include&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="o"&gt;~&lt;/span&gt; &lt;span class="s1"&gt;'/css/critical.css'&lt;/span&gt; &lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="n"&gt;missing&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{{ placeholder_token|raw }}"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body_classes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"#main-content"&lt;/span&gt; &lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"visually-hidden focusable skip-link"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="s1"&gt;'Skip to main content'&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;page_top&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;page&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="n"&gt;page_bottom&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;css&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{{ placeholder_token|raw }}"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;js&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;bottom&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;placeholder&lt;/span&gt; &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{{ placeholder_token|raw }}"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;html&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! This approach helped us move our PageSpeed Insights score between 50 and 60 points up from the initial 20-30 we were getting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F07nn01iqj3hpyfxdygim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F07nn01iqj3hpyfxdygim.png" alt="Higher PageSpeed Insights score after applying changes" width="512" height="217"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some improvements that can potentially be done:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Remove duplicate declarations by comparing critical CSS generated and regular CSS&lt;/li&gt;
&lt;li&gt;Remove unwanted elements that might not be considered critical for the site, i.e.: a slider, video decoration, animations&lt;/li&gt;
&lt;li&gt;Create a page-by-page approach to serve critical CSS that's adjusted for each page rather than just one page used in general&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>performance</category>
      <category>node</category>
      <category>puppeteer</category>
      <category>gulp</category>
    </item>
    <item>
      <title>React explained to newcomers</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Sat, 26 Jan 2019 14:14:16 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/react-explained-to-newcomers-2i72</link>
      <guid>https://forem.com/nicolasjengler/react-explained-to-newcomers-2i72</guid>
      <description>&lt;h3&gt;
  
  
  How would you explain the benefits of React to a dev that has never worked with the library?
&lt;/h3&gt;

&lt;p&gt;I'm mentoring a friend that's currently mastering JavaScript/jQuery, but I'd like to eventually introduce him to a more modern stack (most likely webpack, React AND Vue, Babel, etcetera). I was wondering what's the best approach to explain the benefits of React as a whole without making that explanation too complex.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>react</category>
    </item>
    <item>
      <title>The case against style consistency in the profile of product designers</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Sun, 23 Dec 2018 05:09:25 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/the-case-against-style-consistency-in-the-profile-of-product-designers-1mn3</link>
      <guid>https://forem.com/nicolasjengler/the-case-against-style-consistency-in-the-profile-of-product-designers-1mn3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cyNxHqdk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yjkb9g1jnaohay6zi2qp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cyNxHqdk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/yjkb9g1jnaohay6zi2qp.png" alt="Geometric figures"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have always been a very anxious person, at least ever since I can remember. This can be either a blessing or a course for developers, and designers, depending on the situation. Allow me to give you an example I've come to experience firsthand: &lt;strong&gt;if I need some sort of drive to grind through a task or to learn some new skill in order to keep up with the latest technologies (and trust me, there are plenty of those), anxiety controlled in a healthy manner can be weaponized and turned to my favor. But on the other hand, when things go wild, anxiety can also paralyze me.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The last couple of weeks have found me revising my portfolio and social media profiles over and over again just because I feel I'm not good enough. I'm constantly seeing these amazing &lt;em&gt;Dribbble&lt;/em&gt; and &lt;em&gt;Instagram&lt;/em&gt; profiles of great product designers or coders, and they seem to be all about great visuals and total consistency, they are entirely devoted to developing and selling their own brand by showing all of the amazing products they've worked on. &lt;strong&gt;I truly believe I don't have that in me.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Ever since I started my professional life, in those first years under the "web designer" title, I've worked on a wide range of products, sites, apps, and whatever else you can think of that involves planning, design and/or development. The projects I tackled go from sites for the local dairy industry to animations for an Android app to find accountability partners. My mind ran wild thinking of ways I could've improved and cleaned up my online presence using these past experiences to show some sort of brand and patternization of whatever I presented and introduced to the public, but that just isn't possible because for every project I had put into part of myself and my craft, there was also a big range of differences that impeded said "patternization".&lt;/p&gt;

&lt;p&gt;After some days of deliberation and crippling thoughts, I wondered why is it that I absolutely had to show this side of myself? It's true that I tend to overshare my little experiments. &lt;strong&gt;I create pens in CodePen and post videos on Twitter/Instagram as well as gifs on Mastodon, but I should be doing that, right? I want my potential clients/employers to see that, I want them to hire me because they enjoy that part of myself&lt;/strong&gt;, because they want that in their projects and creations.&lt;/p&gt;

&lt;p&gt;We're constantly bombarded with this expectation that product designers must excel in every field they work on, whether that is UX, UI, front-end development, planning, back-end development, etcetera. I can't do that, because I end up dreading the tasks involved in that approach, and because I have to refrain from doing some things that bring me a lot of joy, like sharing and fiddling with experimental snippets of code in front-end playgrounds. &lt;strong&gt;I've come to terms with the fact that my design and marketing side might not be as strong as other people out there, and that it is OK, we can't be good at everything we do. Being at peace with this allows me to keep on pushing through with the things I'm good at&lt;/strong&gt;, and just as I'm finishing these lines I remember when I wrote &lt;a href="https://medium.com/@nicolasjengler/you-are-not-a-failure-8e4fec7c660f"&gt;this&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>style</category>
      <category>portfolio</category>
      <category>onlinepresence</category>
      <category>marketing</category>
    </item>
    <item>
      <title>How to assign a custom layout to a page according to its URL alias in Drupal 8</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Sun, 28 Oct 2018 14:38:48 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/how-to-assign-a-custom-layout-to-a-page-according-to-its-url-alias-in-drupal-8-en6</link>
      <guid>https://forem.com/nicolasjengler/how-to-assign-a-custom-layout-to-a-page-according-to-its-url-alias-in-drupal-8-en6</guid>
      <description>&lt;p&gt;For the past couple of weeks I've been working as a contractor for an NYC-based NGO that's using Drupal 8 to power their site. My first task was to move their styleguide from a design done in Figma to actual components built with HTML and CSS inside Drupal, but there was a trick: the styleguide had to be set up as some sort of general type content and all I was able to customize was the URL alias.&lt;/p&gt;

&lt;p&gt;I went on and duplicated the &lt;code&gt;page.html.twig&lt;/code&gt; in our subtheme in order to customize that and work there, later renamed the file to &lt;code&gt;page--styleguide.html.twig&lt;/code&gt;. After that I created all related content and used a URL alias that was &lt;code&gt;styleguide&lt;/code&gt; happily knowing that (as stated by Drupal's documentation) it would pick up the custom layout automatically without the need of indicating anything.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Narrator:&lt;/strong&gt; the custom layout wasn't picked up by Drupal&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I wasn't able to find why the custom layout was not being used, so I decided to do some googling and found a useful function to suggest Drupal which layout to use. After some tweaking I ended up with the following snippet (placed inside my &lt;code&gt;.theme&lt;/code&gt; file)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Set up hook&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;themename_theme_suggestions_page_alter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt;$suggestions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$variables&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

  &lt;span class="c1"&gt;// Check if the content being loaded is a node&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$node&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;\Drupal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;routeMatch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getParameter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'node'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the node's ID&lt;/span&gt;
    &lt;span class="nv"&gt;$nid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$node&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the URL alias based on the ID of the node&lt;/span&gt;
    &lt;span class="nv"&gt;$alias&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;\Drupal&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'path.alias_manager'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getAliasByPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/node/'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$nid&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Check if the URL alias matches the styleguide's&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$alias&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'/styleguide'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

      &lt;span class="c1"&gt;// Suggest Drupal to use whatever custom layout we have defined inside /templates&lt;/span&gt;
      &lt;span class="nv"&gt;$suggestions&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'page__styleguide'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm by no means a Drupal expert, quite the contrary, so I'm not entirely sure if this solution is properly executed or performant for that matter. If you know a better way to solve this, feel free to leave a comment!&lt;/p&gt;

</description>
      <category>drupal</category>
      <category>web</category>
      <category>cms</category>
      <category>development</category>
    </item>
    <item>
      <title>4 tips on how to work remotely from a small town and not die trying</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Mon, 08 Oct 2018 01:21:14 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/4-tips-on-how-to-work-remotely-from-a-small-town-and-not-die-trying-3bh3</link>
      <guid>https://forem.com/nicolasjengler/4-tips-on-how-to-work-remotely-from-a-small-town-and-not-die-trying-3bh3</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F378s6rtia385sf7krhct.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F378s6rtia385sf7krhct.jpg" alt="Image of people working in an open space" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Originally on &lt;a href="https://medium.com/@nicolasjengler/4-tips-on-how-to-work-remotely-from-a-small-town-and-not-die-trying-b5e4ad0a2c72" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Working remotely from a small town can sometimes be even harder than doing it from a big city, which is why a good support system and some online friends can make a big difference.&lt;/p&gt;

&lt;p&gt;I’ve been working remotely for about 8 years now. My first gig consisted of getting a new web design from a .psd file to a layout using HTML and CSS (I was incredibly under-qualified for that job, by the way) in my bedroom while living at my parents’ house.&lt;/p&gt;

&lt;p&gt;If you’ve never been an in-house employee or freelancer, working remotely is usually easier the first couple of months or years, since you’ve never experienced the dynamics of working side-by-side with colleagues or having a pre-defined routine guidelined by social norms, which is why you find the habits that coexist inside an office unknown to yourself. Working remotely is hard sometimes if you lack the hability to find drive and inspiration to get you going or the self-determination to have a set of working hours, for example. But if you live in a big city, you have co-working spaces that can be great if working in a shared space is what gets you going or if what you need is some outside pressure to get dressed in clothes other than pajamas. Sadly, small-towns don’t usually have co-working spaces (at least in third-world countries), and living in a small town while getting your job done is way different than being a digital nomad passing by for a couple of days or weeks, and that is why I decided to make this list.&lt;/p&gt;

&lt;p&gt;While I’ve had a 6-month gap in my journey of being a remote front-end developer/product designer (that deserves another post), approximately 96% of my work life has been done in a town of a population that rounds to 45.000 people. Here are some bullets on how to be as productive and motivated as possible while being remote and living in a small city:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Share an office or get used to coffee shops:&lt;/strong&gt;&lt;br&gt;
If after some time of working remotely you start missing that human connection and the small-talk that happens in an office, I suggest you find an office that’s willing to rent you a desk or go to a small bar and turn yourself into a regular customer.&lt;br&gt;
I, personally, rent a part of the office a couple of friends have to run their print shop. We split some expenses and I get a place in the household, so to speak. Being around people definitely helps me avoid the dread of being home alone, and it also forces me to get out and walk a couple of blocks, catch some fresh air, and maybe even run some errands in the process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;If you don’t find a local community, search for one online:&lt;/strong&gt;&lt;br&gt;
As you can probably imagine, a city of 45.000 in an under-developed country isn’t exactly a place swarming with designers and developers, which is why finding a community here is incredibly difficult. Because of this I found myself building an online community with some former colleagues, and also using spaces such as the &lt;a href="https://www.toptal.com/" rel="noopener noreferrer"&gt;Toptal&lt;/a&gt; or the &lt;a href="https://trydesignlab.com/" rel="noopener noreferrer"&gt;Designlab&lt;/a&gt; Slack teams. Sometimes I even Skype with some friends and we each work on our own stuff while chatting a bit and asking for feedback, this is great to feel yourself accompanied by people that works on similar stuff as you do and bond at the same time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Get into webinars:&lt;/strong&gt;&lt;br&gt;
Meetups and gatherings will probably happen a few times or be completely nonexistent in your town, which is why you should get used to webinars in order to get cutting edge training and education in real time. I’d also suggest to coordinate meetups and let the town know, you’ll probably be the only one attending but sometimes other unknown colleagues or people looking to get into the industry might appear and realize they’re not alone!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Make sure your working space or home-office is in proper conditions and adequately delimited:&lt;/strong&gt;&lt;br&gt;
I’m going to assume that if you’re working from a remote location you’ll probably also want to take advantage of working from your own place, and for this reason you’ll need to have a proper working space (or an office inside your home if that’s a possibility), adequately decorated and separated from the rest of the other rooms in your place, with all the tools necessary to get the job done. This is useful to keep in mind that this is where work happens, and also to maintain focus while grinding without getting distracted by your significant other(s) or family.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that’s it! That’s what has gotten me through to this day while working a lot of miles away from the HQs of my employers. While these are not some life-revealing tips, as obvious as they seem, I didn’t realize that most of them would improve the quality of my job and the work-life balance needed to avoid burning out, so I’m leaving those here for other that might be in my position to find out.&lt;/p&gt;

&lt;p&gt;I honestly hope this leads you to a better situation work-wise. Until the next post!&lt;/p&gt;

</description>
      <category>work</category>
      <category>remote</category>
      <category>freelancer</category>
      <category>workplace</category>
    </item>
    <item>
      <title>Explain the new spec for CSS' font-variant property like I'm five</title>
      <dc:creator>Nicolás J. Engler</dc:creator>
      <pubDate>Wed, 04 Oct 2017 12:23:54 +0000</pubDate>
      <link>https://forem.com/nicolasjengler/explain-the-new-spec-for-css-font-variant-property-like-im-five-94p</link>
      <guid>https://forem.com/nicolasjengler/explain-the-new-spec-for-css-font-variant-property-like-im-five-94p</guid>
      <description></description>
      <category>css</category>
      <category>explainlikeimfive</category>
      <category>styles</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
