⭐ If you would like to buy me a coffee, well thank you very much that is mega kind! : https://www.buymeacoffee.com/honeyvig Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies
Showing posts with label DevTools. Show all posts
Showing posts with label DevTools. Show all posts

Monday, October 31, 2022

The Future Of Frontend Build Tools

 This article explores the concept of tooling for frontend development on the web. You will learn why we need frontend tooling, the various stages of evolution it has gone through, and the new developments that will shape the frontend build tools of the future. To follow along with this article, a general understanding of modern frontend development on the web is necessary.

Frontend build tooling is crucial to the workflow of the modern frontend developer for a host of reasons classified under improved developer and user experiences. From the developer’s perspective, frontend tooling gives us: the ability to author modules, a dev server for local development, Hot Module Replacement (HMR) for a shorter feedback loop in development mode, the ability to target legacy browsers with polyfills, processing a host of filetypes apart from JavaScript, the list goes on.

As a result, users can enjoy more capable and feature-rich applications that remain performant through techniques like code-splitting, caching, prefetching, and other resource optimization techniques — with some applications that are even able to work offline.

Frontend tooling gives us so much today that it is hard to imagine that there was a time when it was not even needed at all. A trip down memory lane could help us understand how we got here.

The Past

Before frontend applications became as complex as they are today, all JavaScript was used for was to add basic interactivity to otherwise simple HTML documents — similar to the way Adobe’s Flash was used.

There were no complex “JavaScript-heavy” applications, so, no need for any tooling to make authoring and shipping JavaScript better, but that would not remain the case.

As time went on and we started to create more involved user experiences on the web, we shifted from more static web pages to highly dynamic web applications serving user-specific data. These applications required more JavaScript than their traditional counterparts, and the limits of working with JavaScript became a lot more apparent.

There are two major ways to load JavaScript in the browser. One is with a script tag referencing a JavaScript file, and the other is to write your JavaScript directly in the HTML inside script tags.

<script src="my-javascript-file.js"></script>

<script>
    var a = 1;
    var b = 2;

    var result = a + b;
</script>

This limitation on loading JavaScript becomes a bottleneck when you have lots of JavaScript to load. There are browser limitations to loading many JavaScript files concurrently and maintainability issues with having one huge JavaScript file (like file size, scoping issues, namespace collision, and so on).

We came up with solutions like Immediately Invoked Function Expressions (IIFEs) to help with encapsulation and some of the scoping issues after which, we gained the ability to write our JavaScript in many different files. Then, we needed a way for these many files to be combined into one file to be served in the browser

The present

Being able to split our JavaScript into different files with IIFEs, it seemed like all we needed was a way to concatenate these files and ship a single file to the browser. This need saw the rise of tools like Gulp, Grunt, Brocolli, and so forth. However, we soon realized that our thinking might have been a little too simplistic.

As our applications got even more complex, matters like lack of dead code elimination, full rebuilds for small changes, and other performance issues made us realize that we needed something more than just concatenation. That gave rise to the more modern bundlers like Webpack, Parcel, and others.

With the pace of advancement in the frontend space not slowing down, we have started to observe gaps and issues with the modern build tools.

Some of the major limitations include:

  • Complex setup and configuration of some of these existing bundlers;
  • Increase in build times as applications get larger;
  • Suboptimal performance in development mode.

The rate at which things change in the JavaScript ecosystem is often fatiguing, but the upside is that the community quickly identifies problems and gets to work on potential solutions. With our sights set on improving the performance of frontend tooling, a new generation of build tools is being developed.

The Future

The limitations of the mainstream build tools of the day have led to several attempts to reimagine what a frontend build tool should be and do, and there are quite a few new build tools in the wild today.

Closer inspection will reveal that these new tools seem to be taking two major approaches to solving the problem (not necessarily mutually exclusive): a change in paradigm and a change in platform — both powered by new advancements in the web development ecosystem.

A Replatform

Frontend build tools have traditionally been built with JavaScript and, more recently, Typescript. This made sense, as JavaScript is the language of the web, and authoring build tools for the web in the same language makes it easier for more people to contribute to the effort and build a community around these tools. Still, there are inherent problems with this approach.

As a high-level language, JavaScript cannot reach native levels of performance. This means that tools built on top of this platform have a cap on how performant they can be. So, to break out of this limitation, newer build tools are being built on lower-level, inherently more performant languages like Rust.

Languages like Rust and Go have become popular options for authoring the next generation of build tools with a strong emphasis on performance. Rust, in particular, is popular not only for its performance but also for its impressive developer experience — voted the “most-loved” programming language six years in a row in the Stack Overflow Developer Survey.

In speaking about the decision to build Rome (the build tool and not the city) with Rust, Jamie Kyle says:

“Many others have communicated the performance, memory, and safety benefits of Rust before us — let’s just say everyone who has ever said Rust is good is correct. However, our biggest concern was our own productivity. [...] After some prototyping, however, we quickly realized we might actually be more productive in Rust”

Jamie Kyle in Rome Will Be Written In Rust

The project SWC is at the forefront of this idea of using Rust for frontend build tools. It is now powering projects like Next.js’s new compiler, Deno, Parcel, and others — with a performance that is many orders of magnitude above other existing build tools.

Projects like SWC prove that with a change of the underlying platform, the performance of build tools can be significantly improved.

A paradigm shift

