Browsing Tag: Web

    web design

    Managing Long-Running Tasks In A React App With Web Workers — Smashing Magazine

    10/15/2020

    About The Author

    Awesome frontend developer who loves everything coding. I’m a lover of choral music and I’m working to make it more accessible to the world, one upload at a …
    More about
    Chidi

    In this tutorial, we’re going to learn how to use the Web Worker API to manage time-consuming and UI-blocking tasks in a JavaScript app by building a sample web app that leverages Web Workers. Finally, we’ll end the article by transferring everything to a React application.

    Response time is a big deal when it comes to web applications. Users demand instantaneous responses, no matter what your app may be doing. Whether it’s only displaying a person’s name or crunching numbers, web app users demand that your app responds to their command every single time. Sometimes that can be hard to achieve given the single-threaded nature of JavaScript. But in this article, we’ll learn how we can leverage the Web Worker API to deliver a better experience.

    In writing this article, I made the following assumptions:

    1. To be able to follow along, you should have at least some familiarity with JavaScript and the document API;
    2. You should also have a working knowledge of React so that you can successfully start a new React project using Create React App.

    If you need more insights into this topic, I’ve included a number of links in the “Further Resources” section to help you get up to speed.

    First, let’s get started with Web Workers.

    What Is A Web Worker?

    To understand Web Workers and the problem they’re meant to solve, it is necessary to get a grasp of how JavaScript code is executed at runtime. During runtime, JavaScript code is executed sequentially and in a turn-by-turn manner. Once a piece of code ends, then the next one in line starts running, and so on. In technical terms, we say that JavaScript is single-threaded. This behavior implies that once some piece of code starts running, every code that comes after must wait for that code to finish execution. Thus, every line of code “blocks” the execution of everything else that comes after it. It is therefore desirable that every piece of code finish as quickly as possible. If some piece of code takes too long to finish our program would appear to have stopped working. On the browser, this manifests as a frozen, unresponsive page. In some extreme cases, the tab will freeze altogether.

    Imagine driving on a single-lane. If any of the drivers ahead of you happen to stop moving for any reason, then, you have a traffic jam. With a program like Java, traffic could continue on other lanes. Thus Java is said to be multi-threaded. Web Workers are an attempt to bring multi-threaded behavior to JavaScript.

    The screenshot below shows that the Web Worker API is supported by many browsers, so you should feel confident in using it.

    Showing browser support chart for web workers
    Web Workers browser support. (Large preview)

    Web Workers run in background threads without interfering with the UI, and they communicate with the code that created them by way of event handlers.

    An excellent definition of a Web Worker comes from MDN:

    “A worker is an object created using a constructor (e.g. Worker() that runs a named JavaScript file — this file contains the code that will run in the worker thread; workers run in another global context that is different from the current window. Thus, using the window shortcut to get the current global scope (instead of self within a Worker will return an error.”

    A worker is created using the Worker constructor.

    const worker = new Worker('worker-file.js')

    It is possible to run most code inside a web worker, with some exceptions. For example, you can’t manipulate the DOM from inside a worker. There is no access to the document API.

    Workers and the thread that spawns them send messages to each other using the postMessage() method. Similarly, they respond to messages using the onmessage event handler. It’s important to get this difference. Sending messages is achieved using a method; receiving a message back requires an event handler. The message being received is contained in the data attribute of the event. We will see an example of this in the next section. But let me quickly mention that the sort of worker we’ve been discussing is called a “dedicated worker”. This means that the worker is only accessible to the script that called it. It is also possible to have a worker that is accessible from multiple scripts. These are called shared workers and are created using the SharedWorker constructor, as shown below.

    const sWorker = new SharedWorker('shared-worker-file.js')

    To learn more about Workers, please see this MDN article. The purpose of this article is to get you started with using Web workers. Let’s get to it by computing the nth Fibonacci number.

    Computing The Nth Fibonacci Number

    Note: For this and the next two sections, I’m using Live Server on VSCode to run the app. You can certainly use something else.

    This is the section you’ve been waiting for. We’ll finally write some code to see Web Workers in action. Well, not so fast. We wouldn’t appreciate the job a Web Worker does unless we run into the sort of problems it solves. In this section, we’re going to see an example problem, and in the following section, we’ll see how a web worker helps us do better.

    Imagine you were building a web app that allowed users to calculate the nth Fibonacci number. In case you’re new to the term ‘Fibonacci number’, you can read more about it here, but in summary, Fibonacci numbers are a sequence of numbers such that each number is the sum of the two preceding numbers.

    Mathematically, it is expressed as:

    Thus the first few numbers of the sequence are:

    1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 ...

    In some sources, the sequence starts at F0 = 0, in which case the formula below holds for n > 1:

    In this article we’ll start at F1 = 1. One thing we can see right away from the formula is that the numbers follow a recursive pattern. The task at hand now is to write a recursive function to compute the nth Fibonacci number (FN).

    After a few tries, I believe you can easily come up with the function below.

    const fib = n => {
      if (n < 2) {
        return n // or 1
      } else {
        return fib(n - 1) + fib(n - 2)
      }
    }

    The function is simple. If n is less than 2, return n (or 1), otherwise, return the sum of the n-1 and n-2 FNs. With arrow functions and ternary operator, we can come up with a one-liner.

    const fib = n => (n < 2 ? n : fib(n-1) + fib(n-2))

    This function has a time complexity of 0(2n). This simply means that as the value of n increases, the time required to compute the sum increases exponentially. This makes for a really long-running task that could potentially interfere with our UI, for large values of n. Let’s see this in action.

    Note: This is by no means the best way to solve this particular problem. My choice of using this method is for the purpose of this article.

    To start, create a new folder and name it whatever you like. Now inside that folder create a src/ folder. Also, create an index.html file in the root folder. Inside the src/ folder, create a file named index.js.

    Open up index.html and add the following HTML code.

    <!DOCTYPE html>
    <html>
    <head>
      <link rel="stylesheet" href="styles.css">
    </head>
    <body>
      <div class="heading-container">
        <h1>Computing the nth Fibonnaci number</h1>
      </div>
      <div class="body-container">
        <p id='error' class="error"></p>
        <div class="input-div">
          <input id='number-input' class="number-input" type='number' placeholder="Enter a number" />
          <button id='submit-btn' class="btn-submit">Calculate</button>
        </div>
        <div id='results-container' class="results"></div>
      </div>
      <script src="http://www.smashingmagazine.com/src/index.js"></script>
    </body>
    </html>

    This part is very simple. First, we have a heading. Then we have a container with an input and a button. A user would enter a number then click on “Calculate”. We also have a container to hold the result of the calculation. Lastly, we include the src/index.js file in a script tag.

    You may delete the stylesheet link. But if you’re short on time, I have defined some CSS which you can use. Just create the styles.css file at the root folder and add the styles below:

    
    body {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
      }
      
      .body-container,
      .heading-container {
        padding: 0 20px;
      }
      
      .heading-container {
        padding: 20px;
        color: white;
        background: #7a84dd;
      }
      
      .heading-container > h1 {
        margin: 0;
      }
      
      .body-container {
        width: 50%
      }
      
      .input-div {
        margin-top: 15px;
        margin-bottom: 15px;
        display: flex;
        align-items: center;
      }
      
      .results {
        width: 50vw;
      }
      
      .results>p {
        font-size: 24px;
      }
      
      .result-div {
        padding: 5px 10px;
        border-radius: 5px;
        margin: 10px 0;
        background-color: #e09bb7;
      }
      
      .result-div p {
        margin: 5px;
      }
      
      span.bold {
        font-weight: bold;
      }
      
      input {
        font-size: 25px;
      }
      
      p.error {
        color: red;
      }
      
      .number-input {
        padding: 7.5px 10px;
      }
      
      .btn-submit {
        padding: 10px;
        border-radius: 5px;
        border: none;
        background: #07f;
        font-size: 24px;
        color: white;
        cursor: pointer;
        margin: 0 10px;
      }

    Now open up src/index.js let’s slowly develop it. Add the code below.

    const fib = (n) => (n < 2 ? n : fib(n - 1) + fib(n - 2));
    
    const ordinal_suffix = (num) => {
      // 1st, 2nd, 3rd, 4th, etc.
      const j = num % 10;
      const k = num % 100;
      switch (true) {
        case j === 1 && k !== 11:
          return num + "st";
        case j === 2 && k !== 12:
          return num + "nd";
        case j === 3 && k !== 13:
          return num + "rd";
        default:
          return num + "th";
      }
    };
    const textCont = (n, fibNum, time) => {
      const nth = ordinal_suffix(n);
      return `
      <p id='timer'>Time: <span class='bold'>${time} ms</span></p>
      <p><span class="bold" id='nth'>${nth}</span> fibonnaci number: <span class="bold" id='sum'>${fibNum}</span></p>
      `;
    };

    Here we have three functions. The first one is the function we saw earlier for calculating the nth FN. The second function is just a utility function to attach an appropriate suffix to an integer number. The third function takes some arguments and outputs a markup which we will later insert in the DOM. The first argument is the number whose FN is being computed. The second argument is the computed FN. The last argument is the time it takes to perform the computation.

    Still in src/index.js, add the below code just under the previous one.

    const errPar = document.getElementById("error");
    const btn = document.getElementById("submit-btn");
    const input = document.getElementById("number-input");
    const resultsContainer = document.getElementById("results-container");
    
    btn.addEventListener("click", (e) => {
      errPar.textContent = '';
      const num = window.Number(input.value);
    
      if (num < 2) {
        errPar.textContent = "Please enter a number greater than 2";
        return;
      }
    
      const startTime = new Date().getTime();
      const sum = fib(num);
      const time = new Date().getTime() - startTime;
    
      const resultDiv = document.createElement("div");
      resultDiv.innerHTML = textCont(num, sum, time);
      resultDiv.className = "result-div";
      resultsContainer.appendChild(resultDiv);
    });

    First, we use the document API to get hold of DOM nodes in our HTML file. We get a reference to the paragraph where we’ll display error messages; the input; the calculate button and the container where we’ll show our results.

    Next, we attach a “click” event handler to the button. When the button gets clicked, we take whatever is inside the input element and convert it to a number, if we get anything less than 2, we display an error message and return. If we get a number greater than 2, we continue. First, we record the current time. After that, we calculate the FN. When that finishes, we get a time difference that represents how long the computation took. In the remaining part of the code, we create a new div. We then set its inner HTML to be the output of the textCont() function we defined earlier. Finally, we add a class to it (for styling) and append it to the results container. The effect of this is that each computation will appear in a separate div below the previous one.

    Showing computed Fibonacci numbers up to 43
    Some Fibonacci numbers. (Large preview)

    We can see that as the number increases, the computation time also increases (exponentially). For instance, from 30 to 35, we had the computation time jump from 13ms to 130ms. We can still consider those operations to be “fast”. At 40 we see a computation time of over 1 second. On my machine, this is where I start noticing the page become unresponsive. At this point, I can no longer interact with the page while the computation is on-going. I can’t focus on the input or do anything else.

    Recall when we talked about JavaScript being single-threaded? Well, that thread has been “blocked” by this long-running computation, so everything else must “wait” for it to finish. It may start at a lower or higher value on your machine, but you’re bound to reach that point. Notice that it took almost 10s to compute that of 44. If there were other things to do on your web app, well, the user has to wait for Fib(44) to finish before they can continue. But if you deployed a web worker to handle that calculation, your users could carry on with something else while that runs.

    Let’s now see how web workers help us overcome this problem.

    An Example Web Worker In Action

    In this section, we’ll delegate the job of computing the nth FN to a web worker. This will help free up the main thread and keep our UI responsive while the computation is on-going.

    Getting started with web workers is surprisingly simple. Let’s see how. Create a new file src/fib-worker.js. and enter the following code.

    const fib = (n) => (n < 2 ? n : fib(n - 1) + fib(n - 2));
    
    onmessage = (e) => {
      const { num } = e.data;
      const startTime = new Date().getTime();
      const fibNum = fib(num);
      postMessage({
        fibNum,
        time: new Date().getTime() - startTime,
      });
    };

    Notice that we have moved the function that calculates the nth Fibonacci number, fib inside this file. This file will be run by our web worker.

    Recall in the section What is a web worker, we mentioned that web workers and their parent communicate using the onmessage event handler and postMessage() method. Here we’re using the onmessage event handler to listen to messages from the parent script. Once we get a message, we destructure the number from the data attribute of the event. Next, we get the current time and start the computation. Once the result is ready, we use the postMessage() method to post the results back to the parent script.

    Open up src/index.js let’s make some changes.

    ...
    
    const worker = new window.Worker("src/fib-worker.js");
    
    btn.addEventListener("click", (e) => {
      errPar.textContent = "";
      const num = window.Number(input.value);
      if (num < 2) {
        errPar.textContent = "Please enter a number greater than 2";
        return;
      }
    
      worker.postMessage({ num });
      worker.onerror = (err) => err;
      worker.onmessage = (e) => {
        const { time, fibNum } = e.data;
        const resultDiv = document.createElement("div");
        resultDiv.innerHTML = textCont(num, fibNum, time);
        resultDiv.className = "result-div";
        resultsContainer.appendChild(resultDiv);
      };
    });

    The first thing to do is to create the web worker using the Worker constructor. Then inside our button’s event listener, we send a number to the worker using worker.postMessage({ num }). After that, we set a function to listen for errors in the worker. Here we simply return the error. You can certainly do more if you want, like showing it in DOM. Next, we listen for messages from the worker. Once we get a message, we destructure time and fibNum, and continue the process of showing them in the DOM.

    Note that inside the web worker, the onmessage event is available in the worker’s scope, so we could have written it as self.onmessage and self.postMessage(). But in the parent script, we have to attach these to the worker itself.

    In the screenshot below you would see the web worker file in the sources tab of Chrome Dev Tools. What you should notice is that the UI stays responsive no matter what number you enter. This behavior is the magic of web workers.

    View of an active web worker file
    A running web worker file. (Large preview)

    We’ve made a lot of progress with our web app. But there’s something else we can do to make it better. Our current implementation uses a single worker to handle every computation. If a new message comes while one is running, the old one gets replaced. To get around this, we can create a new worker for each call to calculate the FN. Let’s see how to do that in the next section.

    Working With Multiple Web Workers

    Currently, we’re handling every request with a single worker. Thus an incoming request will replace a previous one that is yet to finish. What we want now is to make a small change to spawn a new web worker for every request. We will kill this worker once it’s done.

    Open up src/index.js and move the line that creates the web worker inside the button’s click event handler. Now the event handler should look like below.

    btn.addEventListener("click", (e) => {
      errPar.textContent = "";
      const num = window.Number(input.value);
      
      if (num < 2) {
        errPar.textContent = "Please enter a number greater than 2";
        return;
      }
      
      const worker = new window.Worker("src/fib-worker.js"); // this line has moved inside the event handler
      worker.postMessage({ num });
      worker.onerror = (err) => err;
      worker.onmessage = (e) => {
        const { time, fibNum } = e.data;
        const resultDiv = document.createElement("div");
        resultDiv.innerHTML = textCont(num, fibNum, time);
        resultDiv.className = "result-div";
        resultsContainer.appendChild(resultDiv);
        worker.terminate() // this line terminates the worker
      };
    });

    We made two changes.

    1. We moved this line const worker = new window.Worker("src/fib-worker.js") inside the button’s click event handler.
    2. We added this line worker.terminate() to discard the worker once we’re done with it.

    So for every click of the button, we create a new worker to handle the calculation. Thus we can keep changing the input, and each result will hit the screen once the computation finishes. In the screenshot below you can see that the values for 20 and 30 appear before that of 45. But I started 45 first. Once the function returns for 20 and 30, their results were posted, and the worker terminated. When everything finishes, we shouldn’t have any workers on the sources tab.

    showing Fibonacci numbers with terminated workers
    Illustration of Multiple independent workers. (Large preview)

    We could end this article right here, but if this were a react app, how would we bring web workers into it. That is the focus of the next section.

    Web Workers In React

    To get started, create a new react app using CRA. Copy the fib-worker.js file into the public/ folder of your react app. Putting the file here stems from the fact that React apps are single-page apps. That’s about the only thing that is specific to using the worker in a react application. Everything that follows from here is pure React.

    In src/ folder create a file helpers.js and export the ordinal_suffix() function from it.

    // src/helpers.js
    
    export const ordinal_suffix = (num) => {
      // 1st, 2nd, 3rd, 4th, etc.
      const j = num % 10;
      const k = num % 100;
      switch (true) {
        case j === 1 && k !== 11:
          return num + "st";
        case j === 2 && k !== 12:
          return num + "nd";
        case j === 3 && k !== 13:
          return num + "rd";
        default:
          return num + "th";
      }
    };

    Our app will require us to maintain some state, so create another file, src/reducer.js and paste in the state reducer.

    // src/reducers.js
    
    export const reducer = (state = {}, action) => {
      switch (action.type) {
        case "SET_ERROR":
          return { ...state, err: action.err };
        case "SET_NUMBER":
          return { ...state, num: action.num };
        case "SET_FIBO":
          return {
            ...state,
            computedFibs: [
              ...state.computedFibs,
              { id: action.id, nth: action.nth, loading: action.loading },
            ],
          };
        case "UPDATE_FIBO": {
          const curr = state.computedFibs.filter((c) => c.id === action.id)[0];
          const idx = state.computedFibs.indexOf(curr);
          curr.loading = false;
          curr.time = action.time;
          curr.fibNum = action.fibNum;
          state.computedFibs[idx] = curr;
          return { ...state };
        }
        default:
          return state;
      }
    };

    Let’s go over each action type one after the other.

    1. SET_ERROR: sets an error state when triggered.
    2. SET_NUMBER: sets the value in our input box to state.
    3. SET_FIBO: adds a new entry to the array of computed FNs.
    4. UPDATE_FIBO: here we look for a particular entry and replaces it with a new object which has the computed FN and the time taken to compute it.

    We shall use this reducer shortly. Before that, let’s create the component that will display the computed FNs. Create a new file src/Results.js and paste in the below code.

    // src/Results.js
    
    import React from "react";
    
    export const Results = (props) => {
      const { results } = props;
      return (
        <div id="results-container" className="results-container">
          {results.map((fb) => {
            const { id, nth, time, fibNum, loading } = fb;
            return (
              <div key={id} className="result-div">
                {loading ? (
                  <p>
                    Calculating the{" "}
                    <span className="bold" id="nth">
                      {nth}
                    </span>{" "}
                    Fibonacci number...
                  </p>
                ) : (
                  <>
                    <p id="timer">
                      Time: <span className="bold">{time} ms</span>
                    </p>
                    <p>
                      <span className="bold" id="nth">
                        {nth}
                      </span>{" "}
                      fibonnaci number:{" "}
                      <span className="bold" id="sum">
                        {fibNum}
                      </span>
                    </p>
                  </>
                )}
              </div>
            );
          })}
        </div>
      );
    };

    With this change, we start the process of converting our previous index.html file to jsx. This file has one responsibility: take an array of objects representing computed FNs and display them. The only difference from what we had before is the introduction of a loading state. So now when the computation is running, we show the loading state to let the user know that something is happening.

    Let’s put in the final pieces by updating the code inside src/App.js. The code is rather long, so we’ll do it in two steps. Let’s add the first block of code.

    import React from "react";
    import "./App.css";
    import { ordinal_suffix } from "./helpers";
    import { reducer } from './reducer'
    import { Results } from "./Results";
    function App() {
      const [info, dispatch] = React.useReducer(reducer, {
        err: "",
        num: "",
        computedFibs: [],
      });
      const runWorker = (num, id) => {
        dispatch({ type: "SET_ERROR", err: "" });
        const worker = new window.Worker('./fib-worker.js')
        worker.postMessage({ num });
        worker.onerror = (err) => err;
        worker.onmessage = (e) => {
          const { time, fibNum } = e.data;
          dispatch({
            type: "UPDATE_FIBO",
            id,
            time,
            fibNum,
          });
          worker.terminate();
        };
      };
      return (
        <div>
          <div className="heading-container">
            <h1>Computing the nth Fibonnaci number</h1>
          </div>
          <div className="body-container">
            <p id="error" className="error">
              {info.err}
            </p>
    
            // ... next block of code goes here ... //
    
            <Results results={info.computedFibs} />
          </div>
        </div>
      );
    }
    export default App;

    As usual, we bring in our imports. Then we instantiate a state and updater function with the useReducer hook. We then define a function, runWorker(), that takes a number and an ID and sets about calling a web worker to compute the FN for that number.

    Note that to create the worker, we pass a relative path to the worker constructor. At runtime, our React code gets attached to the public/index.html file, thus it can find the fib-worker.js file in the same directory. When the computation completes (triggered by worker.onmessage), the UPDATE_FIBO action gets dispatched, and the worker terminated afterward. What we have now is not much different from what we had previously.

    In the return block of this component, we render the same HTML we had before. We also pass the computed numbers array to the <Results /> component for rendering.

    Let’s add the final block of code inside the return statement.

            <div className="input-div">
              <input
                type="number"
                value={info.num}
                className="number-input"
                placeholder="Enter a number"
                onChange={(e) =>
                  dispatch({
                    type: "SET_NUMBER",
                    num: window.Number(e.target.value),
                  })
                }
              />
              <button
                id="submit-btn"
                className="btn-submit"
                onClick={() => {
                  if (info.num < 2) {
                    dispatch({
                      type: "SET_ERROR",
                      err: "Please enter a number greater than 2",
                    });
                    return;
                  }
                  const id = info.computedFibs.length;
                  dispatch({
                    type: "SET_FIBO",
                    id,
                    loading: true,
                    nth: ordinal_suffix(info.num),
                  });
                  runWorker(info.num, id);
                }}
              >
                Calculate
              </button>
            </div>

    We set an onChange handler on the input to update the info.num state variable. On the button, we define an onClick event handler. When the button gets clicked, we check if the number is greater than 2. Notice that before calling runWorker(), we first dispatch an action to add an entry to the array of computed FNs. It is this entry that will be updated once the worker finishes its job. In this way, every entry maintains its position in the list, unlike what we had before.

    Finally, copy the content of styles.css from before and replace the content of App.css.

    We now have everything in place. Now start up your react server and play around with some numbers. Take note of the loading state, which is a UX improvement. Also, note that the UI stays responsive even when you enter a number as high as 1000 and click “Calculate”.

    showing loading state while worker is active.
    Showing loading state and active web worker. (Large preview)

    Note the loading state and the active worker. Once the 46th value is computed the worker is killed and the loading state is replaced by the final result.

    Conclusion

    Phew! It has been a long ride, so let’s wrap it up. I encourage you to take a look at the MDN entry for web workers (see resources list below) to learn other ways of using web workers.

    In this article, we learned about what web workers are and the sort of problems they’re meant to solve. We also saw how to implement them using plain JavaScript. Finally, we saw how to implement web workers in a React application.

    I encourage you to take advantage of this great API to deliver a better experience for your users.

    Further Resources

    Smashing Editorial
    (ks, ra, yk, il)

    Source link

    web design

    Developing For The Semantic Web — Smashing Magazine

    10/07/2020

    About The Author

    Frederick O’Brien is a freelance journalist who conforms to most British stereotypes. His interests include American literature, graphic design, sustainable …
    More about
    Frederick

    The dream of a machine-readable Internet is as old as the Internet itself, but only in recent years has it really seemed possible. As major websites take strides towards data-fying their content, now’s the perfect time to jump on the bandwagon.

    In July the Wikimedia Foundation announced Abstract Wikipedia, an attempt to markup knowledge that is language-independent. In many respects, this is the culmination of decades of buildup, during which the dream of a Semantic Web has never quite taken off, but never quite disappeared either.

    As a matter of fact the Semantic Web is growing, and as it renews its mission we all stand to gain from incorporating semantic markup into our websites, be they personal blogs or social media giants. Whether you care about sophisticated web experiences, SEO, or fending off the tyranny of web monopolies, the Semantic Web deserves our attention.

    The benefits of developing for the Semantic Web are not always immediate, or visible, but every site that does strengthens the foundations of an open, transparent, decentralized internet.

    The Semantic Web

    What exactly is the Semantic Web? It is a machine-readable web, providing through metadata “a common framework that allows data to be shared and reused across application, enterprise, and community boundaries.”

    The idea is as old as the World Wide Web itself. Older, in fact. It was a focal point of Tim Berners-Lee’s 1989 proposal. As he outlined, not only should documents form webs, but the data inside them should too:

    Diagram from Tim Berners-Lee’s World Wide Web proposal to CERN
    A diagram from Sir Tim Berners-Lee’s original proposal for the World Wide Web. (Large preview)

    The Semantic Web’s tread a rocky road in the decades since. Since the turn of the millennium, it has morphed into multiple concepts — open data, knowledge graphs — all effectively meaning the same thing: webs of data.

    As the W3C summarises, it is “an extension of the current web in which information is given well-defined meaning, better-enabling computers and people to work in cooperation.”

    Aaron Swartz speaking in front of a crowd
    Aaron Swartz speaking in 2012. Photograph by Daniel J. Sieradski. (Large preview)

    The idea has had its fair share of advocates. Internet hacktivist Aaron Swartz wrote a book manuscript about the Semantic Web called A Programmable Web. In it he wrote:

    “Documents can’t really be merged and integrated and queried; they serve mostly as isolated instances to be viewed and reviewed. But data are protean, able to shift into whatever shape best suits your needs.”

    For a variety of reasons, the Semantic Web has not taken off in the same way the Web has, though it is catching up. Several markups have tried to seize the mantle over the years — RDFa, OWL, and Schema to name a few — though none have become standard in the way, say, HTML or CSS have. The barrier to entry was too high.

    However, the dream of the Semantic Web has endured, and as more and more sites incorporate it into their designs there’s all the more reason to join the party. The more sites that get on board, the stronger the Semantic Web becomes.

    Further Reading

    Knowledge Without Borders

    Before getting into the weeds of how to design for the Semantic Web, it’s worth digging a little deeper into the why. What does it matter whether data is connected? Aren’t connected documents enough?

    There are several reasons why the Semantic Web continues to be pushed by those who care about a free and open internet. Understanding those reasons is essential to the implementation process. It shouldn’t be a case of ‘eat your vegetables, use semantic markup.’ The Semantic Web is something to believe in and be a part of.

    Benefits of the Semantic Web include:

    • Richer, more sophisticated web experiences
    • Bypassing content silos and internet monopolies
    • Improved search engine readability and rankings
    • Democratisation of information

    Most of these can be traced back to a core tenet of the Semantic Web: a universal language for data. Although the internet has already done wonders for international communication, there’s no escaping the fact some countries have it much better than others. Take languages used on the web vs. languages used in the real world, for example. The eagle-eyed among you may be able to spot a slight imbalance in the data below…

    Bar chart comparing languages spoken online and in real life
    The proportion of languages used on the web do not match up with those used in the real world. (Large preview)

    The borderless utopia of the web is not as close as it might seem to those of us inside the English-speaking bubble. Is that something to chastise anyone for? Not necessarily, but it is something to face up to. Doing so highlights the importance of markup that bridges those gaps. By enriching the data of the web, we take the strain off of its languages.

    This is the crux of the recently announced Abstract Wikipedia, which will attempt to decouple articles from the language they happen to be written in. Wikimedia Executive Director Katherine Maher writes: “Using code, volunteers will be able to translate these abstract ‘articles’ into their own languages. If successful, this could eventually allow everyone to read about any topic in Wikidata in their own language.”

    Abstract Wikipedia creator Denny Vrandečić has been a Semantic Web advocate for years, recognizing its potential to unlock untapped potential online. Breaking down national barriers is essential to that process.

    “No matter what language you publish your content in, you are going to miss out on including the vast majority of people in the world. The Web gave us this wonderful opportunity to have global reach — but by relying on a single language, or a small set of languages, we are squandering this opportunity. While the most important objective is to create good content in the first place, you invite more people to participate in the development of better content by being language-independent. It helps you lower the barriers to contribution and consumption, and it allows for many more people to benefit from that effort.”

    — Denny Vrandečić, Abstract Wikipedia creator

    A timely example of this has been data visualization during the COVID-19 pandemic. The virus has wreaked unspeakable havoc worldwide, but it has also been a shining moment for open data networks, allowing superb web apps, reporting, and more to be common across the web.

    Homepage of ncovid2019.live
    The ncovid2019.live dashboard was made by American high schooler Avi Schiffman and pulls data from WHO, the CDC, and COV19. (Large preview)

    And of course, when data is transparent and easily accessible, it makes it easier to identify anomalies… or straight up deceit. Widespread public access to the kind of information above would be unthinkable even 20 years ago. Now we expect it, and smell a rat when it’s denied us. Data is powerful, and if we want to, can be wielded for good.

    Similarly, checking ourselves out of content silos — a hallmark of the modern web experience — takes power away from web monopolies like Google, Facebook, and Twitter. We’re so used to third party platforms deciphering and presenting information that we forget they’re not strictly necessary.

    “If we had shared formats, shared protocols, we might still end up with certain providers playing a large role in certain markets — think of Gmail for email — but everyone is free to move to another provider, and the market remains competitive.”

    — Denny Vrandečić, Abstract Wikipedia creator

    The Semantic Web is silo-less; it is free, open, and abstract, enabling communication between different languages and platforms that would be far more difficult otherwise.

    Data-fying Online Content

    Designing for the Semantic Web boils down to data-fying online content — looking at your content and seeing what can (and should) be abstracted. What does this mean in practical terms, beyond vaguely agreeing it’s a worthwhile thing to do? It depends:

    1. If starting a project from scratch, incorporate Semantic Web considerations into what you do. As a website takes shape, weave semantic markup into its DNA.
    2. If updating or rebuilding a project, assess what could be woven into the Semantic Web that currently isn’t, then implement.

    Both cases basically amount to data-fying content. In this section, we will go through some examples of data abstraction and how it can make content better, smarter, and more widely available.

    Abstracting Information

    Designing and developing for the Semantic Web means looking at online content with your data hat on. Most of us experience the web as a series of connecting documents or pages; what you want to do with the Semantic Web is connect information. This means assessing your content for data points then adjusting the design based on what you find.

    Semantic Web advocate James Hendler outlines this process particularly well with his DIVE ethos. (DIVE into the data, eh? Eh?). It breaks down as follows:

    • Discover
      Find datasets and/or content (including outside your own organization).
    • Integrate
      Link the relations using meaningful labels.
    • Validate
      Provide inputs to modeling and simulation systems.
    • Explore
      Develop approaches to turn data into actionable knowledge.

    Developing for the Semantic Web is largely about having that birds-eye view of the things you make, and how it potentially feeds into infinitely richer web experiences. As Hendler says, actionable knowledge is the goal.

    This really can be applied to almost any type of web content, but let’s start with a common example: recipes. Let’s say you run a cooking blog, with new recipes every Thursday. If you’re French and post a smashing soufflé recipe on your personal blog in plain text, it’s only useful to those who can read French.

    However, by implementing semantic markup the blog can be transformed into a machine-readable recipe data set. Syntax exists for cooking terms to be abstracted. Schema, for example, which can work alongside Microdata, RDFa, or JSON-LD, has markup including:

    • prepTime
    • cookTime
    • recipeYield
    • recipeIngredient
    • estimatedCost
    • nutrition, breaking down into calories and fatContent
    • suitableForDiet.

    I could go on. The full range of options, with examples, can be read at Schema.org. In adding them to the post format the format of the recipe needn’t change at all — you’re simply putting the information in terms computers can understand.

    Screenshot of a BBC cottage pie recipe
    By converting editorial content into data, BBC recipes massively increase their potential usefulness. (Click for large preview)

    For example, everything highlighted blue in the BBC recipe above has also been given semantic markup — from cooking time to nutritional content. You can see what’s going on under the hood by entering the recipe URL into Google’s Rich Results Test. Note the ‘Add to shopping list’ functionality, an example of connection made possible by Semantic Web implementation. Good content becomes usable data.

    Most of us have crossed paths with this kind of sophistication via search results, but the applications are much wider than that. Semantic markup of recipes makes it easier for websites to be found and used by home assistants. Listed ingredients can be ordered from the local supermarket. Recipes could be filtered in all sorts of ways — for diets, allergies, religion, cost, you name it. Or let’s say you had a limited number of ingredients in the house. With a database you could input those ingredients and see what recipes fit the bill.

    The range of possibilities really do border on limitless. As Swartz said, data is protean. Once you have it you can use it in all sorts of weird and wonderful ways. This piece is not about those weird and wonderful ways so much as it is about making them possible. Designing for the Semantic Web makes subsequent design infinitely richer.

    Here’s a more personal example to show what I mean. A couple of friends and I run a little music webzine as a hobby. Though we publish the odd article or interview, the ‘main event’ is our weekly album reviews, in which the three of us each assign a score, choose favorite tracks, and write summaries. We’ve been going for more than five years, which means we have close to 250 reviews, which means an awful lot of potential data. We didn’t realize how much until we started redesigning the site.

    I touched upon this in a piece about baking structured data into the design process. In dissecting our reviews we realized they were chock full of information that could be given semantic markup. Artists, album names, artwork, release date, individual scores, overall scores, release type, and more. What’s more — and this is where it gets really exciting — we realized we could connect to an existing database: MusicBrainz.

    This two-way approach is the crux of the Semantic Web. When our music website relaunches it will be its own open data source with thousands of unique data points. Connecting to an existing music database will give our own data more context — and potential. Thousands of data points becomes tens of thousands of data points, maybe more.

    Chart showing how semantic markup connects on an album review
    With some simple semantic markup, seemingly innocuous web pages can become the centre of an huge information network. (Large preview)

    The graphic above only scratches the surface of how much information will be connected to reviews pages. The content is the same as it was before, only now it is plugged into a metadata ecosystem — the Giant Global Graph, as Berners-Lee once called it.

    Developing for the Semantic Web means identifying your own data, markup it up, then sussing out how it connects to other data. Because it does. It always does. And that process is how this…

    Illustration showing how semantic data connects across web pages
    (Large preview)

    … in time becomes this…

    The Linked Open Data Cloud
    The Linked Open Data Cloud, a constantly updating visualisation of the state of linked data online. (Large preview)

    The second image is The Linked Open Data Cloud, a constantly updating visualization of the web’s connected data. That red hive of connections is the sciences; the rest has some way to go. That’s where we come in.

    Useful Semantic Web Resources

    Plugging In

    The ideal of the Semantic Web is connection. Make data, share data, demand data. Be part of an information ecosystem. When you’re creating original data, great. Share it. When data already exists and you’d like to use it, pull it in.

    Here are just a handful of the data resources out there:

    Indeed, where databases like these exist, I’d go so far as to say the right thing to do would be update them where they’re lacking information. Why keep it to yourself? Become a contributor, a Semantic Web advocate.

    Implementation

    As far as building Semantic Webness into your sites goes, I’m certainly not advocating manual, doc-by-doc markup. Who’s got time for that? More often than not the solution is a case of standardizing a format and templating for it.

    Templating is the big opportunity here. How many people really have time to markup all that information manually? However, if you have custom inputs, you get the best of both worlds. Content can be filled with people-friendly information and the information exists as data ready to serve whatever purpose comes to mind.

    Take, for example, a static site generator like Eleventy, which has been enjoying a bit of a love-in from the dev community lately. You write a post, run it through a template, and you’re golden. So why not incorporate semantic markup into the template itself?

    Like Eleventy, the new version of our music webzine site uses Markdown for its posts. While we have the same old text posts we always did, every review now also includes the following metadata inputs, which are then pulled into the template:

    Metadata inputs in a Markdown document
    Incorporating metadata inputs into templates allows content to be converted into data, and at most adds a couple of minutes to any given post upload. (Large preview)

    Together with author details in the body of the post and some generic website info, this then translates to the following semantic markup:

    <script type="application/ld+json">
        {
      "@context": "http://schema.org/",
      "@type": "Review",
      "reviewBody": "One of the definitive albums released by, quite possibly, the greatest singer-songwriter we've ever seen. To those looking to probe Young's daunting discography: start here.",
      "datePublished": "2020-08-14",
      "author": [{
        "@type": "Person",
        "name": "André Dack"
      },
                {
        "@type": "Person",
        "name": "Frederick O'Brien"
      },
                {
        "@type": "Person",
        "name": "Marcus Lawrence"
      }],
      "itemReviewed": {
        "@type": "MusicAlbum",
        "name": "After the Gold Rush",
        "@id": "https://musicbrainz.org/release-group/b6a3952b-9977-351c-a80a-73e023143858",
        "image": "https://audioxide.com/images/album-artwork/after-the-gold-rush-neil-young.jpg",
        "albumProductionType": "http://schema.org/StudioAlbum",
        "albumReleaseType": "http://schema.org/AlbumRelease",
        "byArtist": {
            "@type": "MusicGroup",
            "name": "Neil Young",
            "@id": "https://musicbrainz.org/artist/75167b8b-44e4-407b-9d35-effe87b223cf"
        }
      },
      "reviewRating": {
        "@type": "Rating",
        "ratingValue": 27,
        "worstRating": 0,
        "bestRating": 30
      },
      "publisher": {
        "@type": "Organization",
        "name": "Audioxide",
        "description": "Independent music webzine founded in 2015. Publishes reviews, articles, interviews, and other oddities.",
        "url": "https://audioxide.com",
        "logo": "https://audioxide.com/logo-location.jpg",
        "sameAs" : [
        "https://facebook.com/audioxide",
        "https://twitter.com/audioxide",
        "https://instagram.com/audioxidecom"
      ]
        }
    }
        
        </script>

    Where before there was just text, on every single review page there will now also be machine-readable versions of what readers see when they visit the site. The words are all still there, the content has barely changed at all — it’s just been data-fyed. From rich search results to interactive review statistics pages, this massively increases what’s possible. The road ahead is wide and open. It also gives us a stake in MusicBrainz’s future. By connecting their data to our own data, we in turn want to see it do well, and will do our part to ensure it does.

    The appropriate semantic markup depends on the nature of a website, but odds are it exists. Start with the obvious inputs (date, author, content type, etc.) and work your way into the weeds of the content. The first step could be as simple as a hCard (a kind of digital ID card) for your personal website. Print out screenshots of pages and start annotating. You’ll be amazed by how much content can be data-fyed.

    Beyond Imagination

    Designing and developing for the Semantic Web is a practice that dates back to the Internet’s founding ideals. Whether you value beautiful, informative data visualization, want more sophisticated search results, wish to remove power from web monopolies, or simply believe in free and open information, the Semantic Web is your ally.

    Aaron Swartz closed his manuscript with a call to hope:

    “The Semantic Web is based on bet, a bet that giving the world tools to easily collaborate and communicate will lead to possibilities so wonderful we can scarcely even imagine them right now.”

    Abstract Wikipedia Denny Vrandečić echoes those sentiments today, saying:

    “There’s a need for a web infrastructure that will facilitate interoperability between services, which requires a common set of standards for representing data, and common protocols across providers.”

    The Semantic Web has limped along long enough for it to be clear that a silver bullet language is unlikely to appear, but there are enough now peacefully coexisting for Berners-Lee’s founding dream to be a reality for most of the web. Each of us can be advocates in our own neighborhoods.

    Be Better, Demand Better

    As Tim Berners-Lee has said, the Semantic Web is a culture as much as it is a technical hurdle. In a 2009 TED Talk he summed it up nicely: make linked data, demand linked data. That’s truer now than ever. The World Wide Web is only as open and connected and good as we force it to be. Whenever you make something online ask yourself, “How can this plug into the Semantic Web?” The answers will add new dimensions to the things we create, and create unimaginably wonderful new possibilities for years to come.

    Smashing Editorial
    (ra, yk, il)

    Source link

    web design

    Useful Tools In Vue.js Web Development — Smashing Magazine

    10/05/2020

    About The Author

    Front-end developer based in Lagos, Nigeria. He enjoys converting designs into code and building things for the web.
    More about
    Timi

    There are some tools that developers that are just getting started with Vue or sometimes, have experience building with Vue sometimes do not know exist to make development in Vue a lot easier. In this article, we’re going to look at a few of these libraries, what they do, and how to use them during development.

    When working on a new project, there are certain features that are necessary depending on how the application is supposed to be used. For example, if you’ll be storing user-specific data, you’ll need to handle authentications, this will require the setting up of a form that needs to be validated. Things such as authentication and form validations are common; there are solutions that possibly fit your use case.

    To properly utilize your development time, it is better you use what is available, instead of inventing yours.

    As a new developer, there’s the possibility that you won’t be aware of all that the Vue ecosystem provides you. This article will help with that; it will cover certain useful tools that will aid you in building better Vue applications.

    Note: There are alternatives to these libraries and this article is in no way placing these few over the others. They are just the ones I’ve worked with.

    This tutorial is aimed at beginners that either just started learning about Vue or already have basic knowledge of Vue. All code snippets used in this tutorial can be found on my GitHub.

    Vue-notification

    During user interaction, there is often a need to display a success message, error message, or random info to the user. In this section, we’re going to look at how to display messages and warnings to your user using vue-notification. This package provides an interface with a nice animation/transition for displaying errors, general information, and success messages to your user across your application and it does not require a lot of configuration to get up and running.

    Installation

    You can install vue-notification in your project using either Yarn or NPM depending on the package manager for your project

    Yarn
    yarn add vue-notification
    
    npm
    npm install --save vue-notification
    

    After the installation is complete, the next thing would be to add it to the entry point in your app, the main.js file.

    main.js
    //several lines of existing code in the file
        import Notifications from 'vue-notification'
        Vue.use(Notifications)
      

    At this point, we only need to add the notifications component in the App.vue file before we can display notifications in our app. The reason why we’re adding this component to the App.vue file is to avoid repetition in our application because no matter the page the user is on in our app, components in App.vue (e.g the header & footer components) would always be available. This takes the pain of having to register the notification component in every file that we need to display a notification to the user.

    App.vue
    <template>
      <div id="app">
        <div id="nav">
          <router-link to="/">Home</router-link> |
          <router-link to="/about">Notifications</router-link>
        </div>
        <notifications group="demo"/>
        <router-view />
      </div>
    </template>
    

    Here, we add one instance of this component which accepts a group prop which would be used in grouping the different types of notifications we have. This is because the notifications component accepts a number of props that dictate how the component behaves and we’re going to look at a few of these.

    1. group
      This prop is used to specify the different types of notifications you might have in your app. For instance, you might decide to use different styles and behavior depending on what purpose the notification is supposed to serve, form validation, API response, etc.
    2. type
      This prop accepts a value that serves as a ‘class name’ for each notification type we have in our application and examples can include success, error, and warn. If we use any one of these as a notification type, we can easily style the component by using this class format vue-notification + '.' + type, i.e .vue-notification.warn for warn, and so on.
    3. duration
      This prop specifies how long the notification component should appear before disappearing. It accepts a number as a value in ms and also accepts a negative number (-1) if you want it to remain on your user’s screen till they click on it.
    4. position
      This prop is used in setting the position you want notifications to appear from in your app. Some of the available options are top left, top right, top center, bottom right, bottom left, and bottom center.

    We can add these props to our component in App.vue so it now looks like this;

    <template>
      <div id="app">
        <div id="nav">
          <router-link to="/">Home</router-link> |
          <router-link to="/about">Notifications</router-link>
        </div>
        <notifications
          :group="group"
          :type="type"
          :duration="duration"
          :position="position"
        />
        <router-view />
      </div>
    </template>
    <script>
      export default {
        data() {
          return {
            duration: -1,
            group: "demo",
            position: "top center",
            type: "info",
          };
        },
      };
    </script>
    <style>
      .vue-notification.info {
        border-left: 0;
        background-color: orange;
      }
      .vue-notification.success {
        border-left: 0;
        background-color: limegreen;
      }
      .vue-notification.error {
        border-left: 0;
        background-color: red;
      }
    </style>
    

    We also add styling for the different notification types that we would be using in our application. Note that other than group, we can pass each of the remaining props on the fly whenever we want to display a notification and it would still work accordingly. To display a notification in any of your Vue files, you can do the following.

    vueFile.vue
    this.$notify({
      group: "demo",
      type: "error",
      text: "This is an error notification",
    });
    

    Here, we create a notification of type error under the group notification of demo. The property text accepts the message you want the notification to contain and in this case, the message is ‘This is an error notification’. This is what the notification would look like in your app.

    vue-notification with type ‘error’ in action
    vue-notification in action: error notification displaying in the browser. (Large preview)

    You can find out the other available props and other ways to configure the notification on the official docs page.

    Vuelidate

    One of the most common elements used on the web are form elements (input[type='text'], input[type='email'], input[type='password'], and so on) and there is always a need to validate user input to make sure they’re sending the right data and/or using the right format in the input field. With Vuelidate, you can add validation to the forms in your Vue.js application, saving time and benefitting from the time put into this package. I had been hearing about Vuelidate for a while but I was a little reluctant to take a look at it because I thought it would be too complex which meant I was writing validations from scratch for most of the form fields in the apps I worked on.

    When I eventually looked at the docs, I found out it was not difficult to get started with and I could validate my form fields in no time and move on to the next thing.

    Installation

    You can install Vuelidate using any of the following package managers.

    Yarn
    yarn add vuelidate
    
    npm
    npm install vuelidate --save
    

    After installation, the next thing would be to add it to your app’s config in the main.js file so you can use it in your vue files.

    import Vuelidate from 'vuelidate'
    Vue.use(Vuelidate)
    

    Assuming you have a form that looks like this in your app;

    vuelidate.vue
    <template>
      <form @submit.prevent="login" class="form">
        <div class="input__container">
          <label for="fullName" class="input__label">Full Name</label>
          <input
            type="text"
            name="fullName"
            id="fullName"
            v-model="form.fullName"
            class="input__field"
          />
        </div>
        <div class="input__container">
          <label for="email" class="input__label">Email</label>
          <input
            type="email"
            name="email"
            id="email"
            v-model="form.email"
            class="input__field"
          />
        </div>
        <div class="input__container">
          <label for="email" class="input__label">Age</label>
          <input
            type="number"
            name="age"
            id="age"
            v-model="form.age"
            class="input__field"
          />
        </div>
        <div class="input__container">
          <label for="password" class="input__label">Password</label>
          <input
            type="password"
            name="password"
            id="password"
            v-model="form.password"
            class="input__field"
          />
        </div>
        <input type="submit" value="LOGIN" class="input__button" />
        <p class="confirmation__text" v-if="submitted">Form clicked</p>
      </form>
    </template>
    <script>
      export default {
        data() {
          return {
            submitted: false,
            form: {
              email: null,
              fullName: null,
              age: null,
              password: null,
            },
          };
        },
        methods: {
          login() {
            this.submitted = true;
          },
        },
      };
    </script>
    

    Now to validate this type of form, you first need to decide on what type of validation you need for each form field. For instance, you can decide you need the minimum length of the fullName to be 10 and the minimum age to be 18.

    Vuelidate comes with built-in validators that we only need to import it to use. We can also choose to validate the password field based on a particular format, e.g Password should contain at least a lower case letter, an upper case letter, and a special character. We can write our own little validator that does this and plug it into the list of Vuelidate’s plugin.

    Let’s take it step by step.

    Using Built-In Validators
    <script>
      import {
        required,
        minLength,
        minValue,
        email,
      } from "vuelidate/lib/validators";
      export default {
        validations: {
          form: {
            email: {
              email,
              required,
            },
            fullName: {
              minLength: minLength(10),
              required,
            },
            age: {
              required,
              minValue: minValue(18),
            },
          },
        },
      };
    </script>
    

    Here, we import some validators that we need to properly validate our form. We also add a validations property where we define the validation rules for each form field that we want to validate.

    At this point, if you inspect the devTools for your app, you should see something that looks like this;

    vuelidate computed property
    vuelidate computed property (Large preview)

    The $v computed property contains a number of methods that are useful in confirming the validity of our form but we’re only going to focus on a few of them:

    1. $invalid
      To check if the form passes all validation.
    2. email
      To check that the value is a valid email address.
    3. minValue
      To check that the value of age passes the minValue check.
    4. minLength
      To verify the length of fullName.
    5. required
      To ensure all required fields are provided.

    If you enter a value for age less than the minimum age set in the validation and check $v.form.age.minValue, it would be set to false and this means the value in the input field doesn’t pass the minValue validation check.

    Using Custom Validators

    We also need to validate our password field and ensure it contains the required format but Vuelidate does not have a built-in validator that we can use to achieve this. We can write our own custom validator that does this using RegEx. This custom validator would look like this;

    <script>
      import {
        required,
        minLength,
        minValue,
        email,
      } from "vuelidate/lib/validators";
      export default {
        validations: {
          form: {
    //existing validator rules
            password: {
              required,
              validPassword(password) {
                let regExp = /^(?=.*[0-9])(?=.*[!@#$%^&*])(?=.*[A-Z]+)[a-zA-Z0-9!@#$%^&*]{6,}$/;
                return regExp.test(password);
              },
            },
          },
        },
      };
    </script>
    

    Here, we create a custom validator that uses a Regex to check that the password contains the following;

    1. At least one uppercase letter;
    2. At least one lowercase letter;
    3. At least one special character;
    4. At least one number;
    5. Must have a minimum length of 6.

    If you try to enter any password that doesn’t meet any of the requirements listed above, the validPassword would be set to false.

    Now that we’re sure our validations are working, we have to display the appropriate error messages so the user knows why they can’t proceed. This would look like this:

    <template>
      <form @submit.prevent="login" class="form">
        <div class="input__container">
          <label for="fullName" class="input__label">Full Name</label>
          <input
            type="text"
            name="fullName"
            id="fullName"
            v-model="form.fullName"
            class="input__field"
          />
          <p class="error__text" v-if="!$v.form.fullName.required">
            This field is required
          </p>
        </div>
        <div class="input__container">
          <label for="email" class="input__label">Email</label>
          <input
            type="email"
            name="email"
            id="email"
            v-model="form.email"
            class="input__field"
          />
          <p class="error__text" v-if="!$v.form.email.required">
            This field is required
          </p>
          <p class="error__text" v-if="!$v.form.email.email">
            This email is invalid
          </p>
        </div>
        <div class="input__container">
          <label for="email" class="input__label">Age</label>
          <input
            type="number"
            name="age"
            id="age"
            v-model="form.age"
            class="input__field"
          />
          <p class="error__text" v-if="!$v.form.age.required">
            This field is required
          </p>
        </div>
        <div class="input__container">
          <label for="password" class="input__label">Password</label>
          <input
            type="password"
            name="password"
            id="password"
            v-model="form.password"
            class="input__field"
          />
          <p class="error__text" v-if="!$v.form.password.required">
            This field is required
          </p>
          <p class="error__text" v-else-if="!$v.form.password.validPassword">
            Password should contain at least a lower case letter, an upper case
            letter, a number and a special character
          </p>
        </div>
        <input type="submit" value="LOGIN" class="input__button" />
      </form>
    </template>
    

    Here, we add a paragraph that displays either a text telling the user that a field is required, an inputted value for email is not valid or that the password doesn’t contain the required characters. If we look at this in your browser, you would see the errors already appearing under each input field.

    error texts in the form
    Error texts for each input field (Large preview)

    This is bad for user experience as the user is yet to interact with the form and as such the error texts should not be visible at least, till the user tries to submit the form. To fix this, we would add submitted to the condition required for the error texts to show and also switch the value of submitted to true when the user clicks on the submit button.

    <template>
      <form @submit.prevent="login" class="form">
        <div class="input__container">
          <label for="fullName" class="input__label">Full Name</label>
          <input
            type="text"
            name="fullName"
            id="fullName"
            v-model="form.fullName"
            class="input__field"
          />
          <p class="error__text" v-if="submitted && !$v.form.fullName.required">
            This field is required
          </p>
        </div>
        <div class="input__container">
          <label for="email" class="input__label">Email</label>
          <input
            type="email"
            name="email"
            id="email"
            v-model="form.email"
            class="input__field"
          />
          <p class="error__text" v-if="submitted && !$v.form.email.required">
            This field is required
          </p>
          <p class="error__text" v-if="submitted && !$v.form.email.email">
            This email is invalid
          </p>
        </div>
        <div class="input__container">
          <label for="email" class="input__label">Age</label>
          <input
            type="number"
            name="age"
            id="age"
            v-model="form.age"
            class="input__field"
          />
          <p class="error__text" v-if="submitted && !$v.form.age.required">
            This field is required
          </p>
        </div>
        <div class="input__container">
          <label for="password" class="input__label">Password</label>
          <input
            type="password"
            name="password"
            id="password"
            v-model="form.password"
            class="input__field"
          />
          <p class="error__text" v-if="submitted && !$v.form.password.required">
            This field is required
          </p>
          <p
            class="error__text"
            v-else-if="submitted && !$v.form.password.validPassword"
          >
            Password should contain at least a lower case letter, an upper case
            letter, a number and a special character
          </p>
        </div>
        <input type="submit" value="LOGIN" class="input__button" />
      </form>
    </template>
    

    Now the error texts do not appear until the user clicks on the submit button and this is much better for the user. Each validation error would appear if the value inputted in the form does not satisfy the validation.

    Finally, we would only want to process the user’s input when all validations on our form have passed and one way we can do this would be to use the $invalid property on the form which is present in the $v computed property. Let us take a look at how to do that:

    methods: {
          login() {
            this.submitted = true;
            let invalidForm = this.$v.form.$invalid;
            //check that every field in this form has been entered correctly.
            if (!invalidForm) {
              // process the form data
            }
          },
        },
    

    Here, we’re checking to ensure that the form has been completely filled and filled correctly. If it returns false, that means the form is valid and we can process the data from the form but if it is true , it means that the form is still invalid and the user still needs to tend to some errors in the form. We can also use this property to disable or style the submit button depending on your preference.

    Vuex-persistedstate

    During development, there are instances where you would store data like a user’s info and token in your Vuex store. But your Vuex store data would not persist if your users try to refresh your app from the browser or enter a new route from the URL tab of your browser and the current state of your application gets lost with it. This causes the user to be redirected to the login page if the route is being protected with navigation guard which is abnormal behavior for your app to have. This can be fixed with vuex-persistedstate, let look at how.

    Installation

    You can install this plugin using any one of the two methods:

    Yarn
    yarn add vuex-persistedstate
    
    npm
    npm install --save vuex-persistedstate
    

    After the installation process is complete, the next step would be to configure this plugin to be ready for use in your Vuex store.

    import Vue from 'vue'
    import Vuex from 'vuex'
    import createPersistedState from "vuex-persistedstate";
    Vue.use(Vuex)
    export default new Vuex.Store({
        state: {},
        mutations: {},
        actions: {},
        modules: {},
        plugins: [createPersistedState()]
    })
    

    At this point, all of our Vuex Store would be stored in localStorage (by default) but vuex-persistedstate comes with the option to use sessionStorage or cookies.

    import Vue from 'vue'
    import Vuex from 'vuex'
    import createPersistedState from "vuex-persistedstate";
    Vue.use(Vuex)
    export default new Vuex.Store({
        state: {},
        mutations: {},
        actions: {},
        modules: {},
      // changes storage to sessionStorage
        plugins: [createPersistedState({ storage: window.sessionStorage });
    ]
    })
    

    To confirm that our Store would persist after refreshing or closing the browser tab, let us update our store to look like this:

    import Vue from 'vue'
    import Vuex from 'vuex'
    import createPersistedState from "vuex-persistedstate";
    Vue.use(Vuex)
    export default new Vuex.Store({
        state: {
            user: null
        },
        mutations: {
            SET_USER(state, user) {
                state.user = user
            }
        },
        actions: {
            getUser({ commit }, userInfo) {
                commit('SET_USER', userInfo)
            }
        },
        plugins: [createPersistedState()]
    })
    

    Here, we add a user state that would store user data from the form created in the previous section. We also add a SET_USER mutation that would be used in modifying the user state. Finally, we add a getUser action that would receive the user object and pass it to the SET_USER mutation property. The next would be to dispatch this action after validating our form successfully. This looks like this:

    methods: {
        login() {
          this.submitted = true;
          let invalidForm = this.$v.form.$invalid;
          let form = this.form;
          //check that every field in this form has been entered correctly.
          if (!invalidForm) {
            // process the form data
            this.$store.dispatch("getUser", form);
          }
        },
      },
    

    Now, if you correctly fill the form, submit it, and open the localStorage section in the applications tab in the devTools of your browser, you should see a vuex property that looks like this:

    vuex-persistedstate in localStorage
    Vuex store in localStorage (Large preview)

    At this point, if you refresh your browser or open your app in a new tab, your user state would still persist across these tabs/session (on localStorage).

    Conclusion

    There are a lot of libraries that can be very useful in Vuejs web development and sometimes it can be hard to choose the one to use or where to find them. The following links contain libraries that you can use in your Vue.js application.

    1. vuejsexamples.com.
    2. madewithvuejs.com.

    There is often more than one library that does the same thing that you’re trying to achieve in your application when searching for a ‘library’, the important thing is to make sure the option you settle for works for you and is being maintained by its creator(s) so it doesn’t cause your application to break.

    Further Resources

    Smashing Editorial
    (ks, ra, il)

    Source link

    web design

    5 Ways Google Analytics Helps Web Developers In UI/UX Design — Smashing Magazine

    09/30/2020

    About The Author

    Clara Buenconsejo currently works as a Digital Marketing Consultant for The Clay Media, a niche web development and digital marketing agency. While she’s …
    More about
    Clara

    Ever wondered what all those Google Analytics code snippets are for and why your marketing team regularly asks you to add a new one? In this article, we’ll look at 5 features in Google Analytics that can help web developers and designers in making a better user experience on their website.

    Google Analytics is one of the most popular marketing analytics platforms out there — and not just because its standard version is free. More than a million organizations worldwide use this platform to gain better insights on user behavior on their websites.

    However, for most web developers, their involvement with Google Analytics ends with just installing the base code for pageviews. This code usually looks like this, when using the gtag.js version of the code:

    <!-- Global site tag (gtag.js) - Google Analytics -->
    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-35169008-1"></script>
    <script>
      window.dataLayer = window.dataLayer || [];
      function gtag(){dataLayer.push(arguments);}
      gtag('js', new Date());
    
      gtag('config', 'UA-35169008-1');
    </script>
    

    Or it looks like this, with the analytics.js implementation:

    <!-- Google Analytics -->
    <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
    
    ga('create', 'UA-XXXXX-Y', 'auto');
    ga('send', 'pageview');
    </script>
    <!-- End Google Analytics -->
    

    While there’s already many data points made available with this basic implementation, they end up missing out on other key features. Due to the lack of available data to consult, there have even been cases where web developers or designers choose to remove a specific feature on the site, without realizing that most users use that feature regularly.

    Hence, here are five of the most important features in Google Analytics that you can utilize to improve user experience — and separate you from the rest of the web developers and designers out there:

    1. Use Events To Identify User Interactions On Specific Parts Of Your Website

    As stated above, the basic Google Analytics code only tracks pageviews by default. If you want to track actions on your website, such as button clicks or form submissions, you’ll need to fire a separate Google Analytics event. These events can be implemented by adding the following code with the appropriate Event Category, Action, and Label information:

    ga('send', {
      hitType: 'event',
      eventCategory: 'Event Category',
      eventAction: 'Event Action',
      eventLabel: 'Event Label'
    });

    A shorthand version of the code is also available in this format:

    ga('send', 'event', 'Event Category', 'Event Action', 'Event Label');

    Once the events are set up, they will show up in the Google Analytics UI under the Behavior > Events > Top Events report:

    Where to find the Behavior > Events > Top Events report in Google Analytics
    Where to find the Top Events report in Google Analytics. (Large preview)

    As a best practice, you can use Event Category to group events based on a specific function (ex. Page Engagement, Ecommerce). Meanwhile, you can use Event Action to identify the exact action the user made (Click, Scroll, Form Submission) while you can use Event Label to get the URL where the event was fired.

    Alternatively, a better way to implement these events would be to use Google Tag Manager instead. In lieu of the actual Google Analytics code, you will need to install the Google Tag Manager code instead:

    <!-- Google Tag Manager -->
    <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
    new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
    j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
    'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
    })(window,document,'script','dataLayer','GTM-5PLFVFV');</script>
    <!-- End Google Tag Manager -->

    Then once Google Tag Manager is set up, all you need to do is to set up the Google Analytics Page View tag and the Event tags you need. Simply create a new Tag by clicking the “New” button, then click on Tag Configuration, and Google Analytics will be one of the default options available:

    Google Tag Manager - Creating a Google Analytics tag in Tag Configuration settings
    Creating a Google Analytics tag in Google Tag Manager. (Large preview)

    You’ll then be able to select between the different Google Analytics tag types, which includes “Event” as one of them. Once you’ve filled in the Tag Configuration details, you’ll just need to set up the appropriate trigger to fire the event. There are already built-in triggers such as clicks on Google Tag Manager; you’ll just need to select the one suitable for your event.

    Don’t forget to test the tag in Google Tag Manager’s preview mode, then click publish once the set up is complete.

    Take note that it’s important to be careful when you’re implementing events via Google Tag Manager or by adding the actual code for events via Google Analytics. Whatever approach you choose for implementation should be the same all throughout the site. Either you go all the way with Google Tag Manager or with hard-coding the actual event code.

    Otherwise, you may end up tracking the same website action twice — once by adding the event code, another via Google Tag Manager — and recording duplicate data inside Google Analytics.

    Adding events even become more important when it comes to setting up Ecommerce and Enhanced Ecommerce tracking for Google Analytics. While you do need to turn on these settings in the Google Analytics interface, you’ll need to go back to your tracking and add separate ecommerce events. These events are needed to send the complete set of e-commerce data back to the Google Analytics servers.

    2. Learn How Far Users Scroll Down The Page With Scroll Tracking Events

    Other than tracking clicks and form submissions, events in Google Analytics can be also used for scroll tracking. This can be done by adding the Google Analytics event code to fire once a specific element appears in the viewport. You can also set the code to fire if the user has scrolled a specific percentage down the screen.

    Alternatively, in Google Tag Manager, scroll tracking can be implemented much easier by using the Scroll Depth trigger. All you need to do is to create a new trigger, select the “Scroll Depth” trigger type, then fill in the necessary details.

    Google Tag Manager - Finding the Scroll Depth trigger option
    The Scroll Depth trigger type in Google Tag Manager. (Large preview)

    So how can this feature help you in terms of user experience? For starters, this obviously can help you determine up to what part of the page are users willing to scroll down. Since that data is in Google Analytics, you can segment that data based on device or browser, time of day, location, etc.

    That way, if you’re deciding whether you can place a specific widget for a specific kind of user, you have some data to back up your decision. This can also eliminate the need to purchase separate scroll tracking software, as all you’ll need is a bit of time to implement this feature.

    3. Get An Estimate Of How Much Time They Actually Spend On Your Website

    Learning up to where people scroll is one thing; finding out how much time they spend on the site is another. Thankfully that’s also possible to measure with Google Analytics.

    By default, after installing the Google Analytics pageview tag, users can already get a metric called Avg. Session Duration. This metric is generally understood to measure the amount of time that a user spends on each visit to your website (a session).

    However, this metric can be inaccurate at times. After all, Google Analytics really only measures Avg. Session Duration based on the timestamps of the data (hits) that it receives.

    This also explains why most bounces — or visits on the website with either only one pageview or event in them — have an Avg. Session Duration of 00:00:00.

    So how would you get around this limitation? By firing timing hits. These can help accurately calculate the amount of time a user spends on a page without recording another pageview or event. You just need to send the timing hits by implementing this code to fire at specific intervals on your site:

    ga('send', 'timing', [timingCategory], [timingVar], [timingValue], [timingLabel], [fieldsObject]);

    A more detailed description of each field is available on the Google Developers’ site.

    Once implemented, these hits will be visible in the Behavior > Site Speed > User Timings section in Google Analytics.

    Alternatively, since timing hits have a cap of 10,000 hits per day, you can create custom events that fire at specific intervals instead. Like other regular events, these would then be visible in the Behavior > Events > Top Events section.

    A word of caution when setting up timing hits, however: make sure to add a “timeout” of sorts for them. That way these hits won’t continuously fire — and the data sent to Google Analytics — for too long, if the page was just left open on an unattended browser.

    4. Find Out Where Users Get Stuck Or Other Pain Points On The Website

    Once you’ve implemented events and timing hits on Google Analytics, you’d see them in the different sections of the platform. However, this introduces a new challenge: how can you unite these different data points into one report that shows the entire user journey on your website?

    That’s where the Behavior Flow report in Google Analytics comes into play. This report, which appears as a flowchart, shows how users arrive at the site and the subsequent pageviews or actions they take before dropping off.

    Google Analytics: Behavior Flow Report
    The Behavior Flow report in Google Analytics. (Large preview)

    By default, the Behavior Flow report uses the Landing Page and the specific pages that groups of users go to.

    You can also change the Behavior Flow report to focus more on events. Simply click to the dropdown menu below the report’s header and select “Events” or “Pages and Events.”

    Google Analytics Behavior Flow Report - View Options
    Google Analytics Behavior Flow Report — View Options. (Large preview)

    A little caveat with using the Behavior Flow reports, however: when looking at data for larger websites, such as those with millions of pageviews, sampling may occur. This sampling is set in place to help Google Analytics crunch through all the data in a specific amount of time.

    To minimize sampling, you can adjust the date range covered by the Behavior Flow report to reduce the amount of data that Google Analytics needs to analyze. In addition, you can also adjust the granularity of your analysis by clicking on the “Level of Detail” dropdown and setting it to “Show fewer connections.”

    Google Analytics Behavior Flow Report - Level of Detail Options
    Adjust granularity in the Google Analytics Behavior Flow Report by selecting the ‘Level of Detail’ option. (Large preview)

    If the Behavior Flow report is not enough, you can also set up Custom Reports in Google Analytics. To set these up, go to Customization > Custom Reports, then click the “New Custom Report” button.

    Google Analytics Custom Reports - How to access custom reports
    Where to access Custom Reports in Google Analytics. (Large preview)

    Custom Reports can come in three different formats:

    • Explorer, which looks similar to the default Google Analytics reports.
    • Flat Table.
    • Map, best for geographic overlays.

    You can also adjust the settings to filter based on specific metrics using exact match or regular expressions.

    That said, some dimensions and metrics may appear off when combined with each other. This may be due to these metrics having different scopes–one metric may be measured at the user level, while another metric may be measured at the session (website visit) level. For more information about Google Analytics scopes, you can check out the Processing section of this Google Analytics Help Center article.

    5. Discover The Kinds Of User Behavior That Lead To Conversions And Which Actions Don’t

    At the end of the day, a client or your employer is having a website made to achieve a tangible objective. This can be as diverse as selling your company’s products online (ecommerce), generating sign-ups for a service (lead generation), or even just to promote the company’s services (awareness).

    That’s where the true strength of Google Analytics lies. By collecting data based on a combination of pageviews and different events, you can get more in-depth insights into what users actually do on your website. In addition, you can isolate specific key actions as conversions on your website by creating goals.

    To do so, simply go to Admin > Goals, and then click New Goal. You can then choose from a template or set up a custom goal based on a destination ‘pageview of a specific page), events, duration, or even a number of pageviews.

    Google Analytics Goals - Accessing Goals in Admin Section
    Access goals in Google Analytics by going to Admin > Goals. (Large preview)
    Google Analytics - Goal Settings
    Set up conversions with Google Analytics goal settings. (Large preview)

    Once you’ve set up your goals, you can then use Google Analytics segments to analyze the actions that users with conversions have, versus those who did not convert. This is available by default — simply select the Converters or the Non-Converters segments to apply on your reports.

    Google Analytics Segments: Selecting the Converters Segment
    Google Analytics Segments: Selecting the Converters Segment. (Large preview)

    If you want more specific segments regarding conversions, you can click on the Actions option to copy the segment and add your own criteria. For example, you can add age, gender, location, or language for further filtering based on demographics. You can also create segments based on how users got to your site (source and medium), the device they’re using, or even based on the chain of actions they took on your site (under Advanced > Sequences).

    Of course, you can always create segments from scratch in Google Analytics. Simply open the Segments dropdown then click on the red New Segment button to make your own.

    Google Analytics Segments - Segment Options
    Google Analytics Segments — Segment Options. (Large preview)

    With all these features available for free, Google Analytics is truly one of the most powerful tools that any web developer or designer can utilize. However, adding these features to your site is just the tip of the iceberg. There are so many other functionalities there to explore, such as the Measurement Protocol that allows Google Analytics to collect data from IoT devices.

    To know more about Google Analytics, you can check out these official Google resources:

    Lastly, before implementing Google Analytics, make sure to double-check the data privacy regulations in your region to avoid any unintentional violations. For more information about ensuring compliance with these regulations, please consult this Google Support article.

    By balancing the end user’s data privacy rights plus the need to collect data for actionable insights, Google Analytics is definitely one of the finest tools for UI/UX design that’s out in the market.

    Smashing Editorial
    (ra, yk, il)

    Source link

    web design

    How To Build Rapport With Your Web Design Clients — Smashing Magazine

    09/21/2020

    About The Author

    Matt is a passionate social entrepreneur helping purposeful organisations make greater impact with digital technology. He provides development support for …
    More about
    Matt

    Building positive relationships with your clients is the secret ingredient to delivering better work, earning more money, and creating lasting partnerships. In this article, Matt Saunders offers some straightforward advice on how you can become a more business-savvy web de-signer and take your practice to the next level.

    Working as a freelancer in the creative space is rife with obstacles. Some we can see coming, others we can’t.

    One of the challenges that many freelance web designers face in their first few years is managing client relationships. We’ve all heard about — and experienced — the horrors of clients running amok on our work, turning a piece of thoughtfully-considered design into a playground of questionable ideas that often run against best practice.

    When these situations are not managed delicately, the client-designer relationship can break down, invoices may go unpaid, and as a result, websites go unlaunched. This is a scenario that no designer — or indeed no client — wants to be a part of.

    In this article, I’m going to teach some strategies for managing client communication and processes that have helped me to run less stressful projects and achieve better results, as well as draw upon some best practices to help you manage the business side of your work.

    My False Start

    When I started freelancing in 2009, I had very little experience in dealing with clients. I’d only graduated from university two years prior and had been in a steady job ever since. And that job was in-house at an office supplies company, which means that the closest I came to having a client was my boss, which is nothing like the client-designer relationship at all.

    Thus, once I started my own practice, I was not equipped with strategies for managing clients and expectations. As you might imagine, things didn’t go very well.

    As a result, working with a diverse range of clients, from small to large and with varying technical requirements was a challenge. My business acumen left a lot to be desired, and I knew it. I was not confident in my sales skills and this mindset shook the very foundation of my service. It led to me producing lesser-quality, lower-paid work for clients who had little understanding of the design process.

    At the time, I blamed the clients. But, in hindsight, I see that the problem was being caused by the way that I was doing business. I would wonder how other designers — those well-known faces in the industry — managed to produce much better, more profitable work and seem happy about it. This was truly an enigma to me at the time, and as I said: it was easier to blame others than to look inward and resolve the problem at its core.

    What Was The Problem?

    The main issue was one of mindset. When I dug down, I realized that I didn’t consider myself worthy of their business. This manifested in a lack of confidence in my work and some eye-wateringly low prices.

    “We need a homepage design with unlimited revisions — how much?”

    “£20.”

    Ouch.

    Frankly, it doesn’t matter if you’re reading this as a new freelancer, an experienced business owner or an in-house designer; if your mindset is not geared toward building confidence and rapport in your professional relationships, you’ll constantly face challenges in dealing with other people.

    Hands at a laptop working on a website next to a sketch of some wireframes
    It can be really tough to do good work that you care about if you don’t value your expertise. (Image source) (Large preview)

    I realized over time that the way I was looking at my business was upside down. I focused too much on the output (the website design, the money) and not the input (building a relationship with the client).

    So I switched it around.

    Developing Relationships (Not Just Websites)

    In business, at least a part of your motivation must be to develop relationships with clients. It’s important to recognize that clients work with you to solve their business problems. They’re not buying a website: they’re buying a tool to reach some business goal. It took me years to fully appreciate that clients care very little about your tech skills or design flair. They care much more deeply about your ability to help them reach their goals and, less-apparently, how you make them feel during that process.

    To earn respect from your clients and to establish yourself as an authority in your area of work, you need to look beyond your core skill-set. You need to put processes in place, backed by a growth mindset that will see you handle tough situations. Here are some top tips for doing that:

    1. Get Your Formal Processes In Place, And Follow Them

    When starting out as a freelancer it is tempting to work without a contract and without taking a deposit payment. This is a problem because according to a private survey conducted by creative freelancer platform YunoJuno, 55% of its UK members have not been paid for work at some point in their career.

    Putting procedures in place isn’t a silver bullet, but it can mitigate the risk. If you’re operating without contracts and deposit payments, you face two very real problems:

    • You have less security.
    • You’ll be taken less seriously.

    Your client could cancel the project or make unreasonable requests of you. It is vital to establish the goalposts in a written contract, and take at least some of the payment upfront. This gives you security and leverage if things start to go wrong.

    “I’ve been stiffed by clients, experienced scope creep like you couldn’t imagine, spent months on a ‘rush job’, and on occasion, completely lost track of half-completed projects.”

    — Jenny Knizner, VP of marketing at job portal Moon-lighting

    When you take the time to put processes in place, those formalities that you once considered inconvenient can really become a saving grace.

    Hand writing signature on a piece of paper
    Making sure you have formal processes in place can save a lot of headaches down the road. (Image source) (Large preview)

    But perhaps most importantly of all, following these basic rules helps to establish you as a professional. It sends out a message that you take your work and your time seriously. And if a prospective client is reluctant to make any contractual commitments, that’s a pretty good sign for what working with them might be like.

    The foundation for leveling-up your web design business starts by tackling the basics.

    2. Don’t Hide Behind Your Email

    To establish rapport with your client, you’re going to have to talk to them. Face-to-face meetings in person are great, but so are video calls. And there is really no excuse to not do at least do the latter, especially since we’re all familiar with video conferencing now.

    As industry veteran Paul Boag explains in his book Digital Adaptation:

    “Digital does not work well in a world of departmental divisions. People need to sit together, work together, and solve problems together.”

    This means you need to spend real time with your clients, doing real work, and not skirt around big topics over email or any lesser medium.

    Distance creates disconnect, and email sure creates some distance. It has its uses, but when it comes to discussing big ideas, it can be very limiting. If you want to be seen as a project leader, somebody who knows their stuff and can be trusted, it means showing your face once in a while. It means giving your client (and the project) the time and space it deserves to grow and evolve.

    Web design is a service-led industry, and good service is built on clear communication.

    3. Get To Know Your Clients

    Clients are people. People have motivations, dreams, fears and problems just like you. It’s so easy, especially if you hold them at arm’s length, to see clients simply as projects. You’ll have a significantly easier time if you earn their trust by getting to know them. They will be more likely to pay you on time and respect your design decisions. Trust is not earned through emails where you only talk about work. Trust is built by taking the time to speak, face to face, about things other than work. Don’t be afraid to make small talk about weekend plans or current affairs, and observe how your relationship matures to a point of mutual respect.

    “It’s in small talk, in conversations unrelated to work, where we explore other aspects of the person with whom we’re conversing… Big relationships are built on small talk.”

    — David Burkus, author of “Friend of a Friend”

    When was the last time you spoke with a client about something other than your work? Take the time to do this to strengthen your relationship, but be mindful of the line between friendship and a professional partnership. Be friendly with your clients, but know that they’re not your friends. This blurring of boundaries can lead to a relaxing of your professional processes, and before you know it you’re chatting at 9 PM and doing everything for “mates rates”.

    4. Build Long-Term Relationships

    If you want to truly build a business, and not become some transient freelancer who ultimately gives up and goes back into full-time employment, you need to think of your client relationships in the longer term.

    This means digging into their goals and their business well-beyond what your project will deliver in the first instance. Consider how you can help them in other ways: read an article relevant to them? Send them it. Stumbled across a new piece of software that could make them more efficient? Recommend it to them. Find ways of delivering value to them, and it will come back to you in more work and referrals.

    Repeat business is important because the average repeat customer spends 67% more in months 31-36 of their relationship with a business than they do in months 0-6. This particular study pertains to e-commerce sales but I have seen similar patterns in the B2B space also. It’s really all about trust. Once you’ve earned it, they’ll come back for more.

    Woman sitting at laptop on video call with three others
    Getting to know your clients on a more personal level will strengthen your relationship, earn you their trust and lead to repeat business. (Image source) (Large preview)

    Taking the time to foster a relationship with your client helps to shift your thinking away from seeing them as a means to pay the rent this month, to looking at them more as a long term partner.

    5. Practice Your Self-Development

    If you’re anything like me, achieving the previous four points would have felt like a steep hill to climb when I started over 10 years ago. Being able to really grasp a piece of work and manage the project and people effectively takes experience, confidence, and skill.

    For the main part, much of this depends on peeking outside your comfort zone. Running video calls with multiple stakeholders, managing conversations with clients, and insisting on good practices (such as contract signing) all require a level of assertiveness that doesn’t come naturally to many people.

    If you struggle with self-confidence and feel ready to build your resilience, read up on things like positive affirmations and assertiveness skills. These “self-help” ideas are easy to sneer at but they will provide you with practical tools to seriously boost your confidence and grow as a professional.

    In Summary, The Product Comes Second To The Service You Deliver

    Website development is a service. Clients pay for the end product, but the experience they have in working with you will be remembered. How you make people feel matters.

    To quote Simon Sinek’s book Start with Why as mentioned above:

    “People don’t buy what you do, they buy why you do it.”

    If you want to do better work for more money and be respected along the way, taking the time to grow as a professional and go the extra mile in how you manage clients can do a lot for you.

    Whether you’re embarking on a freelance career, or you’ve been around for a while, I urge you to invest some time in reflecting on your work process and communication skills. Reflect on how you’ve done business to date, and consider what the next 3 years might look like for you. The service element of the web design industry is only getting more competitive, sophisticated, and demanding. But with demand comes amazing opportunities. Are you prepared for it?

    Smashing Editorial
    (ah, yk, il)

    Source link

    web design

    4 Lessons Web App Designers Can Learn From Google — Smashing Magazine

    08/12/2020

    About The Author

    Suzanne Scacca is a former WordPress implementer, trainer and agency manager who now works as a freelance copywriter. She specializes in crafting marketing, web …
    More about
    Suzanne
    Scacca

    There’s a reason why Google dominates market share for things like search engines, web browsers, email clients and cloud storage services. It knows exactly what consumers want and it has designed simple, intuitive, and useful solutions for them. If there’s one company whose product features you should be mirroring, it’s Google.

    Whenever I’m curious about what more we could be doing to improve our users’ experiences, the first place I look to is Google. More specifically, I go to the Google Developers site or Think with Google to pull the latest consumer data.

    But I was thinking today, “Why don’t we just copy what Google does?”

    After all, Google has to walk the walk. If not, how would it ever convince anyone to adhere to its SEO and UX recommendations and guidelines?

    The only thing is, Google’s sites and apps aren’t very attractive. They’re practical and intuitive, that’s for sure. But designs worth emulating? Eh.

    That doesn’t really matter though. The basic principles for building a good web app exist across each of its platforms. So, if we’re looking for a definitive answer on what will provide SaaS users with the best experience, I think we need to start by dissecting Google’s platforms.

    What Google Teaches Us About Good Web App Design

    What we want to focus on are the components that make Google’s products so easy to use time and time again. By replicating these features within your own app, you’ll effectively reduce (if not altogether remove) the friction your users would otherwise encounter.

    1. Make the First Thing They See Their Top Priority

    When users enter your dashboard, the last thing you want is for them to be overwhelmed. Their immediate impression whenever they enter your app or return to the dashboard should be:

    “I’m exactly where I need to be.”

    Not:

    “What the heck is going on here? Where do I find X?”

    Now, depending on the purpose of your app, there are usually one or two things your users are going to be most concerned with.

    Let’s say you have an app like Google Translate that has a clear utilitarian purpose. There’s absolutely no excuse for cluttering the main page. They’ve come here to do one thing:

    Google Translate translator tool
    Google Translate users don’t have to hunt around for the translator tool. (Source: Google Translate) (Large preview)

    So, don’t waste their time. Place the tool front and center and let all other pages, settings or notices appear as secondary features of the app.

    Something else this example teaches us is how you should configure your tool for users. Google could easily just leave this open-ended, but it defaults to:

    Default Language —> English

    Google’s data likely shows that this is the most popular way users use this app.

    Although you can’t see it in the desktop app, you can see it on mobile. The formula goes like this:

    Default Language —> Recent Language

    I suspect that, for first-time users, Google will set the translation to the user’s native language (as indicated in their Google user settings).

    If you have the data available, use it to configure defaults that reduce the number of steps your users have to take, too.

    Not every web app provides users with a hands-on tool for solving a problem. In some cases, apps enable users to streamline and automate complex processes, which means their primary concern is going to be how well those processes are performing.

    For that, we can look at a product like Google Search Console, which connects users to data on how their sites perform in Google search as well as insights into problems that might be holding them back.

    It’s no surprise then that the first thing they see upon entering it is this:

    Google Search Console overview - Performance and Coverage stats
    The Google Search Console overview page shows users stats on Performance and Coverage. (Source: Google Search Console) (Large preview)

    Performance (the number of clicks in Google search) and Coverage (number of pages indexed without error) are above the fold. Below it is another chart that displays recommended enhancements to improve core web vitals, mobile usability and sitelinks searchbox visibility.

    Bottom line: The Overview page isn’t littered with charts depicting every data point collected by Google Search Console. Instead, it displays only the top priorities so users can get a bird’s-eye view of what’s going on and not get lost in data they don’t need at that time.

    2. Create a Useful and Simple Navigation Wherever Relevant

    This one seems like a no-brainer, but I’ll show you why I bring it up.

    Zoom is a great video conferencing app. There’s no arguing that. However, when users want to schedule a meeting from their browser, this is what they see:

    Zoom in-browser web app with multiple menus to choose from
    The Zoom web app complicates things with multiple menus. (Source: Zoom) (Large preview)

    The “Join Meeting” and “Host Meeting” options are fine as they both eventually push the user into the desktop app. However, the “Schedule Meeting” in-browser experience isn’t great because it leaves the website navigation bars in place, which only serves as a distraction from the app’s sidebar on the left.

    Once your users have created a login and have access to your app, they don’t need to see your site anymore. Ditch the website navigation and let them be submersed in the app.

    Or do as Google Hangouts does. Lay your app out the way users expect an app to be laid out:

    • Primary navigation along the left side,
    • Hamburger menu button and/or More (…) button contain the secondary navigation,
    • Wide open space for users to play in the app.
    Google Hangouts distraction-free interface and simple navigation
    A look inside Google Hangouts and its distraction-free interface and navigation. (Source: Google Hangouts) (Large preview)

    But Google Hangouts doesn’t do away with the google.com website completely. For users that want to quickly navigate to one of Google’s other products, they can use the grid-shaped icon in the top-right corner. So, if you feel it’s necessary for your users to be able to visit your website once again, you can build it into the app that way.

    This example also demonstrates how important it is to keep your navigation as simple as possible.

    Google Hangouts’ primary navigation uses symbols to represent each of the app’s tabs/options:

    Google Hangouts primary navigation design - icons only
    Google Hangouts uses icons to represent the tabs of its primary navigation. (Source: Google Hangouts) (Large preview)

    While I think it’s okay for Google Hangouts to get away with this icon-only menu design, be careful with this approach. Unless the icons are universally understood (like the hamburger menu, search magnifying glass, or the plus sign), you can’t risk introducing icons that create more confusion.

    As NNG points out, there’s a difference between an icon being recognizable and its meaning being indisputable.

    So, one way you can get around this is to make the outward appearance of the menu icon-only. But upon hover, the labels appear so that users have additional context for what each means.

    As for any secondary navigation you might need — including a Settings navigation — you can write out the labels since it will only appear upon user activation.

    Google Hangouts secondary navigation design - icons and labels
    The Google Hangouts secondary navigation uses an icon and label for each tab. (Source: Google Hangouts) (Large preview)

    Although some of the icons would be easy enough to identify, not all of them would instantly be recognizable (like “Invites” and “Hangouts Dialer”). If even one tab in your secondary navigation is rarely seen across other apps, spell them all out.

    One last thing: The divider lines in this menu are a great choice. Rather than jam 10 tabs/options into this navigation bar together, they’re logically grouped, making it easier for users to find what they’re looking for.

    3. Provide Users with Predictive Search Functionality

    Every app should have a search bar. It might be there to help users sift through content, to find the contact they’re looking for from a long list, or to ask a question about something in the app.

    The more complex your app is, the more critical a role internal search is going to play. But if you want to improve your users’ search experience even more, you’ll want to power yours with predictive search functionality.

    Even though I’m sure you have a Support line, maybe a chatbot and perhaps an FAQs or Knowledgebase to help users find what they need, a smart search bar can connect them to what they’re really looking for (even if they don’t know how to articulate it).

    Google has this search functionality baked into most of its products.

    You’re familiar with autocomplete within the Google search engine itself. But here are some other use cases for smart search capabilities.

    Google Drive connects users to documents (of all types — Docs, Sheets, Slides and more) as well as collaborators that match the search query.

    Google Drive search for 'speed'
    An example search for ‘speed’ within Google Drive. (Source: Google Drive) (Large preview)

    Users can, of course, be taken to a full search results page. However, the search bar itself predicts which content is the most relevant for the query. In this case, these are the most recent pieces of content I’ve written that include the term “speed” in the title.

    Google Maps is a neat use case as it pulls data from a variety of connected (Google) sources to try and predict what its users are looking for.

    Google Maps predictive search example 'Alicia'
    Google Maps pulls from a variety of sources to predict where users want to travel to. (Source: Google Maps) (Large preview)

    In this example, I typed in “Alicia”. Now, Google Maps knows me pretty well, so the first result is actually the address of one of my contacts. The remaining results are for addresses or businesses within a 45-mile radius containing the word “Alicia”.

    It doesn’t just pull from there though. This is one of those cases where the more enjoyable you make the in-app experience, the more your users will engage with it — which means more data.

    For example, this is what I see when I search for “Three”:

    Google Maps displays a 'Favorite' location when a user searches for 'three'
    Google Maps will provide ‘Favorite’ locations in search results when relevant. (Source: Google Maps) (Large preview)

    The very first thing it pulls up is a restaurant called Three Sisters (which is a fantastic restaurant in the city of Providence, by the way). If you look just above the center of the map where the red heart is, that’s the restaurant. This means that I’ve added it to my Favorite places and Google Maps actually calls it out as such in my search results.

    Imagine how much more your users would love your app if it wasn’t always a struggle to get to the content, data or page they were looking for. Or to perform a desired action. When you give your users the ability to personalize their experience like this, use the information they’ve given you to improve their search experience, too.

    4. Enable Users to Change the Design and Layout of the App

    As a designer, you can do your best to design a great experience for your users. But let’s face it:

    You’re never going to please everyone.

    Unlike a website, though, which is pretty much what-you-see-is-what-you-get, SaaS users have the ability to change the design and layout of what they’re interacting with — if you let them. And you should.

    There are many different ways this might apply to the app you’ve built.

    Google Calendar, for example, has a ton of customization options available.

    Google Calendar - view customizations
    Google Calendar allows users to customize the look and view of their calendars. (Source: Google Calendar) (Large preview)

    On the far left is a list of “My calendars”. Users can click which calendars and associated events they want to see within the app.

    In the bottom-right corner is an arrowhead. This enables users to hide the Google apps side panel and give them more room to focus on upcoming events and appointments.

    In the top-right, users have two places where they can customize their calendar:

    • The Settings bar allows them to adjust the color and density of the calendar.
    • The “Month” dropdown allows them to adjust how much of the calendar is seen at once.

    These customizations would all be useful for any sort of project management, planning or appointment scheduling app.

    For other apps, I’d recommend looking at Gmail. It’s chock full of customizations that you could adapt for your app.

    Previously, if users clicked the Settings widget, it would move them out of the app and into the dedicated settings panel. To be honest, it was annoying, especially if you just wanted to make a small tweak.

    Gmail Settings panel - design and layout customization options
    Gmail’s Settings reveals a list of design and layout customization options. (Source: Gmail) (Large preview)

    Now, the Settings button opens this panel within Gmail. It enables users to adjust things like:

    • Line spacing,
    • Background theme,
    • Inbox sorting priorities,
    • Reading pane layout,
    • Conversation view on/off.

    This is a recent update to Gmail’s settings, which probably means these are the most commonly used design customizations its users actually use.

    For any customizations users want to make that they can’t find in this new panel, they can click “See all settings” and customize the in-app design and layout (among other things) even further.

    Other customizations you might find value in enabling in your app are:

    • Keyboard control,
    • Dark mode,
    • Color-blind mode,
    • Text resizing,
    • List/grid view toggling,
    • Widget and banner hiding,
    • Columns displayed.

    Not only do these design and layout controls enable users to create an interface they enjoy looking at and that works better for their purposes, it can also help with accessibility.

    Wrapping Up

    There’s a reason why Google dominates market share with many of its products. It gets the user experience. Of course, this is due largely to the fact that it has access to more user data than most companies.

    And while we should be designing solutions for our specific audiences, there’s no denying that Google’s products can help us set a really strong base for any audience — if we just pay attention to the trends across its platforms.

    Further Reading on SmashingMag:

    Smashing Editorial
    (ra, yk, il)

    Source link

    web design

    4 Lessons Web App Designers Can Learn From Google — Smashing Magazine

    08/12/2020

    About The Author

    Suzanne Scacca is a former WordPress implementer, trainer and agency manager who now works as a freelance copywriter. She specializes in crafting marketing, web …
    More about
    Suzanne
    Scacca

    There’s a reason why Google dominates market share for things like search engines, web browsers, email clients and cloud storage services. It knows exactly what consumers want and it has designed simple, intuitive, and useful solutions for them. If there’s one company whose product features you should be mirroring, it’s Google.

    Whenever I’m curious about what more we could be doing to improve our users’ experiences, the first place I look to is Google. More specifically, I go to the Google Developers site or Think with Google to pull the latest consumer data.

    But I was thinking today, “Why don’t we just copy what Google does?”

    After all, Google has to walk the walk. If not, how would it ever convince anyone to adhere to its SEO and UX recommendations and guidelines?

    The only thing is, Google’s sites and apps aren’t very attractive. They’re practical and intuitive, that’s for sure. But designs worth emulating? Eh.

    That doesn’t really matter though. The basic principles for building a good web app exist across each of its platforms. So, if we’re looking for a definitive answer on what will provide SaaS users with the best experience, I think we need to start by dissecting Google’s platforms.

    What Google Teaches Us About Good Web App Design

    What we want to focus on are the components that make Google’s products so easy to use time and time again. By replicating these features within your own app, you’ll effectively reduce (if not altogether remove) the friction your users would otherwise encounter.

    1. Make the First Thing They See Their Top Priority

    When users enter your dashboard, the last thing you want is for them to be overwhelmed. Their immediate impression whenever they enter your app or return to the dashboard should be:

    “I’m exactly where I need to be.”

    Not:

    “What the heck is going on here? Where do I find X?”

    Now, depending on the purpose of your app, there are usually one or two things your users are going to be most concerned with.

    Let’s say you have an app like Google Translate that has a clear utilitarian purpose. There’s absolutely no excuse for cluttering the main page. They’ve come here to do one thing:

    Google Translate translator tool
    Google Translate users don’t have to hunt around for the translator tool. (Source: Google Translate) (Large preview)

    So, don’t waste their time. Place the tool front and center and let all other pages, settings or notices appear as secondary features of the app.

    Something else this example teaches us is how you should configure your tool for users. Google could easily just leave this open-ended, but it defaults to:

    Default Language —> English

    Google’s data likely shows that this is the most popular way users use this app.

    Although you can’t see it in the desktop app, you can see it on mobile. The formula goes like this:

    Default Language —> Recent Language

    I suspect that, for first-time users, Google will set the translation to the user’s native language (as indicated in their Google user settings).

    If you have the data available, use it to configure defaults that reduce the number of steps your users have to take, too.

    Not every web app provides users with a hands-on tool for solving a problem. In some cases, apps enable users to streamline and automate complex processes, which means their primary concern is going to be how well those processes are performing.

    For that, we can look at a product like Google Search Console, which connects users to data on how their sites perform in Google search as well as insights into problems that might be holding them back.

    It’s no surprise then that the first thing they see upon entering it is this:

    Google Search Console overview - Performance and Coverage stats
    The Google Search Console overview page shows users stats on Performance and Coverage. (Source: Google Search Console) (Large preview)

    Performance (the number of clicks in Google search) and Coverage (number of pages indexed without error) are above the fold. Below it is another chart that displays recommended enhancements to improve core web vitals, mobile usability and sitelinks searchbox visibility.

    Bottom line: The Overview page isn’t littered with charts depicting every data point collected by Google Search Console. Instead, it displays only the top priorities so users can get a bird’s-eye view of what’s going on and not get lost in data they don’t need at that time.

    2. Create a Useful and Simple Navigation Wherever Relevant

    This one seems like a no-brainer, but I’ll show you why I bring it up.

    Zoom is a great video conferencing app. There’s no arguing that. However, when users want to schedule a meeting from their browser, this is what they see:

    Zoom in-browser web app with multiple menus to choose from
    The Zoom web app complicates things with multiple menus. (Source: Zoom) (Large preview)

    The “Join Meeting” and “Host Meeting” options are fine as they both eventually push the user into the desktop app. However, the “Schedule Meeting” in-browser experience isn’t great because it leaves the website navigation bars in place, which only serves as a distraction from the app’s sidebar on the left.

    Once your users have created a login and have access to your app, they don’t need to see your site anymore. Ditch the website navigation and let them be submersed in the app.

    Or do as Google Hangouts does. Lay your app out the way users expect an app to be laid out:

    • Primary navigation along the left side,
    • Hamburger menu button and/or More (…) button contain the secondary navigation,
    • Wide open space for users to play in the app.
    Google Hangouts distraction-free interface and simple navigation
    A look inside Google Hangouts and its distraction-free interface and navigation. (Source: Google Hangouts) (Large preview)

    But Google Hangouts doesn’t do away with the google.com website completely. For users that want to quickly navigate to one of Google’s other products, they can use the grid-shaped icon in the top-right corner. So, if you feel it’s necessary for your users to be able to visit your website once again, you can build it into the app that way.

    This example also demonstrates how important it is to keep your navigation as simple as possible.

    Google Hangouts’ primary navigation uses symbols to represent each of the app’s tabs/options:

    Google Hangouts primary navigation design - icons only
    Google Hangouts uses icons to represent the tabs of its primary navigation. (Source: Google Hangouts) (Large preview)

    While I think it’s okay for Google Hangouts to get away with this icon-only menu design, be careful with this approach. Unless the icons are universally understood (like the hamburger menu, search magnifying glass, or the plus sign), you can’t risk introducing icons that create more confusion.

    As NNG points out, there’s a difference between an icon being recognizable and its meaning being indisputable.

    So, one way you can get around this is to make the outward appearance of the menu icon-only. But upon hover, the labels appear so that users have additional context for what each means.

    As for any secondary navigation you might need — including a Settings navigation — you can write out the labels since it will only appear upon user activation.

    Google Hangouts secondary navigation design - icons and labels
    The Google Hangouts secondary navigation uses an icon and label for each tab. (Source: Google Hangouts) (Large preview)

    Although some of the icons would be easy enough to identify, not all of them would instantly be recognizable (like “Invites” and “Hangouts Dialer”). If even one tab in your secondary navigation is rarely seen across other apps, spell them all out.

    One last thing: The divider lines in this menu are a great choice. Rather than jam 10 tabs/options into this navigation bar together, they’re logically grouped, making it easier for users to find what they’re looking for.

    3. Provide Users with Predictive Search Functionality

    Every app should have a search bar. It might be there to help users sift through content, to find the contact they’re looking for from a long list, or to ask a question about something in the app.

    The more complex your app is, the more critical a role internal search is going to play. But if you want to improve your users’ search experience even more, you’ll want to power yours with predictive search functionality.

    Even though I’m sure you have a Support line, maybe a chatbot and perhaps an FAQs or Knowledgebase to help users find what they need, a smart search bar can connect them to what they’re really looking for (even if they don’t know how to articulate it).

    Google has this search functionality baked into most of its products.

    You’re familiar with autocomplete within the Google search engine itself. But here are some other use cases for smart search capabilities.

    Google Drive connects users to documents (of all types — Docs, Sheets, Slides and more) as well as collaborators that match the search query.

    Google Drive search for 'speed'
    An example search for ‘speed’ within Google Drive. (Source: Google Drive) (Large preview)

    Users can, of course, be taken to a full search results page. However, the search bar itself predicts which content is the most relevant for the query. In this case, these are the most recent pieces of content I’ve written that include the term “speed” in the title.

    Google Maps is a neat use case as it pulls data from a variety of connected (Google) sources to try and predict what its users are looking for.

    Google Maps predictive search example 'Alicia'
    Google Maps pulls from a variety of sources to predict where users want to travel to. (Source: Google Maps) (Large preview)

    In this example, I typed in “Alicia”. Now, Google Maps knows me pretty well, so the first result is actually the address of one of my contacts. The remaining results are for addresses or businesses within a 45-mile radius containing the word “Alicia”.

    It doesn’t just pull from there though. This is one of those cases where the more enjoyable you make the in-app experience, the more your users will engage with it — which means more data.

    For example, this is what I see when I search for “Three”:

    Google Maps displays a 'Favorite' location when a user searches for 'three'
    Google Maps will provide ‘Favorite’ locations in search results when relevant. (Source: Google Maps) (Large preview)

    The very first thing it pulls up is a restaurant called Three Sisters (which is a fantastic restaurant in the city of Providence, by the way). If you look just above the center of the map where the red heart is, that’s the restaurant. This means that I’ve added it to my Favorite places and Google Maps actually calls it out as such in my search results.

    Imagine how much more your users would love your app if it wasn’t always a struggle to get to the content, data or page they were looking for. Or to perform a desired action. When you give your users the ability to personalize their experience like this, use the information they’ve given you to improve their search experience, too.

    4. Enable Users to Change the Design and Layout of the App

    As a designer, you can do your best to design a great experience for your users. But let’s face it:

    You’re never going to please everyone.

    Unlike a website, though, which is pretty much what-you-see-is-what-you-get, SaaS users have the ability to change the design and layout of what they’re interacting with — if you let them. And you should.

    There are many different ways this might apply to the app you’ve built.

    Google Calendar, for example, has a ton of customization options available.

    Google Calendar - view customizations
    Google Calendar allows users to customize the look and view of their calendars. (Source: Google Calendar) (Large preview)

    On the far left is a list of “My calendars”. Users can click which calendars and associated events they want to see within the app.

    In the bottom-right corner is an arrowhead. This enables users to hide the Google apps side panel and give them more room to focus on upcoming events and appointments.

    In the top-right, users have two places where they can customize their calendar:

    • The Settings bar allows them to adjust the color and density of the calendar.
    • The “Month” dropdown allows them to adjust how much of the calendar is seen at once.

    These customizations would all be useful for any sort of project management, planning or appointment scheduling app.

    For other apps, I’d recommend looking at Gmail. It’s chock full of customizations that you could adapt for your app.

    Previously, if users clicked the Settings widget, it would move them out of the app and into the dedicated settings panel. To be honest, it was annoying, especially if you just wanted to make a small tweak.

    Gmail Settings panel - design and layout customization options
    Gmail’s Settings reveals a list of design and layout customization options. (Source: Gmail) (Large preview)

    Now, the Settings button opens this panel within Gmail. It enables users to adjust things like:

    • Line spacing,
    • Background theme,
    • Inbox sorting priorities,
    • Reading pane layout,
    • Conversation view on/off.

    This is a recent update to Gmail’s settings, which probably means these are the most commonly used design customizations its users actually use.

    For any customizations users want to make that they can’t find in this new panel, they can click “See all settings” and customize the in-app design and layout (among other things) even further.

    Other customizations you might find value in enabling in your app are:

    • Keyboard control,
    • Dark mode,
    • Color-blind mode,
    • Text resizing,
    • List/grid view toggling,
    • Widget and banner hiding,
    • Columns displayed.

    Not only do these design and layout controls enable users to create an interface they enjoy looking at and that works better for their purposes, it can also help with accessibility.

    Wrapping Up

    There’s a reason why Google dominates market share with many of its products. It gets the user experience. Of course, this is due largely to the fact that it has access to more user data than most companies.

    And while we should be designing solutions for our specific audiences, there’s no denying that Google’s products can help us set a really strong base for any audience — if we just pay attention to the trends across its platforms.

    Further Reading on SmashingMag:

    Smashing Editorial
    (ra, yk, il)

    Source link

    web design

    The Renaissance Of No-Code For Web Designers — Smashing Magazine

    07/30/2020

    About The Author

    Product designer @ Wix • Coder • Running shoes addict
    More about
    Uri

    Just like during the Renaissance, we’re living in times of incredible cultural and artistic innovation. As the Internet evolves, browsers align, capabilities are added and accessibility of technology becomes easier, designers face new opportunities to create, think, and change their status with no-code tools.

    The word Renaissance — which means “rebirth” in French — was given to a tremendous period of philosophical and artistic achievements that began in the 14th century.

    During this time, there were a wide range of developments, including:

    • Use of oil paints, rather than tempera, which made the painting process easier.
    • Use of fabric, rather than wooden boards, which reduced the expenses of painting.
    • Translation of classical texts in architecture, anatomy, philosophy, and more, making knowledge more accessible to the general public.

    These developments and more made the Renaissance one of the most productive artistic eras in history, dramatically reducing the creative barrier and attracting a large audience rather than just a small group of elites.

    Block of stone
    ‘Every block of stone has a statue inside it, and it is the task of the sculptor to discover it.’ — Michelangelo. Some people see a block of stone, while other people see a source of creation. The tools available to us at any given time can bring out our maximum potential. (Large preview)

    Just like the Renaissance era, today’s web design field is exploring its potential through no-code development platforms (NCDPs). These tools allow non-programmers to create application software through graphical user interfaces and configuration, instead of traditional computer programming.

    The Designer/Developer Mental Model

    A realistic collage featuring a 3D sculpture holding lightning in his left hand and light bulbs his right hand
    Taken from ‘The Singularity Is Here: Human 2.0‘ by Amit Maman. Part of his final project at Shenkar College of Engineering and Design, Maman created this triptych to show his vision of the singularity and the turning point in human history that it represents. His work is inspired by principles from the Renaissance era. (Large preview)

    In 2000, usability expert Jakob Nielsen introduced “Jakob’s Law,” the idea that users develop mental models of the products they interact with based on their previous experience. The more users can focus on their goal without challenging this mental model, the easier it is for them to achieve that goal.

    “CSS is closer to painting than Python.”
    — Chris Coyier, co-founder at CodePen

    Design and development skills are rooted in different types of thinking and require different types of tools. While designers use WYSIWYG editors like Figma, Sketch, and Photoshop to place elements on the canvas, developers work with IDEs like VSCode, Webstorm, and Brackets. In order to remain productive, designers and developers need to be able to make changes and receive instant feedback, according to their mental model.

    So, using drag and drop builders may actually interfere with developers who want to debug fast, but working only with a text editor may be inappropriate for designers who want to test composition.

    Designers And Code

    Many designers understand the functional differences between a mockup and a working product. In order to understand the possibilities of the medium, where to draw the boundaries and how to deal with the constraints, many designers are willing to “get their hands dirty” when it comes to learning code — but they have difficulties.

    One of the main reasons designers are not coders is because there is a large gap between the designer’s mental model and the conceptual model of many code editors. Design and development take two very different modes of thought. This mismatch leads to a difficult and frustrating learning curve for designers that they might not be able to overcome.

    Code Abstraction

    A realistic collage featuring a 3D sculpture smashing water
    (Large preview)

    Abstraction is a core concept of computer science. Languages, frameworks, and libraries are built on different abstraction layers of complexity to facilitate, optimize, and guarantee productivity.

    “Visual programming tools abstract code away from the creator, making them significantly more accessible. The real magic of these tools, however, is how they integrate all of the underlying layers of software into end products, providing useful functionality through modular components that can be harnessed through intuitive visual interfaces.”
    — Jeremy Q. Ho, No Code is New Programming

    When working with abstraction layers, there are tools such as Editor X and Studio for websites/web applications, Draftbit and Kodika for mobile apps, and Modulz for design systems, which enable a visual representation of code, in addition to code capabilities.

    By adopting a familiar visual medium, the learning curve becomes easier for designers.

    If Chris Wanstrath the co-founder and former CEO of GitHub said, “the future of coding is no coding at all,” then surely no-code is a legitimate way to develop — despite the perception that these tools don’t offer the flexibility to write your own code, line by line.

    Indeed, we see that interest in the term “nocode” is growing:

    A screenshot of Google Trends
    Search for the term ‘nocode’ in the last 5 years on Google Trends. (Large preview)

    Difference Between Imperative And Declarative Programming

    In order to understand the development of no-code tools for designers, you need to know the distinction between two types of programming:

    1. Imperative Programming
      Deconstruct the result into a sequence of imperatives, i.e. explicit control flow. For example: JavaScript, Python, C ++.
    2. Declarative Programming
      Declare the result, i.e. implicit control flow. For example: SQL, HTML, CSS.

    Declarative languages are often domain-specific languages, or DSL, which means they’re used for a specific purpose, in a specific domain.

    For example, SQL is DSL for working with databases, HTML is DSL for adding semantic structure and meaning to content on a web page, and CSS is DSL for adding style.

    “There are too many variables to consider. The point of CSS is to make it so you don’t have to worry about them all. Define some constraints. Let the language work out the details.”
    — Keith J. Grant, Resilient, Declarative, Contextual

    Imperative programming sets specific, step-by-step instructions to the browser to get the desired result, while declarative programming states the desired result and the browser does the work by itself.

    The Middle Ages

    The effort to create a visual interface tool for web design development started in the 1990s through groundbreaking attempts like InContext Spider, Netscape Navigator Gold, Microsoft FrontPage, and of course, Dreamweaver.

    A screenshot of Dreamweaver MX
    Dreamweaver MX, Foundation Dreamweaver MX. (Large preview)

    During this period, the common terminology included: visual HTML authoring tool, WYSIWYG web page compositor, or simply HTML editor. The term “no-code” was popular in the 1990s — but for a different reason. In 1996, the American rock band Pearl Jam released their fourth studio album, No Code.

    These no-code tools dramatically reduced the creative barrier and attracted a large audience, the Internet wasn’t ready for these types of tools at the time.

    This effort was limited for the following reasons:

    1. Layout

    When the inventor of the World Wide Web Tim Berners-Lee launched his creation in 1989, he didn’t offer a way to design a website.

    This came along in October 1994, after a series of suggestions on how to design the Internet by different people — including one from Håkon Wium Lie — who proposed an idea that attracted everyone’s attention. Lie believed in a declarative style that would allow browsers to handle the processing — it was called Cascading Style Sheets, or simply CSS.

    “CSS stood out because it was simple, especially compared to some of its earliest competitors.”
    — Jason Hoffman, A Look Back at the History of CSS

    For a long time after, CSS provided design solutions for a single object — but it didn’t give an adequate response to the relationship between the objects.

    Methods to address this were effectively hacks, and they weren’t able to handle a great deal of complexity. As sites evolved from simple documents to complex applications, web layouts became difficult to assemble. Instead of using a style in a declarative way as Lie designed, web developers were forced to use imperative programming.

    A grid system based on the rules of Swiss designer Josef Müller-Brockmann that was customary in print from the 1940s seems like a distant dream when considering anything related to the Web.

    Three posters by Josef Muller-Brockmann
    Posters by Josef Muller-Brockmann. (Large preview)

    Because of these layout limitations, no-code platforms were forced to add an abstract layer to perform backstage calculations. This layer causes a range of problems, including losing the semantic value of the objects, performance issues, bulky code, a complex learning curve, unscalability, and accessibility issues.

    2. Browser Alignment

    In the early days, browser makers were the ones who decided how to build the Internet. This led to the Web becoming a manipulative commodity. Competition between browsers led to unique “design features”. This forced the need to rebuild the same site several times, so it could be accessed from multiple browsers.

    “Developers in the 90s would often have to make three or four versions of every website they built, so that it would be compatible with each of the browsers available at the time.”
    — Amy Dickens, Web Standards: The What, The Why, And The How

    To offset the need to build websites that fit specific browsers, the World Wide Web Consortium (WC3) community was established at MIT in 1994. The WC3 is an international community working to develop functional, accessible and cross-compatible web standards.

    When the standards were introduced, browser makers were encouraged to stick to one way of doing things — thus preventing several versions of the same site from being built. Despite WC3’s recommendations, it took a long time for browsers to meet the same standards.

    Due to a lack of alignment between the browsers (Internet Explorer, I’m looking at you), CSS for a time was stuck and no new capabilities were added. Once a declarative language doesn’t support something, it requires you to lean on all kinds of imperative hacks in order to achieve that goal.

    3. Data Binding

    In the early years of the Web, sites were developed as a collection of static pages with no semantic meaning. When Web 2.0 arrived, it received the description “the web as a platform,” which led to a significant change — pages had dynamic content, which affected the connection to the data, and of course the semantic meaning.

    “Sites in the 1990s were usually either brochure-ware (static HTML pages with insipid content) or they were interactive in a flashy, animated, JavaScript kind of way.”
    — Joshua Porter, Web 2.0 for Designers

    Indeed, connecting to data using a no-code approach has existed for a long time — but the user experience was difficult. Additionally, the transition to semantic marking so content could be detected in no-code tools was difficult because of the mixing between declarative and imperative programming.

    No-code tools didn’t mesh with those core tasks.

    A realistic collage featuring a 3D holding Old TV with glitch screen
    (Large preview)

    Proto-Renaissance

    On June 29, 2007, the nature of the Internet was changed dramatically. This was the day when Steve Jobs introduced the iPhone — a combination of mobile phone and media player that connected to the Internet and enabled multi-touch navigation.

    When the iPhone was introduced in 2007, it was a turning point for web design. All of a sudden web designers lost control of the canvas on which we designed websites. Previously, websites only had to work on monitor screens, which varied in size, but not all that much. How were we supposed to make our websites work on these tiny little screens?
    — Clarissa Peterson, Learning Responsive Web Design

    This created new challenges for web design development. Mainly, how to build a site that can be used on multiple types of devices. Many “hack” approaches to layout design simply fell apart — they caused more problems than they solved.

    Everything needed to be reevaluated.

    The No-Code Renaissance

    A pair of statues floating in the air as they hug each other
    (Large preview)

    Browsers supporting WC3 standards (Chrome and Firefox ) have huge market share today, which has pushed more browsers to support the standards. The fact that all of the browsers support the same standard, enable alignment in the building of sites and ensure these capabilities would continue to work as standards and browsers evolve.

    Methods such as media query, flexbox and grid — which are natively available in the browsers for layout design — have paved the way for flexible layouts, even when element sizes are dynamic.

    “When CSS Grid shipped in March 2017, our toolbox reached a tipping point. At last we have technology powerful enough to let us really get creative with layout. We can use the power of graphic design to convey meaning through our use of layout—creating unique layouts for each project, each section, each type of content, each page.”
    — Rachel Andrew, The New CSS Layout

    In this way, HTML became cleaner and it was able to achieve its original purpose: a semantic description of the content.

    Finally, thanks to alignment between the browsers and new capabilities, no-code tools are backed by powerful, uniform technology. These changes created a clearer distinction between declarative and imperative. New possibilities were created to solve old problems.

    “Simplicity is the ultimate sophistication.”
    — Leonardo da Vinci

    The Effect Of No-code On Designers

    A screenshot of Editor X in edit mode
    Editor X | David’s photo by Igor Ferreira on Unsplash. (Large preview)

    The developments of the Internet over the years has led to a situation where the abstraction between design and code is constantly improving. This has implications for the way web designers plan and implement their designs.

    1. Design Planning

    While popular design tools use static content for dynamic web design, no-code tools allow designers to work with the web’s own materials.

    “Photoshop is the most effective way to show your clients what their website will never look like.”
    — Stephen Hay, author of Responsive Design Workflow

    If we have a complex design with different states, micro-interactions, animations and responsive breakpoints — by using no-code tools we can work in a more tangible way.

    Additionally, the development of the web enables no-code tools to clearly separate content from the design (which allows designers to visually manage real content). Reflecting the dynamic content in the design (e.g. text, images, videos, and audio), gives designers a clearer understanding of how it will appear.

    The advantage of working in the no-code workspace is that interactions appear immediately. This allows designers to quickly test their design choices and see if they work.

    2. Design Implementation

    After investing in design perfection, designers should explain the visual and conceptual decisions to developers through prototypes. Prototypes not only take time in terms of preparation, but their design is also often implemented incorrectly due to misinterpretations.

    With no-code tools, designers are able to place objects on their display and handle their visibility and behavior with ease and speed. In other words, they can design the end result without depending on anyone else.

    To use myself as an example, when the Coronavirus pandemic hit, I worked with a small team on a project to help connect young volunteers to isolated seniors. In just three days, myself and another designer built the website and connected user registration data to a database, while the team’s developer worked to integrate data from the site into a separate mobile app.

    The Effect Of No-code On Developers

    Will no-code tools completely replace developers? The short answer: No. The significant change is in the way designers and developers can work together to create websites.

    In addition to the development of CSS, Javascript has also evolved in parallel and perhaps even more. The idea that frontend developers need to control all the abilities makes no sense. And yet, the development of no-code over the years has enabled designers to build their own designs.

    It’s a win-win situation, in which  developers can focus on developing logic, and designers have more control over the user experience and styling.

    The Effort Is Not Yet Complete

    I don’t want to leave you with the impression that designers have complete freedom to design with no-code tools. There are still some missing style capabilities that CSS has not yet solved, and these still require imperative development.

    Unlike in the Middle Ages, where art was considered as handicraft without a theoretical basis, Renaissance developments changed the status of the artist — who was suddenly considered a polymath.

    No-code tools remove bottlenecks, which allows designers to gain more ownership, influence, and control over the experiences they design.

    We’ve come a long way from the days when designers weren’t able to bring their designs to life. As the Internet evolves, browsers align, capabilities are added and the accessibility of technology becomes easier — designers are faced with new opportunities to create, think, and change their status with no-code tools.

    The no-code movement not only affects how things are done, but by who.

    Credits: Yoav Avrahami and Jeremy Hoover contributed to this article.

    Further Reading on SmashingMag:

    Smashing Editorial
    (fb, ra, yk, il)

    Source link

    web design

    The Renaissance Of No-Code For Web Designers — Smashing Magazine

    07/30/2020

    About The Author

    Product designer @ Wix • Coder • Running shoes addict
    More about
    Uri

    Just like during the Renaissance, we’re living in times of incredible cultural and artistic innovation. As the Internet evolves, browsers align, capabilities are added and accessibility of technology becomes easier, designers face new opportunities to create, think, and change their status with no-code tools.

    The word Renaissance — which means “rebirth” in French — was given to a tremendous period of philosophical and artistic achievements that began in the 14th century.

    During this time, there were a wide range of developments, including:

    • Use of oil paints, rather than tempera, which made the painting process easier.
    • Use of fabric, rather than wooden boards, which reduced the expenses of painting.
    • Translation of classical texts in architecture, anatomy, philosophy, and more, making knowledge more accessible to the general public.

    These developments and more made the Renaissance one of the most productive artistic eras in history, dramatically reducing the creative barrier and attracting a large audience rather than just a small group of elites.

    Block of stone
    ‘Every block of stone has a statue inside it, and it is the task of the sculptor to discover it.’ — Michelangelo. Some people see a block of stone, while other people see a source of creation. The tools available to us at any given time can bring out our maximum potential. (Large preview)

    Just like the Renaissance era, today’s web design field is exploring its potential through no-code development platforms (NCDPs). These tools allow non-programmers to create application software through graphical user interfaces and configuration, instead of traditional computer programming.

    The Designer/Developer Mental Model

    A realistic collage featuring a 3D sculpture holding lightning in his left hand and light bulbs his right hand
    Taken from ‘The Singularity Is Here: Human 2.0‘ by Amit Maman. Part of his final project at Shenkar College of Engineering and Design, Maman created this triptych to show his vision of the singularity and the turning point in human history that it represents. His work is inspired by principles from the Renaissance era. (Large preview)

    In 2000, usability expert Jakob Nielsen introduced “Jakob’s Law,” the idea that users develop mental models of the products they interact with based on their previous experience. The more users can focus on their goal without challenging this mental model, the easier it is for them to achieve that goal.

    “CSS is closer to painting than Python.”
    — Chris Coyier, co-founder at CodePen

    Design and development skills are rooted in different types of thinking and require different types of tools. While designers use WYSIWYG editors like Figma, Sketch, and Photoshop to place elements on the canvas, developers work with IDEs like VSCode, Webstorm, and Brackets. In order to remain productive, designers and developers need to be able to make changes and receive instant feedback, according to their mental model.

    So, using drag and drop builders may actually interfere with developers who want to debug fast, but working only with a text editor may be inappropriate for designers who want to test composition.

    Designers And Code

    Many designers understand the functional differences between a mockup and a working product. In order to understand the possibilities of the medium, where to draw the boundaries and how to deal with the constraints, many designers are willing to “get their hands dirty” when it comes to learning code — but they have difficulties.

    One of the main reasons designers are not coders is because there is a large gap between the designer’s mental model and the conceptual model of many code editors. Design and development take two very different modes of thought. This mismatch leads to a difficult and frustrating learning curve for designers that they might not be able to overcome.

    Code Abstraction

    A realistic collage featuring a 3D sculpture smashing water
    (Large preview)

    Abstraction is a core concept of computer science. Languages, frameworks, and libraries are built on different abstraction layers of complexity to facilitate, optimize, and guarantee productivity.

    “Visual programming tools abstract code away from the creator, making them significantly more accessible. The real magic of these tools, however, is how they integrate all of the underlying layers of software into end products, providing useful functionality through modular components that can be harnessed through intuitive visual interfaces.”
    — Jeremy Q. Ho, No Code is New Programming

    When working with abstraction layers, there are tools such as Editor X and Studio for websites/web applications, Draftbit and Kodika for mobile apps, and Modulz for design systems, which enable a visual representation of code, in addition to code capabilities.

    By adopting a familiar visual medium, the learning curve becomes easier for designers.

    If Chris Wanstrath the co-founder and former CEO of GitHub said, “the future of coding is no coding at all,” then surely no-code is a legitimate way to develop — despite the perception that these tools don’t offer the flexibility to write your own code, line by line.

    Indeed, we see that interest in the term “nocode” is growing:

    A screenshot of Google Trends
    Search for the term ‘nocode’ in the last 5 years on Google Trends. (Large preview)

    Difference Between Imperative And Declarative Programming

    In order to understand the development of no-code tools for designers, you need to know the distinction between two types of programming:

    1. Imperative Programming
      Deconstruct the result into a sequence of imperatives, i.e. explicit control flow. For example: JavaScript, Python, C ++.
    2. Declarative Programming
      Declare the result, i.e. implicit control flow. For example: SQL, HTML, CSS.

    Declarative languages are often domain-specific languages, or DSL, which means they’re used for a specific purpose, in a specific domain.

    For example, SQL is DSL for working with databases, HTML is DSL for adding semantic structure and meaning to content on a web page, and CSS is DSL for adding style.

    “There are too many variables to consider. The point of CSS is to make it so you don’t have to worry about them all. Define some constraints. Let the language work out the details.”
    — Keith J. Grant, Resilient, Declarative, Contextual

    Imperative programming sets specific, step-by-step instructions to the browser to get the desired result, while declarative programming states the desired result and the browser does the work by itself.

    The Middle Ages

    The effort to create a visual interface tool for web design development started in the 1990s through groundbreaking attempts like InContext Spider, Netscape Navigator Gold, Microsoft FrontPage, and of course, Dreamweaver.

    A screenshot of Dreamweaver MX
    Dreamweaver MX, Foundation Dreamweaver MX. (Large preview)

    During this period, the common terminology included: visual HTML authoring tool, WYSIWYG web page compositor, or simply HTML editor. The term “no-code” was popular in the 1990s — but for a different reason. In 1996, the American rock band Pearl Jam released their fourth studio album, No Code.

    These no-code tools dramatically reduced the creative barrier and attracted a large audience, the Internet wasn’t ready for these types of tools at the time.

    This effort was limited for the following reasons:

    1. Layout

    When the inventor of the World Wide Web Tim Berners-Lee launched his creation in 1989, he didn’t offer a way to design a website.

    This came along in October 1994, after a series of suggestions on how to design the Internet by different people — including one from Håkon Wium Lie — who proposed an idea that attracted everyone’s attention. Lie believed in a declarative style that would allow browsers to handle the processing — it was called Cascading Style Sheets, or simply CSS.

    “CSS stood out because it was simple, especially compared to some of its earliest competitors.”
    — Jason Hoffman, A Look Back at the History of CSS

    For a long time after, CSS provided design solutions for a single object — but it didn’t give an adequate response to the relationship between the objects.

    Methods to address this were effectively hacks, and they weren’t able to handle a great deal of complexity. As sites evolved from simple documents to complex applications, web layouts became difficult to assemble. Instead of using a style in a declarative way as Lie designed, web developers were forced to use imperative programming.

    A grid system based on the rules of Swiss designer Josef Müller-Brockmann that was customary in print from the 1940s seems like a distant dream when considering anything related to the Web.

    Three posters by Josef Muller-Brockmann
    Posters by Josef Muller-Brockmann. (Large preview)

    Because of these layout limitations, no-code platforms were forced to add an abstract layer to perform backstage calculations. This layer causes a range of problems, including losing the semantic value of the objects, performance issues, bulky code, a complex learning curve, unscalability, and accessibility issues.

    2. Browser Alignment

    In the early days, browser makers were the ones who decided how to build the Internet. This led to the Web becoming a manipulative commodity. Competition between browsers led to unique “design features”. This forced the need to rebuild the same site several times, so it could be accessed from multiple browsers.

    “Developers in the 90s would often have to make three or four versions of every website they built, so that it would be compatible with each of the browsers available at the time.”
    — Amy Dickens, Web Standards: The What, The Why, And The How

    To offset the need to build websites that fit specific browsers, the World Wide Web Consortium (WC3) community was established at MIT in 1994. The WC3 is an international community working to develop functional, accessible and cross-compatible web standards.

    When the standards were introduced, browser makers were encouraged to stick to one way of doing things — thus preventing several versions of the same site from being built. Despite WC3’s recommendations, it took a long time for browsers to meet the same standards.

    Due to a lack of alignment between the browsers (Internet Explorer, I’m looking at you), CSS for a time was stuck and no new capabilities were added. Once a declarative language doesn’t support something, it requires you to lean on all kinds of imperative hacks in order to achieve that goal.

    3. Data Binding

    In the early years of the Web, sites were developed as a collection of static pages with no semantic meaning. When Web 2.0 arrived, it received the description “the web as a platform,” which led to a significant change — pages had dynamic content, which affected the connection to the data, and of course the semantic meaning.

    “Sites in the 1990s were usually either brochure-ware (static HTML pages with insipid content) or they were interactive in a flashy, animated, JavaScript kind of way.”
    — Joshua Porter, Web 2.0 for Designers

    Indeed, connecting to data using a no-code approach has existed for a long time — but the user experience was difficult. Additionally, the transition to semantic marking so content could be detected in no-code tools was difficult because of the mixing between declarative and imperative programming.

    No-code tools didn’t mesh with those core tasks.

    A realistic collage featuring a 3D holding Old TV with glitch screen
    (Large preview)

    Proto-Renaissance

    On June 29, 2007, the nature of the Internet was changed dramatically. This was the day when Steve Jobs introduced the iPhone — a combination of mobile phone and media player that connected to the Internet and enabled multi-touch navigation.

    When the iPhone was introduced in 2007, it was a turning point for web design. All of a sudden web designers lost control of the canvas on which we designed websites. Previously, websites only had to work on monitor screens, which varied in size, but not all that much. How were we supposed to make our websites work on these tiny little screens?
    — Clarissa Peterson, Learning Responsive Web Design

    This created new challenges for web design development. Mainly, how to build a site that can be used on multiple types of devices. Many “hack” approaches to layout design simply fell apart — they caused more problems than they solved.

    Everything needed to be reevaluated.

    The No-Code Renaissance

    A pair of statues floating in the air as they hug each other
    (Large preview)

    Browsers supporting WC3 standards (Chrome and Firefox ) have huge market share today, which has pushed more browsers to support the standards. The fact that all of the browsers support the same standard, enable alignment in the building of sites and ensure these capabilities would continue to work as standards and browsers evolve.

    Methods such as media query, flexbox and grid — which are natively available in the browsers for layout design — have paved the way for flexible layouts, even when element sizes are dynamic.

    “When CSS Grid shipped in March 2017, our toolbox reached a tipping point. At last we have technology powerful enough to let us really get creative with layout. We can use the power of graphic design to convey meaning through our use of layout—creating unique layouts for each project, each section, each type of content, each page.”
    — Rachel Andrew, The New CSS Layout

    In this way, HTML became cleaner and it was able to achieve its original purpose: a semantic description of the content.

    Finally, thanks to alignment between the browsers and new capabilities, no-code tools are backed by powerful, uniform technology. These changes created a clearer distinction between declarative and imperative. New possibilities were created to solve old problems.

    “Simplicity is the ultimate sophistication.”
    — Leonardo da Vinci

    The Effect Of No-code On Designers

    A screenshot of Editor X in edit mode
    Editor X | David’s photo by Igor Ferreira on Unsplash. (Large preview)

    The developments of the Internet over the years has led to a situation where the abstraction between design and code is constantly improving. This has implications for the way web designers plan and implement their designs.

    1. Design Planning

    While popular design tools use static content for dynamic web design, no-code tools allow designers to work with the web’s own materials.

    “Photoshop is the most effective way to show your clients what their website will never look like.”
    — Stephen Hay, author of Responsive Design Workflow

    If we have a complex design with different states, micro-interactions, animations and responsive breakpoints — by using no-code tools we can work in a more tangible way.

    Additionally, the development of the web enables no-code tools to clearly separate content from the design (which allows designers to visually manage real content). Reflecting the dynamic content in the design (e.g. text, images, videos, and audio), gives designers a clearer understanding of how it will appear.

    The advantage of working in the no-code workspace is that interactions appear immediately. This allows designers to quickly test their design choices and see if they work.

    2. Design Implementation

    After investing in design perfection, designers should explain the visual and conceptual decisions to developers through prototypes. Prototypes not only take time in terms of preparation, but their design is also often implemented incorrectly due to misinterpretations.

    With no-code tools, designers are able to place objects on their display and handle their visibility and behavior with ease and speed. In other words, they can design the end result without depending on anyone else.

    To use myself as an example, when the Coronavirus pandemic hit, I worked with a small team on a project to help connect young volunteers to isolated seniors. In just three days, myself and another designer built the website and connected user registration data to a database, while the team’s developer worked to integrate data from the site into a separate mobile app.

    The Effect Of No-code On Developers

    Will no-code tools completely replace developers? The short answer: No. The significant change is in the way designers and developers can work together to create websites.

    In addition to the development of CSS, Javascript has also evolved in parallel and perhaps even more. The idea that frontend developers need to control all the abilities makes no sense. And yet, the development of no-code over the years has enabled designers to build their own designs.

    It’s a win-win situation, in which  developers can focus on developing logic, and designers have more control over the user experience and styling.

    The Effort Is Not Yet Complete

    I don’t want to leave you with the impression that designers have complete freedom to design with no-code tools. There are still some missing style capabilities that CSS has not yet solved, and these still require imperative development.

    Unlike in the Middle Ages, where art was considered as handicraft without a theoretical basis, Renaissance developments changed the status of the artist — who was suddenly considered a polymath.

    No-code tools remove bottlenecks, which allows designers to gain more ownership, influence, and control over the experiences they design.

    We’ve come a long way from the days when designers weren’t able to bring their designs to life. As the Internet evolves, browsers align, capabilities are added and the accessibility of technology becomes easier — designers are faced with new opportunities to create, think, and change their status with no-code tools.

    The no-code movement not only affects how things are done, but by who.

    Credits: Yoav Avrahami and Jeremy Hoover contributed to this article.

    Further Reading on SmashingMag:

    Smashing Editorial
    (fb, ra, yk, il)

    Source link

    web design

    Are Modern Best Practices Bad For The Web? — Smashing Magazine

    07/28/2020

    We’re asking if modern best practices are bad for the web? Are modern frameworks taking us down the wrong path? Drew McLellan speaks to Lean Web expert Chris Ferdinandi to find out.

    Today, we’re asking if modern best practices are bad for the web? Are modern frameworks taking us down the wrong path? I speak to Lean Web expert Chris Ferdinandi to find out.

    Show Notes

    Weekly Update

    Transcript

    Photo of Chris FerdinandiDrew McLellan: He’s the author of Vanilla JS Pocket Guide Series, creator of the Vanilla JS Academy Training Program, and host of the Vanilla JS Podcast. He’s developed a Tips newsletter, it’s read by nearly 10,000 developers each weekday. He’s taught developers at organizations like Chobani and The Boston Globe. And his JavaScript plugins have been used by organizations like Apple and Harvard Business School. Most of all, he loves to help people learn Vanilla JavaScript. So we know he’d rather pick Vanilla JavaScript over a framework, but did you know he was once picked out in a police lineup as being the person least likely to have committed the crime? My Smashing friends, please welcome Chris Ferdinandi. Hello, Chris. How are you?

    Chris Ferdinandi: Oh, I’m smashing. Thanks for having me.

    Drew: I wanted to talk to you today about this concept of a Lean Web, which something of a passion for you, isn’t it?

    Chris: Yes, very much so.

    Drew: Why don’t you set the scene for us? When we talk about a Lean Web, what is the problem we are trying to solve?

    Chris: Yeah, great question. Just as a caveat for all the listeners, this episode might get a little old man yells at cloud. I’m going to try to avoid that. When I look at the way we build for the web today, it feels a little bit like a bloated over-engineered mess. I’ve come to believe that a lot of what we think of as best practices today might actually be making the web worse.

    Chris: The Lean Web is an approach to web development that is focused on simplicity, on performance, and the developer experience over… I’m sorry, not the developer experience. The user experience rather, over the developer experience, and the ease of building things from a team perspective, which is what I think where we put a lot of focus today and as we’ll probably get into in our conversation.

    Chris: I’ve actually come to find that a lot of these things we think of as improving the developer experience do so for a subset of developers, but not necessarily everybody who’s working on the thing you’re building. So there’s a whole bunch of issues with that too, that we can dig into. But really, the Lean Web is about focusing on simplicity and performance for the user and really prioritizing or putting the focus on the people who use the things we make rather than us, the people who are making it.

    Drew: As the web matures as a development platform, there seems to be this ever increasing drive towards specialization.

    Chris: Yes.

    Drew: People who used to cover Full Stack, and then we split into front-end and back-end. And then that front-end split into people who do CSS or JavaScript development. And then increasingly within JavaScript, it becomes more specialized. Somebody might consider themselves and market themselves as a React developer or an Angular developer, and their entire identity and outlook is based around a particular framework that they are highly skilled in. Is this dependency on frameworks, the core of our work on the web, a bad thing?

    Chris: It’s nuanced. I used to be very strongly in the yes, always camp. I think broadly, I still feel like yes, our obsession as an industry with frameworks and tools in general really, is potentially a little bit to our detriment. I don’t think frameworks are inherently bad. I think they’re useful for a very narrow subset of use cases. And we end up using them for almost everything, including lots of situations where they’re really not necessarily the best choice for you or for the project.

    Chris: When I think about a lot of the issues that we have on the web today, the core of those issues really starts with our over-reliance on frameworks. Everything else that comes after that is in many ways, because we throw so much not just frameworks which is JavaScript in general, at the web. I say that as someone who professionally teaches people how to write and use JavaScript. That’s how I make my money. And I’m here saying that I think we use too much JavaScript, which is sometimes a little bit of an odd thing.

    Drew: In the time before the big frameworks sprouted up, we used to build user interfaces and things with jQuery or whatever. And then frameworks came along and they gave us more of this concept of a state-based UI.

    Chris: Yes.

    Drew: Now, that’s a fairly complex bit of engineering that you’re required to get in place. Does working with less JavaScript exclude using something like that, or do you have to re-implement it yourself? Are you just creating a loaded boilerplate?

    Chris: A lot of it depends on what you’re doing. If you have a non-changing interface, you can build a state-based UI with… I don’t know, maybe a dozen or so lines of code. If you have a non-changing interface, I would honestly probably say state-based UI. It’s not necessarily the right approach. There’s probably other things you can do instead. Think of static site generators, some pre-rendered markup, even an old-school WordPress or PHP driven site.

    Chris: But where this starts to get interesting is when you get into more dynamic and interactive interfaces. Not just apps. I know people love to draw this line between websites and apps, and I think there’s this weird blend between the two of them and the line is not always as clear. When you start to get into more the user does stuff, something changes. State-based UI becomes a little bit more important. But you still don’t need tons of code to make that happen.

    Chris: I look at something like React or Vue, which are absolutely amazing pieces of engineering. I don’t want to take away from the people who work on those. I ended up as a learning exercise, building my own mini-framework just to get a better sense for how these things work under the hood. It is really hard to account for all of the different moving pieces. So I have tremendous respect for the people who build and work on these tools. But React and Vue are both about 30 kilobytes after minifying and gzipping. So once you unpack them, they’re substantially bigger than that.

    Chris: Not all of it, but a good chunk of that weight is devoted to this thing called the virtual DOM. There are alternatives that use similar APIs or approaches. For React, you have Preact, which is 2.5 kilobytes or about 3 kilobytes instead of 30. It’s a tenth of the size. For Vue, you have Alpine JS instead, which is about 7 kilobytes. Still, substantially smaller. The big difference between those and their big brother counterparts, is that they’ve shed the virtual DOM. They may drop a method or two. But generally, it’s the same approach and the same kind of API in the way of working with code, and they’re substantially smaller.

    Chris: I think a lot of the tools we use are potentially overpowered for the things we’re trying to do. If you need a state-based UI and you need reactive data and these dynamic interfaces, that’s great. I think one of the big things I try and talk about today is not… never use tools. For me, Vanilla JS is not you’re handwriting every single line of code and every single project you do. That’s madness. I couldn’t do that, I don’t do that. But it’s being more selective about the tools we use. We always go for the multi-tool, the Swiss Army knife that has all these things in it. And sometimes, all you really need is a pair of scissors. You don’t need all the other stuff, but we have it anyways.

    Chris: Which is a really long way to… I’m sorry, of answering your question. Which is sometimes it’s more code than you could or would want to write yourself, but it’s not nearly as much code as I think we think it requires. When I say you don’t need a framework, I get a lot of push-back around this idea that, “Well, if you don’t use a framework, you’re basically writing your own.” Then that comes with its own problems. I think there’s a place in between using React or Vue and writing your own framework, and it’s maybe picking something that’s a little bit smaller. There are sometimes reasons where writing your own framework might actually be the right call, depending on what you’re trying to do. It’s all very fluid and subjective.

    Drew: It’s quite interesting that as a learning exercise, you implemented your own state-based framework. I remember in the past, I used to think that every time I reached for a library or something, I liked to think that I could implement it myself.

    Chris: Sure, sure.

    Drew: But reaching for the library saved me the hassle of doing that. I knew if I had to write this code myself, I knew what approach I’d take to do it. And that was true all the way up to using things like jQuery and things. These days, I think if I had to write my own version of Vue or React, I have almost no idea what’s happening now in that library, in all that code.

    Drew: For those of us who are not familiar, when you say something like Preact drops the virtual DOM and makes everything a lot smaller, what’s that virtual DOM giving us?

    Chris: To answer that question, I want to take just a slight step back. One of the nicest things that frameworks and other state-based libraries give you is DOM diffing. If you’re not really updating the UI that much, you could get by with saying, “Here’s a string of what the markup is supposed to look like. In HTML, I’ll just put all this markup in this element.” When you need to change something, you do it again. That is a little expensive for browsers, because it triggers a repaint.

    Chris: But I think potentially more importantly than that, one of the issues with doing that is that you have any sort of interactive element in there, a form-field, a link that someone has focused on. That focus is lost because the element… even though you have a new thing that looks similar, it’s not the same literal element. So if focus is lost, it can create confusion for people using screen readers. There’s just a whole bunch of problems with that.

    Chris: Any state-based UI thing worth its weight is going to implement some for of DOM diffing, where they say, “Here’s what the UI should look like. Here’s what it looks like right now in the DOM. What’s different?” And it’s going to go and change those things. It’s effectively doing the stuff you would do just manually updating the UI yourself, but it’s doing it for you under the hood. So you can just say, “Here’s what I want it to look like.” And then the library or framework figures it out.

    Chris: The smaller things like Preact or Alpine, they’re actually doing that directly. They’re converting the string you provide them of what the UI should look like into HTML elements. And then they’re comparing each element to its corresponding piece in the literal DOM. As you end up with UIs that get bigger and bigger and bigger, that can have a performance implication because querying the DOM over and over again becomes expensive. If you want to get a sense for the type of interface where this becomes a problem, right-click and inspect element on the “Favorite” button on Twitter, or the “Like” button on Facebook. And take a look at the nesting of divs that gets you to that element. It’s very, very deep. It’s like a dozen or so divs, nested one inside the other just for that single tweet.

    Chris: When you start going that many layers down, it starts to really impact performance. What the virtual DOM does is instead of checking the real DOM every time, it creates an object-based map of what the UI looks like in JavaScript. And then does the same thing for the UI you want to replace the existing one with, and it compares those two. That’s a lot more performance in theory, than doing that in the real DOM. Once it gets a list of the things it needs to change, it just runs off and makes those changes. But it only has to attack the DOM once. It’s not checking every single element, every single time. If you have interfaces like Twitters or Facebooks or QuickBooks or something like that, virtual DOM probably makes a lot of sense.

    Chris: The challenge with it is… the difference between Preact and React is 27 kilobytes before you unpack the whole thing into its actual codewave. The raw download and unpacking and compiling time on that alone can add quite a bit of latency to the initial load on a UI. That becomes even more pronounced if your users are on not the latest devices from Apple. Even an Android device from a couple of years ago or a feature phone, or if you have people in developing countries, it’s just really… the time to get going is slower. And then on top of that, the actual interactive time is slower because of the extra abstraction.

    Chris: So it’s not just you load it and they’re comparable in speed. Each micro interaction that someone makes and the changes that need to happen can also be slightly slower just because of all that extra code in there. If you have a really, really complex UI with lots of nested elements and lots of data, then the virtual DOM’s performance gains outweigh that extra code weight. But any typical UI for a typical app that most of what I see developers using React or Vue for, the benefit you get from the virtual DOM just isn’t there and they’d be better off. Even if you want to keep the same convenience of React, use Preact. It’s a fraction of the size, it’ll work exactly the same way, and it’ll more performing. This is the kind of thing that I tend to argue for.

    Chris: We need to be better about picking the right tool for the job. If you go with an approach like that, if you get to a point where a virtual DOM actually makes sense, it’s much easier to port Preact into React than if you rolled your own. That’s the situation. If you’re really worried about that, you get some future-proofing built in too.

    Drew: Some might say, they might make the argument that these frameworks, things like Vue, React are so highly optimized for performance that you get so much benefit there that surely just pairing that with a package manager in a bundler to make sure you’re only sending down the code that you want to. Surely, you are way ahead already just by doing that?

    Chris: Yeah. I don’t agree. I don’t really have much more to elaborate on that other than… I guess maybe, but not really. Even with a bundler, you still need that React core. Even with the bundling, that’s still going to be bigger than using something like Preact.

    Chris: Drew, I really appreciate you leading the question on this. Because one of the other things I do talk about in my book, The Lean Web, and my talk of the same name, is how these tools… You mentioned the bundling, for example. One of the things we do to get around the performance hit that we take from using all this JavaScript is we throw even more JavaScript at the front-end to account for it. One of the ways we do that is package managers and module bundlers.

    Chris: As you alluded to… for those of you who don’t know, these are tools that will… they will compile all of your little individual JavaScript bits into one big file. The newer ones and the more… I don’t want to call them thoughtful. But the newer ones will use a feature called tree shaking, where they get rid of any code that isn’t actually needed. If that code has some dependencies that aren’t used for the thing you’ve actually done, they’ll drop some of that stuff out to make your packages as small as possible. It’s actually not a terrible idea, but it results in this thing I typically call dependency health where you have this really delicate house of cards of dependencies on top of dependencies on top of dependencies.

    Chris: Getting your process set up takes time. And anybody who has ever run an NPM install and then discovered that a bunch of dependencies were out of date and had to spend an hour trying to figure out which ones needed to be fixed and oh, it’s actually a dependency in a dependency and you don’t have the ability to go fix it yourself. It’s a whole thing. Maybe it works for you, but I’d rather spend my time not messing around trying to get my dependencies together.

    Chris: I’ve started collecting tweets from people where they complain about time wasted on their workflow. One of my favorites, Brad Frost a couple year ago, was talking about the depressing realization that the thing you’ve been slogging through in modern JS could have taken you 10 minutes in jQuery. I’m not really a jQuery fan, but I feel that pain when it comes to working with frameworks.

    Chris: The other issue with a lot of these tools is they start to become gatekeepers. I don’t know how much you really want to dive into this or not, Drew. But one of my big push-backs against JS, all the things in a workflow. Especially when you start to then say, “Well, if we’re already using JS for the HTML, why not use it for CSS too?” You start to exclude a lot of really talented people from the development process. It’s just a really big loss for the project for the community as a whole.

    Drew: Well, I certainly am… I started picking up React at the beginning of 2020, adding that to my skillset. I’ve been doing it now for nearly seven months. I’ve got to say one part I’m least confident in is setting up the tooling around getting a project started.

    Drew: It seems like there’s an awful lot of work to get something to Hello World, and there’s even more that you’ve got to know to get it to be production ready. That has to make development more difficult to get started with if this is being put forward as what you should be doing in 2020 to learn to be a web developer. Somebody coming in new to it is going to have a real problem. It’s going to be a real barrier to entry, isn’t it?

    Chris: Absolutely. The other piece here is that JavaScript developers aren’t always the only people working on a code base or contributing in a meaningful way to that code base. The more we make knowing JavaScript a requirement for working with a code base, the less likely those people are to be able to actually participate in the project.

    Chris: An example of that, that I like to talk about is WordPress, who has been recently… I shouldn’t say recently at this point. It’s been a couple of years now. But they’ve been shifting their back-end stack more and more to JavaScript, away from PHP, which is not inherently a bad thing. Their new editor, Gutenburg, is built on React.

    Chris: In 2018, WordPress’s lead accessibility consultant, Rian Rietveld, whose name I almost certainly butchered… she very publicly resigned from her positioned and documented why in a really detailed article. The core of the problem was that her and her team were tasked with auditing this editor to make sure that it was going to be accessible. WordPress comprises now 30% of the web. Their goal is to democratize publishing, so accessibility is a really important part of that. It should be an important part of any web project. But for them in particular, it is acutely important. Her team’s whole job is to make sure… her team’s whole job was to make sure that this editor would be accessible. But because neither she nor anyone on her team had React experience and because they couldn’t find volunteers in the accessibility community with that experience, it made it really difficult for her and her team to do their work.

    Chris: Historically, they could identify errors and then go in and fix them. But with the new React based workflow, they were reduced to identifying bugs and then filing tickets. They got added to a backlog along with all the other feature development requests that the JavaScript developers were working on. A lot of stuff that could have been easily fixed didn’t make it into the first release.

    Chris: In May of 2019, about a year after Rian resigned, there was a detailed accessibility audit done on Gutenburg. The full report was 329 pages. The executive summary alone was 34 pages. It documented 91 accessibility related bugs in quite a bit of detail. Many of these were really… I don’t want to call them simple low-hanging fruit, but a lot of them were basic things that Rian’s team could have fixed and it would have freed up the developers to focus on feature development. That’s ultimately what it seems like they ended up doing, was spending a lot of time on feature development and pushing this stuff off til later. But that team is super important to the project, and they suddenly got locked out of the process because of a technical choice.

    Chris: Alex Russell is a developer on the Chrome team. He wrote this article a couple of years ago called The Developer Bait and Switch, where he talked about the straw man argument of frameworks. This idea that these tools let you move faster and because of that, you can iterate faster and deliver better experiences. It’s this idea that a better developer experience means a better user experience. I think this is a very clear example of how that argument doesn’t always play out the way people believe it does. It’s a better experience for maybe some people, not for everyone.

    Chris: CSS developers, people working on design systems, their ability to create tools that others can use sometimes gets limited by these tool choices too. In my experience, I used to be better at CSS. It’s changed a lot in the last few years and I am nowhere near as good as I used to be. In my experience, the people who are really advanced CSS developers… and I do mean that in the truest sense. People who work on CSS are proper web developers working on a programming language. It’s a very special, or can be a very specialized thing. The people who are exceptionally good at it, in my experience, are not always also very good at JavaScript because you end up diving really deep into one thing and you slide a little bit on some other stuff. Their ability to work with these technologies gets hindered as well, which is too bad because it used to not be the case.

    Chris: When the stack was simpler, it was easier for people from multiple disciplines to participate in the development process. I think that’s to the detriment of both the things we build and the community at large, when that’s no longer the case.

    Drew: I found recently in a project researching ways to deal with some of the CSS problems, workflow problems, we’re having multiple working on the project and the bundle size increasing and the old CSS never getting removed. It was a React project, so we were looking at some of these CSS in JavaScript approaches to see what would be best for us to use to solve the problems that we had. What became very quickly apparent is there’s not only one solution to do this. There are dozens of different ways you could do this.

    Drew: CSS in JS is a general approach, but you might go from one project to the next and it’s completely influenced in a completely different way. Even if you’re a CSS person and you learn a particular approach on a project, those skills may not be transferrable anyway. It’s very difficult to see how somebody should investment too much time in learning that if they’re not particularly comfortable with JavaScript.

    Chris: Yeah. The other interesting thing that I think you just got out a little bit is when I talk about this, one of the biggest pieces of push-back I get is that frameworks enforce conventions. You’re going with Vanilla JavaScript, you’ve got this green field-blue sky, you can do anything you want kind of project. With React, there’s a React way to do things.

    Chris: But one of the things I have found is that there are Reacty approaches, but there’s not a strict one right way to do things with React. It’s one of the things people love about it. It’s a little bit more flexible, you can do things a couple of different ways if you want. Same with Vue. You can use that HTML based thing where you’ve got your properties right in the HTML and Vue replaces them, but you can also use a more JSX-like templating kind of syntax if you’d prefer.

    Chris: I’ve heard multiple folks complain about when they’re learning React, one of the big problems is you Google how to do X in React and you get a dozen articles telling you a dozen different ways that you could do that thing. That’s not to say they don’t put some guardrails on a project. I don’t think it’s as clearcut as, “I’ve chosen a framework. Now this is the way I build with it.” To be honest, I don’t know that that’s necessarily something I’d want either. I don’t think you’d want those tightly confined… some people do, maybe. But if you’re touting that as a benefit, I don’t think it’s quite as pronounced as people sometimes make it out to be.

    Chris: You got into an interesting thing though just there, where you were mentioning the CSS that is no longer needed. I think that is one of the legitimately interesting things that something like CSS and JS… or tying your CSS to JavaScript components in some way can get you is if that component drops out, the CSS also in theory, goes away with it. A lot of this to me feels like throwing engineering at people problems. Invariably, you’re still dependent on people somewhere along the line. That’s not to say never use those approaches, but they’re certainly not the only way to get at this problem.

    Chris: There are tools you can use to audit your HTML and pull out the styles that aren’t being used even without using CSS and JavaScript. You can write CSS “the old-fashioned way” and still do the linting of unused styles. There are authoring approaches to CSS that give you a CSS in JS-like output and keep your style sheet small without spitting out these gibberish human unreadable class names that you get with CSS and JS sometimes. Like X2354ABC, or just these nonsense words that get spit out.

    Chris: This is where I start to get really into the old man yells at cloud kind of thing. I’m really showing my developer age here. But yeah, it’s not necessarily that these things are bad, and they’re built to solve legitimate problems. I sometimes feel like there’s a little bit of a… if it’s good enough for Facebook, it’s good enough for us kind of thing that happens with these. Well, Facebook uses this tool. If we’re a real engineering program… team, department, organization, we should too. I don’t necessarily think that’s the right way to think about it. It’s because Facebook deals with problems that you don’t, and vice-versa. The size and scale of what they work on is just different, and that’s okay.

    Drew: Exactly. I see some of these things like CSS and JavaScript to be almost like a polyfill. We’ve got legitimate problems, we need a way to solve it. The technology isn’t providing us a way to solve it yet. Maybe whilst we wait for the web platform to evolve and to get around to addressing that problem, this thing that we do right now with JavaScript kind of will see us through and we’ll be okay. We know it’s bad. We know it’s not a great solution, but it helps us right now. And hopefully in the while we can pull it out and use the native solution.

    Chris: It’s really funny you bring this up. Because literally last night, I was watching a talk from Jeremy Keith from last year about progressive web apps. But he was talking about how a couple of decades ago, he was trying to convince people to use JavaScript. Which seems ridiculous at the time, but JavaScript was this new thing. He showed people how you could do cool things like change the color of a link on hover with this new… It seems absurd that you would need JavaScript for that now, because that’s what CSS does for you. But things like the focus attribute or property just didn’t exist at the time.

    Chris: One of the things he said in the talk that I think really resonated with me is that JavaScript in many ways, paves those cow paths. It’s this very flexible and open language that we can use to create or bolt in features that don’t exist yet. And then eventually, browsers catch up and implement these features in a more native way. But it takes time. I completely understand what you’re saying about this. It’s not the perfect solution, but it’s what we have right now.

    Chris: I think for me, the biggest difference between polyfills and some of these solutions is polyfills are designed to be ripped out. If I have a feature I want to implement that the browser doesn’t support yet, but there’s some sort of specification for it and I write a polyfill… once browsers catch up, I can rip that polyfill out and I don’t have to change anything. But when you go down the path of using some of these tools, ripping them up out means rewriting your whole code base. That’s really expensive and problematic. That’s not to say never use them, but I feel really strongly that we should be giving thought to picking tools that can easily be pulled out later. If we no longer need them or the platform catches up, it doesn’t require a huge rewrite to pull them out.

    Chris: So getting to that we have a whole bunch of styles we don’t use anymore thing, that’s why I would personally favor a build tool technology that audits your CSS against the rendered markup and pulls out the things you don’t need. Because down the road if a platform catches up, you can pull that piece of the build tool out without having to change everything. It’s just augmenting what you already have, whereas CSS and JS doesn’t give you that same kind of benefit. I’m just picking on that one, but I think about a lot of these technologies more broadly.

    Chris: I do feel things like React or Vue are probably paving some cow paths that browsers will eventually catch up with and probably use similar approaches if not the same, so there may be less rewriting involved there. A lot of the ecosystem stuff that gets plugged in around that may be less so.

    Drew: I think it’s right, isn’t it, that the web platform moves slowly and carefully. You think if five years ago, we were all putting JavaScript Carousels on our pages. They were everywhere. Everyone was implementing JavaScript Carousels. If the web platform had jumped and implemented a Carousel solution to satisfy that need, it would not be sat there with nobody using it because people aren’t doing that with Carousels anymore. Because it was just a fad, a design trend. To counteract that and stop the platform itself becoming bloated and becoming a problem that needs solving, it does have to move at a lot steadier pace. The upshot of that is HTML that I wrote in 1999 still works today because of that slow process.

    Drew: One of the other areas where things seem to be bloating out on the web is… I guess it’s related to the framework conversation. But it’s the concept of a single-page app. I feel like that a lot of promises are made around single-page apps as to their performance, like you’re getting all this benefit because you’re not reloading the entire page framework. I feel like they don’t always make good on those performance promises. Would you agree with that?

    Chris: Yes. Although I will confess, despite having a very lengthy chapter in my book on this and talking about that a lot in talks and conversations with people, I don’t think single-page apps are always a terrible thing. But I do think this idea that you need one for performance is overstated. You can oftentimes get that same level of performance with different approaches.

    Chris: I think one of the bigger challenges with single-page apps is… For anybody who’s unfamiliar with those. When a single-page app, instead of having separate HTML files or if you’re using something like a database driven site like WordPress, even though you don’t have actual physical HTML files for each page in your WordPress site, WordPress is creating HTML files on the fly and sending them back to browsers when URLs are requested. For purposes of this conversation, instead of having separate HTML files for every view in your app, a single-page app has a single HTML file. That’s what makes it a single-page app. JavaScript handles everything. Rendering the content, routing to different URL paths, fetching new content if it needs to from an API or something like that.

    Chris: One of the spoken benefits of these or stated benefits of these is that only the content on the page changes. You don’t have to re-download all the JS and the CSS. Oh, and you can do those fancy page transitions that designers sometimes love. In theory, this is more performant than having to reload the whole page.

    Chris: The problem with this approach from my perspective is that it also breaks a bunch of stuff that the browser just gives you for free out-of-the-box, and then you need to recreate it with more JS. You have an app that’s slow because it has a lot of JS. So you throw even more JavaScript at it to improve that performance and in doing so, you break a bunch of browser features and then have to re-implement those with even more JS too.

    Chris: For example, some things that the browser will do for free with a traditional website that you need to recreate with JavaScript when you go the single-page app. You need to intercept clicks on links and suppress them from actually firing, with your JavaScript. You then need to figure out what you actually need to show based on that URL, which is normally something that would get handled on the server or based on the file that goes with that URL path. You need to actually update the URL in the address bar without triggering a page reload. You need to listen for forward and back clicks on the browser and update content again, just like you would with clicks on links. You need to update the document title.

    Chris: You also need to shift focus in a way that announces the change in page to people who are using screen readers and other devices so that they’re not confused about where they are or what’s going on. Because they can’t see the change that’s happening, they’re hearing it announced. If you don’t actually shift focus anywhere, that announcement doesn’t happen. These are all things that the browser would do for you that get broken with single-page apps.

    Chris: On top of that, because you have all this extra JavaScript, this is complicated. So most people use frameworks and libraries to handle this sort of thing. Because of all this extra JavaScript to support this approach, you end up with potentially slower initial page load than you would have otherwise. Depending on the content you have, this approach I think sometimes can make sense. If you have an app that is driven by API data where you don’t necessarily know what those URL paths are going to look like ahead of time.

    Chris: Just an example here. You have an animal rescue where you have some adoptable animals, and that data comes from Petfinder, the animal adoption website. You have a bunch of animals there. Petfinder manages that, but you want to display them on your site with the Petfinder API. When your website’s being built, it doesn’t always necessarily have visibility to what pets are available in this exact moment and what kind of URL paths you’re going to need. A single-page app can help you there because it can dynamically on the fly, create these nice URLs that map with each dog or cat.

    Chris: Something like Instagram with lots of user created content, maybe that also makes sense. But for a lot of things, we do know where those URLs are going to be ahead of time. Creating an HTML file that has the content on it already is going to be just as fast as… sometimes even faster than the JavaScript based single-page app approach, especially if you use some other techniques to keep your overall CSS and JavaScript size down. I use this approach on a course portal that I have. The page loads feel instantaneous because HTML is so easy for browsers to render compared to other parts of the stack. It feels like a single-page app, but it’s not.

    Drew: Especially when you consider hosting solutions like a Jamstack approach of putting HTML files out in a CDN so it’s being served somewhere physically close to the user.

    Chris: Yep.

    Drew: Loading those pages can just be so, so quick.

    Chris: Yes. Absolutely. Absolutely. One of the other arguments I think people used to make in favor of single-page apps is offline access. If someone loads it and then their network goes down, the app is already up and all the routes are handled just with the file that’s already there. So there’s no reloading, they don’t lose any work. That was true for a long time. Now with service workers and progressive web apps, that is I think less of a compelling argument, especially since service workers can fetch full HTML files and cache them ahead of time if needed.

    Chris: You can literally have your whole app available offline before someone has even visited those pages if you want. It just happens in the background without the user having to do anything. It’s again, one of those technologies that maybe made sense for certain use cases a few years ago a little less compelling now.

    Drew: It reminds me slightly of when we used to build websites in Flash.

    Chris: Yes.

    Drew: And you’d have just a rectangle embedded in an HTML page which is your Flash Player, and you’d build your entire site in that. You had to reimplement absolutely everything. There was no back button. If you wanted a back button, you had to create a back button, and then you had to create what the concept of a page was. You were writing code upon code, upon code to reimplement just as you are saying things that the browser already does for you. Does all this JavaScript that we’re putting into our pages to create this functionality… is this going to cause fragility in our front-ends?

    Chris: Yes. This is almost certainly from my mind, one of the biggest issues with our over-reliance on JavaScript. JavaScript is just by its nature, is a scripting language, the most fragile part of the front-end stack.

    Chris: For example, if I write an HTML element that doesn’t exist, I spell article like arcitle instead of article and the browser runs across that, it’s going to be like, “Oh, I don’t know what this is. Whatever, I’ll just treat it like a div.” And it keeps going. If I mistype a CSS property… Let’s say I forget the B in bold, so I write old instead, font way old. The browser’s going to be, “I don’t know what this is. Whatever, we’ll just keep going.” Your thing won’t be bold, but it will still be there.

    Chris: With JavaScript, if you mistype a variable name or you try to use a property, you try to call a variable that doesn’t exist or a myriad of other things happen… your minifier messes up and pulls one line of code to the one before it without a semicolon where it needs one, the whole app crashes. Everything from that line on stop working. Sometimes even stuff that happens before that doesn’t complete, depending on how your app is set up. You can very quickly end up with an app that in a different approach, one where you rely a lot more on HTML and CSS, it would work. It might not look exactly right, but it would still work… to one that doesn’t work at all.

    Chris: There’s an argument to be made that in 2020, JavaScript is an integral and important part of the web and most people don’t disable it and most people are using devices that can actually handle modern JavaScript. That’s true, but that’s not the only reason why JavaScript doesn’t work right, even if you have a linter there for example and you catch bugs ahead of time and things. There’s plenty of reasons why JavaScript can go horribly awry on you. CDNs fail.

    Chris: Back in July of last, a year ago this month… at least, when we’re recording this… a bad deploy took down Cloudflare. Interestingly as we’re recording this, I think a week or two ago, Cloudflare had another massive outage that broke a whole bunch of things, which is not a knock on Cloudflare. They’re an incredibly important service that powers a ton of the web. But CDNs do sometimes go down. They are a provider used by 10% of Fortune 1,000 companies. If your JS is served by that CDN and it breaks, the JavaScript file never loads. And if your content is dependent on that JS, your users get nothing instead of getting something just not styled the way you’d like.

    Chris: Firewalls and ad blockers get overly aggressive with what they block. I used to work at a company that had a JavaScript white list because they were extremely security conscious, they worked with some government contract stuff. They had a list of allowed JavaScript, and if your site or if your URL wasn’t part of that, no JavaScript. You have these sites. I remember going to a site where it had one of the hamburger kind of style menus on every view whether it was desktop or mobile, and I could not access any page other than the homepage because no JavaScript, no hamburger, that was it.

    Chris: Sometimes connections just timeout for reasons. Either the file takes a while or someone’s in a spotty or slow connection. Ian Feather, an engineer at BuzzFeed, shared that about 1% of requests for JavaScript on the site fail which is 13 million requests a month. Or it was last year, it’s probably even more now. That’s a lot of failed JavaScript. People commuting go through tunnels and lose the internet. There’s just all sorts of reasons why JavaScript can fail and when it does, it’s so catastrophic.

    Chris: And so we built this web that should be faster than ever. It’s 2020, 5G is starting to become a thing. I thought 4G was amazing. 4G is about as fast as my home wifi network. 5G is even faster, which is just bonkers. Yet somehow, we have websites that are slower and less performant than they were 5 or 10 years ago, and that makes no sense to me. It doesn’t have to be that way.

    Drew: How do we get out of this mess, Chris?

    Chris: Great question. I want to be really clear. I know I’ve hammered on this a couple times. I’m not saying all the new stuff is bad, never use it. But what I do want to encourage is a little bit more thoughtfulness about how we build for the web.

    Chris: I think the overlying theme here is that old doesn’t mean obsolete. It doesn’t mean never embrace new stuff, but don’t be so quick to just jump on all the shiny new stuff just because it’s there. I know it’s one of the things that keeps this industry really exciting and makes it fun to work in, there’s always something new to learn. But when you pick these new things, do it because it’s the right tool for the job and not just because it’s the shiny new thing.

    Chris: One of the other things we didn’t get into as much as I would have liked, but I think is really important, is that the platform has caught up in a really big way in the last few years. Embracing that as much as possible is going to result in a web experience for people that is faster, that is less fragile, that is easier for you to build and maintain because it requires fewer dependencies such as using what the browser gives you out-of-the-box. We used to need jQuery to select things like classes. Now browsers have native ways to do that. People like JSX because it allows you to write HTML in JavaScript in a more seamless way. But we also have template literals in Vanilla JavaScript that give you that same level of ease without the additional dependency. HTML itself can now replace a lot of things that used to require JavaScript, which is absolutely amazing.

    Chris: We talked a little bit about… this is a CSS thing, but hovers over links and how that used to require JavaScript. But using things like the details and summary elements, you can create disclosure, like expand and collapse or accordion elements natively with no scripting needed. You can do auto complete inputs using just a… I shouldn’t say just, I hate that word. But using a humble input element and then a data list element that gets associated with it, with some options. If you’re curious about how any of this stuff works over at vanillajstoolkit.com, I have a bunch of JavaScript stuff that the platform gives you. But I also have some used to require JavaScript and now doesn’t kind of things that might be interesting too if you want some code samples to go along with this.

    Chris: On the CSS side of things, my most popular Vanilla JS plugin ever is this library that lets you animate scrolling down to anchor links. It is very big. It’s the hardest piece of code I’ve ever had to write. And it now is completely replaced with a single line of CSS, scroll behavior smooth. It’s more performant. It’s easier to write. It’s easier to modify its behavior. It’s just a better overall solution.

    Chris: One of the other things that I wish we did more is leaning on multi-page apps. I feel a little bit vindicated here, because I recently saw an article from someone at Google that actually pushes for this approach now too. I thought that was pretty interesting, given this huge angular and then framework… all the things, boom, that Google started a few years back. Kind of cool to see them come back around to this. Using things like static site generators and awesome services like Netlify and CDN caching, you can create incredibly fast web experiences for people using individual HTML files for all of your different views. So kind of leaning on some of this out-of-the-box stuff.

    Chris: In situations where that’s not realistic for you, where you do need more JavaScript, you do need some sort of library, maybe taking a look at the smaller and more modular approaches first instead of just going for the behemoths of the industry. Instead of React, would Preact work? Instead of angular… I mean, instead of Vue rather, would Alpine JS work? There’s also this really interesting pre-compiler out there now called Svelt, that gives you a framework-like experience and then compiles all your code into Vanilla JavaScript. So you get these really tiny bundles that have just what you need and nothing else. Instead of CSS and JavaScript, could you bolt in some third party CSS linter that will compare your HTML to your CSS and pull out the stuff that got left in there by accident? Would a different way of authoring your CSS, like object oriented CSS by Nicole Sullivan, work instead? We didn’t really get to talk about that, but it’s a really cool thing people should check out.

    Chris: And then I think maybe the third and most important piece here, even though it’s less of a specific approach and more just a thing I wish more people kept in mind, is that the web is for everyone. A lot of the tools that we use today work for people who have good internet connections and powerful devices. But they don’t work for people who are on older devices, have spotty internet connections. This is not just people in developing areas. This is also people in the U.K., in certain parts of the U.S. where we have absolutely abysmal internet connections. The middle of our country has very slow internet. I know there’s places in part of London where they can’t wire a new broadband in for historical reasons, so you’re left with these old internet connections that are really bad. There’s places like that all over the world. Last time I was in Italy, same thing. The internet there was horrible. I don’t know if it’s changed since then.

    Chris: The things we build today don’t always work for everyone, and that’s too bad. Because the vision of the web, the thing I love about it, is that it is a platform for absolutely everyone.

    Drew: If listeners want to find out more about this approach, you’ve gone into loads of detail to it in your book, The Lean Web. And that’s available online. Is it a physical book or a digital book?

    Chris: It’s a little bit of both. Well, no. It’s definitely not a physical book. You go to leanweb.dev. You can read the whole thing for free online. You can also if you want, there’s EPUB and PDF versions available for a really small amount of money, I forget how much now. I haven’t looked at it in a while. The whole thing is free online if you want it. You can also watch a talk on this topic where I go into more details if you want.

    Chris: But I’ve also put together a special page just for listeners of Smashing Podcast at gomakethings.com/smashingpodcast, because I’m very creative with naming things. That includes a bunch of resources in addition to the book, around things that we talked about today. It links to a lot of the different techniques that we covered, other articles I’ve written that go deeper into some of these topics and expand on my thinking a little bit. If folks want to learn more, that would probably be the best place to start.

    Drew: That’s terrific. Thank you. I’ve been learning all about the Lean Web. What have you been learning about lately, Chris?

    Chris: Yeah, a couple of things. I alluded to this a little bit earlier with watching Jeremy’s video on progressive web apps. I have been putting off learning how to actually write my own progressive web app for a couple of years because I didn’t have a specific need on anything I was working with. I recently learned from one of my students who is in South Africa, that they have been dealing with rolling blackouts because of some stuff they have going on down there. As a result, she is not able to work on some of the projects we’ve been doing together regularly, because the power goes out and she can’t access the learning portal and follow along.

    Chris: For me, now building an experience where it works even if someone doesn’t have internet has become a higher priority than… I realized that maybe it was before, so I just started digging into that and hope to get that put together in the next few weeks. We’ll see. Jeremy Keith’s resources on this have been an absolute lifesaver though. I’m glad they exist.

    Chris: I know, Drew, you mentioned one of the reasons you like to ask this question is to show that people no matter how seasoned they are, are always learning. Just a little related anecdote. I have been a web developer for I think, about eight years now. I still have to Google the CSS property to use for making things italic, literally every single time I use it. For some reason, my brain defaults to text decoration even though that’s not the right one. I’ll try a couple of combinations of different things, and I always have one word wrong every time. I also sometimes write italics instead of italic. Yeah. If anybody ever there is ever feeling like, oh, I’m never going to learn this stuff… just know that no matter how seasoned you are, there’s always some really basic thing that you Google over and over again.

    Drew: I’ve been a web developer for 22, 23 years, and I have to Google the different properties for Flexbox still, every time. Although I’ve been using that for 23 years. But yeah, some things just… there’s probably going to more of those as I get older.

    Chris: Yeah. Honestly, I ended up building a whole website of stuff I Google over and over again, just to have an easier copy-paste reference because that was easier than Googling.

    Drew: That’s not a bad idea.

    Chris: That’s the kind of lazy I am. I’ll build a whole website to save myself like three seconds of Googling.

    Drew: If you the listener would like to hear more from Chris, you can find his book on the web at leanweb.dev, and his developer Tips newsletter and more at gomakethings.com. Chris is on Twitter at Chris Ferdinandi. And you can check out his podcast at vanillajspodcast.com or wherever you usually get your podcasts. Thanks for joining us today, Chris. Do you have any parting words?

    Chris: No. Thank you so much for having me, Drew. I had an absolutely smashing time. This was heaps of fun. I really appreciate the opportunity to come chat.

    Smashing Editorial
    (il)

    Source link