The way a typical frontend build pipeline works today is you author JavaScript modules in many different files, run a command, the build tool picks up these modules, bundles them into a single module, converts them to a format understood by browsers, and serves that file in the browser.

To improve the performance in development mode, a lot of the optimizations that would take more time to complete are left out and are, instead run when we are bundling our production application. This ensures that it takes as little time as possible to spin up a dev server, run our application in development mode and get productive.

The bundling process still takes quite some time, though and as a project grows, build times (even in development) only get longer and longer. Wouldn’t it be great if we could somehow skip bundling altogether while still being able to write modules as usual and have the browser understand how to work with them? A new set of build tools is taking this approach, known as Unbundled Development.

Unbundled development is great. It solves a major issue with existing build tools: they often need to rebuild entire sections of your application for even trivial code changes, and build times get longer as the application grows. We lose the rapid feedback — essential for a pleasant development experience.

One might wonder, if unbundled development is so great, why isn’t it the norm today? There are two major reasons why unbundled development is only starting to gain traction: browser compatibility for cutting edge features and processing node module imports.

1. Browser compatibility for cutting edge features

Unbundled Development is powered by ES Modules (ESM), which brings a standardized module system to JavaScript — supported natively across multiple runtimes, including the browser. With this new capability, we can mark our script tags as modules and can consequently use the import and export keywords that we are all familiar with;

<script type="module" src="main.js"></script>

<script type="module">
  /** JavaScript module code goes here */
</script>

ES modules have been around for quite some time. Still, we are only able to start taking advantage of it for things like unbundled development, mostly because of how long its standardization took across all the players in the web ecosystem.

In her article about ES Modules, on Mozilla Hacks, Lin Clark says:

“ES modules bring an official, standardized module system to JavaScript. It took a while to get here, though — nearly 10 years of standardization work.”

Lin Clark in ES Modules: A Cartoon Deep-Dive

The issue of browser support or lack thereof has plagued frontend development for a long time. This is why we have vendor prefixing our CSS, sometimes the reason for polyfills, why we spend time ensuring cross-platform support for our web applications, and why it sometimes takes quite some time before we can take advantage of the latest and greatest web features in our day to day work.

Try to visit a StackBlitz project using Safari, and you will be greeted with the following screen communicating the lack of support for WebContainers in non-Chromium-based browsers.

The pace of feature adoption is not the same across browser providers, and there are often variations in how different vendors implement certain features. However, the future looks bright with initiatives like Interop 2022.

2. Processing node module imports

Most, if not all, frontend applications we write today depend on external libraries from NPM. For a typical react application, We would import react at the top of our component files like so:

import React from 'react'

/** The rest of your component code */

Trying to load this directly in the browser, as we would need to do for unbundled development, will lead to two issues. First, the browser does not know how to resolve the path to find react and secondly, the react library is published as a Common JS (CJS) module — which cannot run natively in the browser without some pre-processing.

The latter is the bigger issue here, as it is possible, and even trivial, to simply replace our node module imports with relative paths to specific files. Still, the fact that most NPM packages are written in a module format more suitable for Node JS than the browser requires that our NPM dependencies are treated specially to facilitate unbundled development.

Snowpack, in particular, handles this by processing application dependencies into separate Javascript files that can then be used directly in the browser. More on how Snowpack does this can be found here.

With ES Modules now being mainstream in most modern browsers, and clever workarounds for NPM dependencies, build tools like Vite and Snowpack can offer the option of unbundled development with drastically improved performance, snappy builds, besides super fast HMR.

Final Thoughts

Frontend development has come a long way, and our needs are constantly evolving and increasing in complexity. Build tools are an essential part of how we build frontend applications, and existing tools are falling short of the mark sparking the development of new tools that reimagine how build tools should be designed.

With a huge focus on performance, ease of use, and less complex configuration, the next generation of build tools are poised to power ambitious frontend applications for some time to come.

Are you excited about the recent developments in this space? Let me know in the comments what you think about the upcoming innovations and the current landscape.

Thursday, October 27, 2022

What’s New In DevTools

 Our friendly DevTools at Mozilla, Google, Microsoft, and Apple have once again been hard at work. And in this article, I’ll attempt to summarize the most impactful new features that are now available in browser developer tools.

So much has happened over these past few months that I may have missed a few things, but hopefully, you’ll find something that helps you in this article. There should be a little bit for everyone, whatever your level of experience with web development is, and whatever browser you use.

So, without further ado, let’s jump right in.

Note: Because Edge is based on Chromium, the open-source browser engine that also powers Chrome, all of the Chrome features listed below are also available in Edge (unless otherwise noted).

CSS Debugging

We’ve got a lot of long-awaited and profoundly impacting new features in CSS lately.

To name just a few:

  • Container Queries help us style components based on the size of their containers,
  • The :has() pseudo-class lets us style elements based on what they contain, and
  • CSS Cascade Layers make it easy to gracefully handle increasing complexity in our websites’ code.

But, although these features are amazing, shipping support for them in browsers is only part of the story. For people to comfortably use them, documentation and tooling are necessary too.

We’re in luck because both Container Queries and CSS Cascade Layers have associated DevTools features now.

Specifically, Container Queries are supported in Safari WebInspector and Chrome DevTools where information about the corresponding @container at-rules is displayed when viewing CSS in the Styles sidebar.

Chrome, Safari, and Firefox DevTools also now have support for CSS Cascade layers in their Elements (or Inspector) tools. The layer to which a particular rule belongs is now displayed next to that rule:

Maybe a little less popular, but still very useful, the hwb() CSS function makes it possible to express colors in a more natural way based on hue and an amount of whiteness and blackness.

hwb() is now supported in all major browsers, and Chrome (and Chromium-based browsers), as well as Firefox, both have support for it in DevTools. That means they will show hwb in the autocomplete list when editing CSS in the Styles (or Rules) sidebar and will show the same color swatch used for other color formats too.

Next, it has also become easier to edit CSS in the Styles sidebar and get meaningful autocompletion results across browsers.

Chrome now previews all CSS variable values when autocompleting the var() function, not just colors, and it also displays @supports and @scope at-rules.

Safari now uses fuzzy matching when auto-completing CSS, making it much faster to type property names and values.

And Firefox added support for the color-mix() function in its auto-complete too.

Talking about Firefox, the browser has had the amazing Inactive CSS feature since 2019, which lets you know when a particular CSS declaration doesn’t have an impact on the current element.

Firefox continued to improve this feature over time and recently added more coverage for use cases such as warning when border-image-* is used on elements within a table with border-collapse or warning when width or height are used on ruby elements.

And, while we’re on the topic of inactive CSS, the Chrome team is actually working on a similar feature. In fact, it’s already available in Chrome (and all Chromium-based browsers) by enabling the CSS authoring hints experiment under Settings (F1) > Experiments in DevTools and should become available by default with Chrome 108.

Over the past few years, browser DevTools has gotten fantastic layout debugging tools to inspect, understand, and tweak grid and flex layouts. More recently, Safari has been adding more features in this area as well.

You can now use CSS alignment controls in the Styles sidebar and inspect Flexbox layouts too.

JavaScript Debugging

Let’s change gears a bit and talk about JavaScript debugging.

It’s very common to use external libraries and frameworks in a JavaScript codebase, to avoid having to re-implement things that have already been solved. For some years already, DevTools have allowed users to ignore third-party scripts when debugging (see docs for Chrome, Edge, Firefox).

Hiding scripts makes it easier to debug your code. It avoids ending up in foreign-looking library code when stepping through your own logic.

Recently, Firefox shipped a new feature that builds on top of this. You can now ignore pieces of code within a file. If you have a function that keeps getting called all the time but isn’t interesting for what you’re trying to debug, you can simply ignore that one function now.

Over in Chrome (and Chromium), a whole lot of small and not-so-small JavaScript debugging improvements were made:

The Page source tree was improved, and there’s now a way to group sources by authored (to show the original source files, thanks to source maps) or deployed (to show the actual files on the server).

It is now also possible to live edit the code of a function while debugging. If you’re paused at a breakpoint inside a function and want to test a quick fix, you can edit the code right there and save the file. The function will be restarted with the new code.

Next, stack traces for asynchronous operations are now reported entirely, showing you the full story of what happened before your current breakpoint, even if those things happened asynchronously.

Stack traces now also automatically ignore known third-party scripts, making it much easier to debug your own code.

Performance Investigation

Web performance is probably an area where we depend on tools even more than in other areas. You can’t really guess what’s running slow or eating too much memory until you profile your webpage. Fortunately, we keep on getting new options to investigate performance and memory problems, making our lives easier.

In fact, Chrome shipped an entirely new panel dedicated just to this!

Note: This panel is available in Chrome only and not in other Chromium-based browsers.

The Performance Insights panel shipped with Chrome 102 and has gradually gotten better and better, with recent additions like First Contentful Paint, Last Contentful Paint, Time To Interactive metrics and text flashes identification.

Think of the Performance Insights panel as a simpler version of the (sometimes scary) Performance panel:

Talking about the Performance panel, it recently got a brand new Interactions track in Chromium-based browsers, giving you a way to know when user events occur and how long they last, making it easier to debug responsiveness issues.

Edge has also been busy shipping new features in this area.

In the Performance tool, source maps can now be used to display original function names, even when sharing recorded profiles with other people:

In the Memory tool, you now get a summary of your heap snapshots organized by node types. Heap snapshots are hard to dig through, and these node types make it easier to see what is using the most memory on your webpage. There are also new ways to filter memory retainers to find memory leak culprits quickly.

Finally, Firefox has also been active in this area over the past few months. A number of years ago, Firefox created a brand new Performance tool for its own use. The idea, at the time, was to have a tool to debug performance problems in the browser code itself. But over time, the tool was adapted to become useful to web developers too.

And now, the final changes have been made, and the old Firefox DevTools’ Performance panel has fully been replaced with the new one:

Network Debugging

Debugging your frontend code is important, but sometimes problems can happen in the network layer of your app when communicating with your server. Thankfully, a few very useful features were recently added to the Network tools in various browsers.

In Edge, a new column was added to the Network log. The Fulfilled by column makes it easier to debug your service worker logic and Progressive Web Apps.

You can now discover straight away whether a request was handled by the service worker, the browser cache, or your server.

Firefox just shipped a completely redesigned version of its Edit and Resend feature. This feature has been available in Firefox for a long time already and is a great way to debug your server-side APIs or just test something quickly.

With it, you can right-click on any HTTP request displayed in the Network tool, select Edit and Resend, then manipulate the request parameters, headers, and body, and finally send the modified request.

Firefox completely redesigned it recently. It’s now much easier to edit the parameters before sending a new request.

And finally, Safari has added quite a few great features in this area too. You can now block network requests entirely, and you can also locally override requests by using regular expressions.

Editor Integration

Microsoft also does VSCode, which is a very popular code editor amongst web developers, and some time ago, the Edge team released the Edge Tools extension for VS Code. The extension gives you an embedded browser and the browser DevTools right in VS Code alongside your code.

This year, the team continued to work on the extension and added more features. In particular, the following things are now possible:

  • The extension now has the Console and Application tools available. Previously, only the Elements and Network tools were available. Console logs used to go to VSCode’s output, but now they also go to the Console tool in the embedded DevTools.
  • The embedded browser has been completely redesigned and features a lot of emulation and rendering options to test your webpage under different conditions. For example, you can emulate different media types or the prefers-code-scheme media feature. You can also emulate different color vision deficiencies.
  • Next, you can launch the embedded browser and DevTools simply by right-clicking an HTML file in VS Code.
  • Finally, you can use VS Code’s Quick Fix options to automatically fix a number of issues reported by the extension in your code.

One more thing, if you like using Visual Studio (not VS Code), note that the team released an extension for it too. Check out the Edge Developer Tools for Visual Studio extension.

Test Automation

It’s possible to automate browsers nowadays, and it can be very useful for testing. With browser automation libraries such as WebDriver, Puppeteer, and Playwright, you can write tests that mimic what users would do on your website and verify that these scenarios continue working over time, as you make changes to your product.

This area is in constant evolution; in particular, the WebDriver spec is evolving with a new bi-directional version. Also, the Chrome DevTools team has been innovating quite a lot lately. They shipped a new tool called the Recorder last year and have been improving it over time.

Here are some of the new features that got added to the panel in recent months:

  • It’s now possible to wait until elements are visible and clickable before continuing a recording.
  • Element selectors are better supported.
  • You can import and export recorded flows as JSON.
  • Double-click, mouse over, and right-click events can be recorded too.
  • There’s also an option to replay a recording slowly or step-by-step.
  • And, finally, the Recorder tool now supports extensions to export recordings to a variety of test automation formats, such as Cypress, WebPageTest, Nightwatch, or WebdriverIO.

Miscellaneous Updates

Phew, that was a lot! But we’re not done. Let’s wrap this up with a list of somewhat random but very useful features.

Chrome made a lot of source maps and stack traces improvements, providing a more stable and easier-to-use debugging experience. If you usually debug your JavaScript code with logs, now may be a good time to give breakpoint debugging a try and see if it speeds things up for you.

Talking about logging, they also made it possible to properly style logs with ANSI escape codes.

Next, you can now pick colors from anywhere on your screen when changing colors in the Styles sidebar.

Note: This was made possible thanks to the EyeDropper API, which you can also use on your web pages.

Edge shipped a feature to publish and retrieve production source maps from Azure, making it much easier to securely debug your code in production even when you don’t want to publish source maps and original source code to your server.

Read more about publishing your source maps and consuming them from DevTools.

The team also opened a new public feedback repository on GitHub which you can use to report ideas, issues, and features or just discuss them.

Finally, they shipped a redesigned Welcome tool where you can find all sorts of useful videos and links to documentation.

Switching to Firefox, the DevTools team continued to keep their Compatibility panel up to date with new browser compatibility data, so you can get relevant cross-browser support issues right when debugging your CSS.

The team also made it possible to disable and re-enable any event listener for a given element in the Inspector.

Finally, Edge just shipped a cool new experimental feature that enables one to type commands and access common browser and DevTools features from one keyboard shortcut.

The Command palette experiment lets you enter commands in the browser by pressing Ctrl+Q (note that prior to Edge 108, the shortcut was Ctrl+Shift+Space).


And that’s it for today. I hope you found a few things that will be useful for your web development projects.

DevTools has gotten impressively full of features over the years, and it’s hard to keep track, but here are a few pointers that I hope will make it easier to discover new features:

And with this, thanks for reading, and if you have great DevTools tips you want to share with everyone, please drop us a comment!

Friday, June 17, 2022

What’s That (Dev) Tool?

 How many browser DevTools panels do you commonly use in your day-to-day web development? One? Three? Probably not that many more. In this article, her's spotlight on a number of tools that people don’t use or even know about. Let’s dive in!

Have you ever looked to see what other tools were available to you within the DevTools toolbox? You’re probably using the same few panels over and over again — I know I am!

It turns out there are more than thirty (30!) individual panels in Chrome DevTools (as well as other Chromium-based browsers, such as Edge). Safari and Firefox have fewer panels but still probably more than you use on any given day.

 When I realized this, it gave me an idea for a silly game where you’d try to name as many panels as you could in under one minute. Play it here and try your luck (no cheating, OK?): What’s That Tool?

 

This game is silly, of course. As a web developer, remembering the exact names of each and every tool in DevTools isn’t important. It’s more important to know how to use these tools when needed.

But the game does prove a point: there are many more tools than what people use or even know about! The whole goal of this game is — by the time the minute is gone and the full list is displayed — to realize, “oh wow, that’s a lot of tools I had no idea even existed.”

So, why are there so many? Let’s face it, DevTools is crammed with buttons, tabs, and features. How did we get here, and is there a way out?

The Story Of An Explosion

In the early 2000s, web development was very different than it is now. Back then, most of the complexity lay in generating the right HTML code from your server. The browsers’ ability to “view source” was enough to debug the odd table colspan problems. JavaScript was only getting started on the web, and CSS was nowhere near the feature-full language it is now.

So, on top of the old alert() debugging trick, the very few tools we used for front-end code debugging were very specialized; they only did one thing. Venkman only did JavaScript debugging, Aardvark was focused on inspecting elements, and Console2 displayed nice JavaScript log messages.

Joe Hewitt brought it all together under one tool called Firebug which was a Firefox extension. It was an absolute revolution for web developers throughout the world! Around 2010, Firebug was probably the most used front-end debugging tool, and Firefox was a dominant browser. Crazy! Right?

Even if you have never used Firebug and started your web development journey in more recent times, I’m willing to bet this user interface feels familiar.

Though the DevTools we use now aren’t very different from what Firebug used to look like, it felt like we had fewer things to worry about back then and, therefore, fewer tools to help them with.

As the screenshot above shows, there weren’t many tools at all:

  • Console to view logs and execute JavaScript,
  • HTML tab to view and edit the page’s DOM and the applied CSS styles,
  • JavaScript debugger,
  • Network tab to check the downloaded resources and HTTP requests.

Fast forward to 15 years in the future, to now. The user interface of the browser tools we use hasn’t changed much, but the sheer number of panels skyrocketed! Here’s a quick and incomplete (and very approximative) history of when new panels got introduced in Chrome DevTools:

YearPanels
2008Console, Elements, Sources, Network, JavaScript profiler
2010Performance (called Timeline at the time)
2013Rendering, Layers
2014CSS Overview, Network Conditions
2015Security, Memory
2016Animations
2017Coverage, Lighthouse (called Audits at the time), Performance Monitor, Network Request Blocking
2018Changes, Accessibility
2020Media, WebAuthn, WebAudio, Issues
2021Memory Inspector, Recorder
2022Performance Insights

There are many reasons why the number of new panels keeps growing. Some of them are good, while others are more questionable:

  • The number of features and APIs available to the Web platform is constantly and quickly increasing. Now, there are many more things a web developer can do on the web than 15 years ago. Some of those things can’t easily be debugged with the 4 or 5 tools we had back then, thus it required new panels in DevTools.
  • Our discipline is way more developed than it used to be. Front-end web development was maybe regarded as a little less interesting or important 15 years ago. It has now proven itself as a much deeper field of computer engineering that requires knowledge of not only programming but also performance optimization, accessibility, user experience, progressive enhancements, and more.
    These things tend to sometimes require specialized tools too.
  • People who write the code for the browsers and DevTools also need tools themselves, and sometimes they end up as new panels. The Protocol Monitor panel in Chromium is a great example of this.
  • Deleting things is really hard! You’re bound to break people’s workflows if you do it. So, things tend to accumulate over time. Chrome, for example, has three tools to do performance optimizations: Performance, Performance Insights, and JavaScript profiler.
  • Finally, there seems to be a general tendency to add new things rather than improve what’s already in place. I get it; it’s more exciting to most people to build new things rather than fix bugs. But it tends to make the software more complicated over a long period of time. And this has most probably been at play in DevTools, too.

In any case, we’re here now with probably what’s one of the most advanced tooling suites any application platform could dream of. But it’s also one of the most complex that no one uses to its full potential.

Is This A Problem?

Yes! Put simply, DevTools is a very complicated product, and its user interface can be scary.

Where other products have five main user scenarios, DevTools has dozens, if not hundreds. Do you need to simulate a mobile screen? Detect color contrast? Convert between font units? See JSON responses? DevTools can do it all! And these are just a few random examples.

So, with that many options and features, it isn’t a surprise that the user interface is complex so much that new users can feel very overwhelmed in their first-run experience. But even experienced users don’t necessarily know what’s available outside of the same few panels they’re used to.

This is starting to become a serious usability problem, in my opinion, one that may sometimes discourage new people in their learning journey. People coming to DevTools today are likely to be used to newer development products that are much easier to use. The digital tool space is undergoing a big change in this direction, and the browser DevTools haven’t started moving yet.

This isn’t a simple problem to solve either. As I said before, there are some really good reasons why we need a lot of specialized tooling. So, the complexity is needed, but I believe it should be opt-in rather than opt-out!

Indeed, the DevTools learning curve is getting very steep because so much information is presented to users right from the start, and people have to learn to ignore the parts they don’t know about or think they don’t need.

Why Don’t We Just Clean It All Up?

Well, it’s complicated. There are many user scenarios built in DevTools, and there are probably as many workflows as there are people using DevTools out there. Even the most rarely used tools are here for a reason, and the few people who use them may depend on them.

In my experience working on DevTools, removing old/un-maintained/rarely used panels for the sake of making the codebase easier to work with always proved to be a bad idea, especially when done without enough customer research.

In fact, while I worked on Firefox, we tried removing the Fonts panel at some point in Firefox DevTools, and the response was pretty instant and strong — so much that we put it back in! We lacked the necessary customer understanding of how this tool was being used and what unique scenarios it supported.

In 2016, the 3D view panel had to be removed because it wasn’t supported anymore by the new (back then) Firefox architecture. To this day, more than six years later, people still complain that it’s gone (note that you can still use it in Edge)!

As a final example, the Chrome team removed the Properties sidebar pane in 2020 but later added it again after seeing how much people needed it.

Usage numbers alone aren’t a good measure of a tool’s worth. Some tools may be used by a few people only, but they may depend on them to do their jobs. Proper user research and understanding of the various user roles and scenarios (and DevTools has a lot of them!) are needed to be able to simplify the product.

A Way Out?

I want to propose two directions that I think have a lot of potential when it comes to improving the situation with DevTools:

  1. simplifying the DevTools core and opening it up to more powerful extensions, so that users make their own tools;
  2. being bold and taking risks with a radically user-friendly user interface.

A Powerful But Simple Core, Boosted With Extensions

Visual Studio Code is such an amazing product! Many people use it and not only web developers. It’s built on a very strong core that can be extended tremendously.

This way, the people who work on VS Code don’t have to worry about all of the features that people might need. VS Code is a bit like DevTools in the sense that no two people have the same needs and workflows, and there are hundreds of ways to use the product.

So, the team’s job is to build a solid foundation that allows basic editing and top that up with an extension API that lets other people dig deep into the platform and add extra features.

There are many advantages to this, but one that is of particular interest to me here is that complexity is opt-in. When you install VS Code the first time, it’s not overwhelming. It’s a text editor, and you can use it to edit text right off the bat. But if your project has special needs, like checking code quality or doing some custom syntax highlighting, then you can install all the fancy extensions you want and get the extra functionality you need.

The VS Code extension API goes really deep into how much you can customize the editor, and I believe this is largely responsible for its success.

DevTools, however, is built differently. You can also install extensions in the browser to add new panels to DevTools, but there aren’t very many useful extensions available outside of the major framework ones (React, for example). The teams who work on DevTools are the ones who pretty much do all the tools that a web developer might need.

By using the browser extensions API, creating a new panel in DevTools isn’t too hard, but the API isn’t as advanced as in VS Code. In particular, there is no way to extend the existing tools to augment their functionality. This is a serious limitation that I think is responsible for the low number of useful extensions we have at our disposal.

As an example, the amazing Motions DevTools extension allows you to view and edit animations on the web. But it’s limited to its own panel container, and it can’t integrate with the Elements panel right next to it, which would have been useful to simplify user workflows and re-use existing components, such as the color picker.

Motion DevTools overview trailer

I believe we need to go further than that. We need a more powerful set of APIs that makes it possible to create the specialized features that some people might need without complexifying the default DevTools experience for everyone else.

The Extensible Web Manifesto is very similar to this approach. It advocates for providing low-level capabilities for third-party developers to create their own experiences before they — perhaps one day — become part of the core if they prove to be popular.

Taking Risks And Designing A Radically User-Friendly UI

Another very much-needed way to move forward and improve the status of our DevTools is to be willing to take a few risks, be bold, and test new UI ideas.

As I said in the intro, the shape of DevTools hasn’t really changed in about 15 years. I think we’re very much overdue for at least some re-design. We need to bring the UI into the 2020s, start using more modern interface patterns, and make the overall experience less daunting.

The folks working on Safari Web Inspector at Apple tried something like this around 2013. They applied some of their design principles from other products like XCode or iTunes in an attempt to simplify their DevTools toolbar.

Although they have now gone back to a more traditional tabbed navigation which seems to work better with developers, I appreciate this early attempt to make a more user-friendly interface that’s also more consistent with what people knew at the time.

This also goes to show that very special care needs to be taken to bring developers along a journey of user interface change in DevTools.

This brings me to the team working on the Edge DevTools now (which, full disclosure, I am part of). I believe this is currently the only team doing something in this area.

Our current experiment is called Focus Mode, and it is effectively the first attempt at redesigning the entire DevTools product UI.

Focus Mode is available to users of DevTools on the Canary and Dev pre-release channels of Microsoft Edge by enabling the “Focus Mode” experiment from the DevTools Settings. Most users of these channels should in fact already have it on, as our team is gradually rolling out the feature and listening to user feedback in order to ensure this is not disruptive to existing workflows and a welcome change.

Based on this feedback, we will continue rolling out Focus Mode to users of the Beta channel and eventually to the normal release version of Edge.

Now, it might not seem like a big change at first, but this is only a first step in an iterative approach to creating a more approachable user interface. Again, changing things in this product is complicated, so our team is taking things slow.

But if you look closely, there are a few major changes to the UI that try to make things less cluttered and more streamlined.

The most visible changes are located in the top toolbar. Here is an animation showing a comparison of what the toolbar looks like with and without Focus Mode:

  • The list of warnings, errors, and infos is now gone from the toolbar, and instead, it appears as colored badges on the Console and Issues panel tabs, removing some clutter.
  • The Settings, Feedback, and main menu icons have been grouped under just one menu button in the top-right corner, further reducing clutter.
  • Tabs now have icons, so they’re easier to see and tell apart.

Here are a few more things coming with Focus Mode.

The + button in the toolbar shows all available tools with their icons making it easier to re-open a tool you’ve closed before and maybe more inviting to try tools you haven’t tried yet.

It’s also possible to switch the tabs to a vertical orientation. Being positioned to the left and hiding the labels further reduces the noise in the central part of the window, letting you focus on the code. Additionally, it matches UI patterns that people are growing used to in other tools (for example, the Activity bar in VS Code or vertical tabs in Edge).

And finally, the drawer in DevTools was re-designed. The drawer is this area of the user interface that appears at the bottom when you press the Esc key on the keyboard, and that normally contains the Console.

It was introduced as a way to have access to the Console at the same time as other tools, and all browser DevTools have this now. But over the years, the Chrome team added more and more things to the drawer, in particular secondary tools that were useful but not quite popular enough for a spot on the main tab bar (e.g., the Rendering panel was added there).

I think it’s come to a point where it’s hard to know for sure which tool is available in which area. Edge — with Focus Mode — is taking a different approach. The drawer is now called Quick View, which is always visible at the bottom of the toolbox (so you don’t even have to know to press Escape) and can be used to display any tool you want.

I’m very excited about where Focus Mode is going, and I can’t wait for our team to start exploring what’s next in this area.

If you want to try Focus Mode out, make sure you have a copy of Edge (you can also get a pre-release version if you prefer to have the latest changes), open DevTools, and if you don’t already have it ON, press F1, then go to Experiments and check the Focus Mode box.

Let the team know what you think about it — and if you have other ideas — by filing new issues on our DevTools GitHub repository.

I believe that a user-friendly DevTools that is both more welcoming to learners and inclusive of everyone’s needs is possible, and together, we can make it happen. As a community, let’s demand more from our friendly DevTools teams!

There are full-time dedicated DevTools product engineering teams working for each browser vendor. They keep adding new features and fixing bugs, but they can only do a good job with our collective help.

Tell them if the UI doesn’t work for you. Let them know about your most common workflows. How many clicks did you need? Do you often forget where things are? Do you wish things were named differently? Input like this can lead to changes that make a big difference for millions of users.

As mentioned, we’re actively seeking feedback on this experiment and other DevTools features. You can leave comments on our GitHub repository. Other browsers also like to hear feedback on their DevTools which you can do at the Mozilla bugzilla tracker for Firefox, on the Chromium bug tracker for Chrome, and on the WebKit bugzilla tracker for Safari.

Thanks for reading! And see you next time.


Saturday, June 11, 2022

The Future Of Frontend Build Tools

 This article explores the concept of tooling for frontend development on the web. You will learn why we need frontend tooling, the various stages of evolution it has gone through, and the new developments that will shape the frontend build tools of the future. To follow along with this article, a general understanding of modern frontend development on the web is necessary.

Frontend build tooling is crucial to the workflow of the modern frontend developer for a host of reasons classified under improved developer and user experiences. From the developer’s perspective, frontend tooling gives us: the ability to author modules, a dev server for local development, Hot Module Replacement (HMR) for a shorter feedback loop in development mode, the ability to target legacy browsers with polyfills, processing a host of filetypes apart from JavaScript, the list goes on.

As a result, users can enjoy more capable and feature-rich applications that remain performant through techniques like code-splitting, caching, prefetching, and other resource optimization techniques — with some applications that are even able to work offline.

Frontend tooling gives us so much today that it is hard to imagine that there was a time when it was not even needed at all. A trip down memory lane could help us understand how we got here.

The Past

Before frontend applications became as complex as they are today, all JavaScript was used for was to add basic interactivity to otherwise simple HTML documents — similar to the way Adobe’s Flash was used.

There were no complex “JavaScript-heavy” applications, so, no need for any tooling to make authoring and shipping JavaScript better, but that would not remain the case.

As time went on and we started to create more involved user experiences on the web, we shifted from more static web pages to highly dynamic web applications serving user-specific data. These applications required more JavaScript than their traditional counterparts, and the limits of working with JavaScript became a lot more apparent.

There are two major ways to load JavaScript in the browser. One is with a script tag referencing a JavaScript file, and the other is to write your JavaScript directly in the HTML inside script tags.

<script src="my-javascript-file.js"></script>

<script>
    var a = 1;
    var b = 2;

    var result = a + b;
</script>

This limitation on loading JavaScript becomes a bottleneck when you have lots of JavaScript to load. There are browser limitations to loading many JavaScript files concurrently and maintainability issues with having one huge JavaScript file (like file size, scoping issues, namespace collision, and so on).

We came up with solutions like Immediately Invoked Function Expressions (IIFEs) to help with encapsulation and some of the scoping issues after which, we gained the ability to write our JavaScript in many different files. Then, we needed a way for these many files to be combined into one file to be served in the browser

The present

Being able to split our JavaScript into different files with IIFEs, it seemed like all we needed was a way to concatenate these files and ship a single file to the browser. This need saw the rise of tools like Gulp, Grunt, Brocolli, and so forth. However, we soon realized that our thinking might have been a little too simplistic.

As our applications got even more complex, matters like lack of dead code elimination, full rebuilds for small changes, and other performance issues made us realize that we needed something more than just concatenation. That gave rise to the more modern bundlers like Webpack, Parcel, and others.

With the pace of advancement in the frontend space not slowing down, we have started to observe gaps and issues with the modern build tools.

Some of the major limitations include:

  • Complex setup and configuration of some of these existing bundlers;
  • Increase in build times as applications get larger;
  • Suboptimal performance in development mode.

The rate at which things change in the JavaScript ecosystem is often fatiguing, but the upside is that the community quickly identifies problems and gets to work on potential solutions. With our sights set on improving the performance of frontend tooling, a new generation of build tools is being developed.

The Future

The limitations of the mainstream build tools of the day have led to several attempts to reimagine what a frontend build tool should be and do, and there are quite a few new build tools in the wild today.

Closer inspection will reveal that these new tools seem to be taking two major approaches to solving the problem (not necessarily mutually exclusive): a change in paradigm and a change in platform — both powered by new advancements in the web development ecosystem.

A Replatform

Frontend build tools have traditionally been built with JavaScript and, more recently, Typescript. This made sense, as JavaScript is the language of the web, and authoring build tools for the web in the same language makes it easier for more people to contribute to the effort and build a community around these tools. Still, there are inherent problems with this approach.

As a high-level language, JavaScript cannot reach native levels of performance. This means that tools built on top of this platform have a cap on how performant they can be. So, to break out of this limitation, newer build tools are being built on lower-level, inherently more performant languages like Rust.

Languages like Rust and Go have become popular options for authoring the next generation of build tools with a strong emphasis on performance. Rust, in particular, is popular not only for its performance but also for its impressive developer experience — voted the “most-loved” programming language six years in a row in the Stack Overflow Developer Survey.

In speaking about the decision to build Rome (the build tool and not the city) with Rust, Jamie Kyle says:

“Many others have communicated the performance, memory, and safety benefits of Rust before us — let’s just say everyone who has ever said Rust is good is correct. However, our biggest concern was our own productivity. [...] After some prototyping, however, we quickly realized we might actually be more productive in Rust”

Jamie Kyle in Rome Will Be Written In Rust

The project SWC is at the forefront of this idea of using Rust for frontend build tools. It is now powering projects like Next.js’s new compiler, Deno, Parcel, and others — with a performance that is many orders of magnitude above other existing build tools.

Projects like SWC prove that with a change of the underlying platform, the performance of build tools can be significantly improved.

A paradigm shift

The way a typical frontend build pipeline works today is you author JavaScript modules in many different files, run a command, the build tool picks up these modules, bundles them into a single module, converts them to a format understood by browsers, and serves that file in the browser.

To improve the performance in development mode, a lot of the optimizations that would take more time to complete are left out and are, instead run when we are bundling our production application. This ensures that it takes as little time as possible to spin up a dev server, run our application in development mode and get productive.

The bundling process still takes quite some time, though and as a project grows, build times (even in development) only get longer and longer. Wouldn’t it be great if we could somehow skip bundling altogether while still being able to write modules as usual and have the browser understand how to work with them? A new set of build tools is taking this approach, known as Unbundled Development.

Unbundled development is great. It solves a major issue with existing build tools: they often need to rebuild entire sections of your application for even trivial code changes, and build times get longer as the application grows. We lose the rapid feedback — essential for a pleasant development experience.

One might wonder, if unbundled development is so great, why isn’t it the norm today? There are two major reasons why unbundled development is only starting to gain traction: browser compatibility for cutting edge features and processing node module imports.

 

1. Browser compatibility for cutting edge features

Unbundled Development is powered by ES Modules (ESM), which brings a standardized module system to JavaScript — supported natively across multiple runtimes, including the browser. With this new capability, we can mark our script tags as modules and can consequently use the import and export keywords that we are all familiar with;

<script type="module" src="main.js"></script>

<script type="module">
  /** JavaScript module code goes here */
</script>

ES modules have been around for quite some time. Still, we are only able to start taking advantage of it for things like unbundled development, mostly because of how long its standardization took across all the players in the web ecosystem.

In her article about ES Modules, on Mozilla Hacks, Lin Clark says:

“ES modules bring an official, standardized module system to JavaScript. It took a while to get here, though — nearly 10 years of standardization work.”

Lin Clark in ES Modules: A Cartoon Deep-Dive

The issue of browser support or lack thereof has plagued frontend development for a long time. This is why we have vendor prefixing our CSS, sometimes the reason for polyfills, why we spend time ensuring cross-platform support for our web applications, and why it sometimes takes quite some time before we can take advantage of the latest and greatest web features in our day to day work.

Try to visit a StackBlitz project using Safari, and you will be greeted with the following screen communicating the lack of support for WebContainers in non-Chromium-based browsers.

The pace of feature adoption is not the same across browser providers, and there are often variations in how different vendors implement certain features. However, the future looks bright with initiatives like Interop 2022.

2. Processing node module imports

Most, if not all, frontend applications we write today depend on external libraries from NPM. For a typical react application, We would import react at the top of our component files like so:

import React from 'react'

/** The rest of your component code */

Trying to load this directly in the browser, as we would need to do for unbundled development, will lead to two issues. First, the browser does not know how to resolve the path to find react and secondly, the react library is published as a Common JS (CJS) module — which cannot run natively in the browser without some pre-processing.

The latter is the bigger issue here, as it is possible, and even trivial, to simply replace our node module imports with relative paths to specific files. Still, the fact that most NPM packages are written in a module format more suitable for Node JS than the browser requires that our NPM dependencies are treated specially to facilitate unbundled development.

Snowpack, in particular, handles this by processing application dependencies into separate Javascript files that can then be used directly in the browser. More on how Snowpack does this can be found here.

With ES Modules now being mainstream in most modern browsers, and clever workarounds for NPM dependencies, build tools like Vite and Snowpack can offer the option of unbundled development with drastically improved performance, snappy builds, besides super fast HMR.

Final Thoughts

Frontend development has come a long way, and our needs are constantly evolving and increasing in complexity. Build tools are an essential part of how we build frontend applications, and existing tools are falling short of the mark sparking the development of new tools that reimagine how build tools should be designed.

With a huge focus on performance, ease of use, and less complex configuration, the next generation of build tools are poised to power ambitious frontend applications for some time to come.

Are you excited about the recent developments in this space? Let me know in the comments what you think about the upcoming innovations and the current landscape.