Browsing Tag: Optimizing

    web design

    Optimizing Video For Size And Quality — Smashing Magazine

    02/15/2021

    About The Author

    Doug leads developer relations at api.video, studying the intersection of media and web performance. A Google Developer Expert and the author of O’Reilly’s …
    More about
    Doug

    Adding video to your application can increase customer engagement and satisfaction. But the exact opposite can occur when there are issues with the video playback: video stalls are frustrating and drive customers away. In this article, we’ll walk through the steps to optimize the video on your website to ensure fast playback and reduce stalls.

    Over the last few years, more and more projects are using video as an integral part of the application. This is a great direction, as videos are more engaging than still photos (videos can double conversion rate and increase time spent on site), and as such, can really draw customers to explore details about products and services. However, it all goes sideways when there are issues related to the video playback.

    Video playback issues are directly related to the size and bitrate of the video. A video with large dimensions or a high bitrate will take longer to download and will require a higher speed network to play back smoothly. This leads to longer startup times, and if the network cannot supply the video fast enough, the video will stall during video playback.

    There is a solution though! By running basic optimizations of our videos before adding them to our websites, we can prevent these issues from occurring for good — well, most of them. All we really need to do is make the file smaller — in one way or another. So, now the trick is: how do we make the file smaller without reducing quality?

    In this article, we’ll walk through the tools and some of the steps you can take to optimize your videos for playback — all of it to avoid stalls and impress your precious customers!

    Real-World Data

    It’s not uncommon to find websites with extremely large videos — for example, used used as hero background videos. In my research, I was looking into sites found in the December 2020 mobile HTTPArchive, and it wasn’t difficult to spot a good number of sites loading huge video files by default, both on mobile and on desktop.

    It’s of course doubtful that you will be able to achieve the same savings that I’ll be showing here, but you will get some useful pointers and tips on things to keep in mind when dealing with videos. In fact, it is very easy to accidentally place extremely large videos on your website if you are not careful, resulting in them being almost unusable for most of your customers.

    The Pumpkin Patch Story

    Imagine that it’s mid-October, and you’re looking for a pumpkin patch and a corn maze to spend a weekend afternoon with your family. In the comfort of your desktop machine, you search the web for a nearby location and find the perfect one. The website looks lovely, with a beautiful drone 4K video of the fields playing at the top of the page. You pick the URL and send it to yourself and your loved ones so that you together can continue exploring this option on the go.

    But when you open the page on your phone, you notice a glitch: the video is desperately trying to play on your phone, but unfortunately fails to do so. The video keeps stalling and restarting over and over, being much more disruptive and annoying than it was on your computer. Eventually you move on, bookmark the URL, and move on with your daily routine.

    After a fun muddy day (well, I have recently lived in Seattle and the UK, so pumpkin patches are muddy), you’re back on your computer: perhaps you think yet again about that video and you wonder why it wasn’t playing well on your phone. Well, let’s diagnose what is going on.

    You might start by opening DevTools in your browser. Once the page is loaded, we can move to the Network tab, and filter by “media” to see all the video files:

    Filtering resources by ‘Media’ in DevTools. (Large preview)

    We see that an MP4 file is being downloaded. The file doesn’t come through the network as a standalone file; rather, the streaming service must be breaking up the file into a few segments, so you might see several 206 (partial content) requests for the same file.

    Looking at the response headers for this file, we can spot some details:

    accept-ranges: bytes
    access-control-allow-headers: x-test-header, Origin, X-Requested-With, Content-Type, Accept
    access-control-allow-methods: GET, POST, PUT, DELETE, OPTIONS
    Content-Length: 87690242
    Content-Range: bytes 70025216-157715457/157715458
    content-type: video/mp4
    date: Fri, 22 Jan 2021 15:27:26 GMT
    last-modified: Mon, 24 Jun 2019 05:13:04 GMT
    server: Apache
    

    Now, some of these numbers are slightly scare as they are slightly large. In fact, they are often so large that I’ve found myself getting into the habit of adding commas, so I can get an idea of how large the files actually are. In this case, the partial download is 87 MB, and the entire file is 157,715,457 bytes. Yes, that’s right, this video is 157MB, and it (tried) to load on my phone earlier today! No wonder it didn’t succeed.

    So What’s Up With This Video?

    Let’s dive a little bit deeper. Apparently, the video is way too large to play smoothly on a mobile phone with a lower memory and a slower network. But what do we need to fix it? To figure out what exactly is the problem, we can use FFMPEG, which is open source and free, and proves to be one of the most reliable tools to optimize videos. We could endlessly tweak the configuration in FFMPEG, but let’s just touch on a few important ones in this article.

    So, let’s start with the diagnosis tool called FFprobe. FFprobe gathers information from multimedia streams, and provides you with the details about how the video is encoded and how it will play. It’s a part of the FFMPEG package, and actually quite easy to use.

    Even better: if your video is online already, there is an online version of ffprobe that we can jump to right away. So, let’s just enter the URL into the form, and get the details about the video in return (e.g. video dimensions, bitrate, and quite a bit of metadata).

    When I add the MP4 URL from the pumpkin farm, we immediately see one of the issues. The show_format response from ffprobe returns a summary: apparently, there are 2 streams, and it’s 62s long (which all sounds normal enough to not raise any suspicions). But when we get to the size and bitrate, we immediately see where the video is failing.

    (Large preview)

    As mentioned above, it might be a good idea to get used to adding commas to these large numbers. As it turns out, indeed the drone footage flying over the field is 157MB, and has a bitrate of 20 MB per second! It means that for the video to play seamlessly, the network must be able to stream the video at a rate faster than 20 MBPS, which is exactly why it was stalling on the phone.

    What is the ideal playback bitrate?

    To avoid stall, we need to stream the video at an appropriate rate. That’s where bitrate becomes important. Bitrate is the playback speed of the video. For the browser to play the video smoothly, the video has to be downloading faster than it plays back — meaning that the video will only play back smoothly if the network speed is over 20 MBPS. When I think of network speeds, I tend to rely on WebPageTest’s traffic profiles:

    Traffic profiles to keep in mind on WebPageTest: ranging from Cable and DSL to 3G Slow and 2G. (Large preview)

    As we can tell from the overview abouve, the video might play well on the “Native Connection”, and on the ultra-fast optic cable FIOS connection (20 MBPS is exactly the speed required, so hopefully nothing else needs to be downloaded in the background). However, all the other connections have a downlink speed that’s significantly lower than 20 MBPS. If the video is loading at these speeds, the player will attempt to consume the video faster than it can be downloaded, and the video will permanently stall.

    The bitrate of your video sets the minimum network speed that your customers can use. In general, the bitrate of your video should be about 80% of the available throughput on the network. So a 20 MBPS video really needs 24 MBPS network throughput to play the video seamlessly. Everyone on a slower connection will have a quite poor experience and is likely to not be able to watch the video at all. More specifically, this means that for us to play smoothly and silky on 4G, the bitrate has to stay below 7.2 MBPS.

    Can We Lower This Video’s Bitrate?

    Yes! Let’s look at some of the configurations we can use to reduce this video’s bitrate. But first, let’s look at the data we get from FFprobe. One thing that is quite noticeable is the r_frame_rate value, which is the number of frames per second in the video. Its value is 60000/1001. It means that the frame rate for the video is 60 frames per second. However, typical frame rates on the web are 25–30, so the first thing we can do is to re-encode the video with a lower bitrate.

    Another thing to keep in mind is Constant Rate Factor. In FFMPEG, the principal quality/size benchmark is the Constant Rate Factor (CRF) compression, with values ranging from 0 (no compression) to 50 (high compression). The default value for CRF in FFMPEG is 23 (if you leave out the CRF parameter, your video is with that value). In my personal experience, values from 23-28 still produce high-quality videos, looking good on the web and greatly reduced in file size.

    So let’s start at 30fps and a CRF of 23. The Terminal command will look like this:

    ffmpeg -i input.mp4 -vcodec h264 -acodec aac -crf 23 -strict -2 :v fps=fps=30 output.mp4
    

    Voilà! This results in an 81.5 MB video — already a 48% improvement. But the video is still very large, with a 10 MBPS bitrate. If we set CRF to 28, the file drops to 35.4MB, with a bitrate of 4.5 MBPS which is much more likely to play well on a 4G connection.

    This is a five-time improvement over the original video. To make this video even more accessible, we can resize the video to make it smaller. That’s something we’ll discuss in the streaming section below.

    The Hungry For Pizza Story

    Imagine that you’re in Los Angeles, perhaps visiting from abroad and roaming on your phone, and of course thinking about grabbing a slice of pizza. You find a remarkable pizza place on your phone, and decide to head there. You may have noticed a few videos and hero images on the page, but really, every pizza place kind of looks the same, so you didn’t bother to watch the video. You head and grab a slice or two before heading back to your hotel.

    That night, you get a text from your carrier that you used a lot more data than you imagined (and definitely way more than you originally planned!). A couple of cabs, and the pizza website — how expensive was the pizza website again?

    You pop the pizza website into WebPageTest and check it on a mobile connection:

    A pie chart with the video taking up 80.2% of the entire data consumed. (Large preview)

    44 MB of video. Where is it coming from? Even beyond that, when we examine the source and the waterfall in a bit more detail, we can see that there are actually two videos! Fortunately (or unfortunately?), neither managed to be downloaded entirely:

    Video 1 downloaded 11.8 MB (of 121 MB total)
    Video 2 downloaded 31.1MB (of 139 MB total)

    This raises a few concerns and a few questions.

    First, why was so much video downloaded when it wasn’t autoplaying? We haven’t managed to click anything just yet, but already used almost 40 MB of data. The answer, as always, lies in the source. Well, “view source”, that is.

    <video
      id="u457537-video"
      class="video-js vjs-big-play-centered"
      controls
      preload="auto"
      width="1050"
      height="591"
      poster="assets/home_poster.jpg"
      data-setup='{"fluid": true}'>
      <source src="http://www.smashingmagazine.com/assets/home_1.mp4" type='video/mp4'>
      <source src="assets/home.webm" type='video/webm'>
      <p class="vjs-no-js">To view this video please enable JavaScript, and consider
        upgrading to a web browser that <a href="http://videojs.com/html5-video-support/"
        target="_blank">supports HTML5 video</a></p>
    </video>
    

    Off the bat, we see at least two issues:

    • preload=“auto”
      When we set preload="auto", we are overriding the browser’s default setting, enforcing video download — whether or not your customer has pressed “Play”. The default preload attribute is metadata, and would have resulted in a few 100KB downloaded. Admittedly, it is a much better outcome for site visitors who will never watch this video.
    • Video Order
      If you have multiple versions of the video (in this case: h264 .mp4 and VP8 .webm encoded videos), the browser will choose the first video it knows how to play. Now, every modern browser supports mp4, while most modern browsers also support webm (95.4% global support, according to CanIUse).

    One trick that I like to use is to insert the appropriate video source line with Javascript. That way, if you so choose to not serve video on certain screens, you just have an empty <video> tag — and no video can be downloaded.

    
        window.onload = addAutoplay();
        var videoLocation  = document.getElementById("hero-video");
    
        function addAutoplay() {
            if(window.innerWidth > 992){
                videoLocation.setAttribute("autoplay","");
          };
        }
    
    

    If we now run an ffprobe on these two videos, we’ll discover significant differences in sizes:

    The webm is 90% smaller, and yet has 0 views, since every browser supports the mp4. These two videos are both 640×360, and 140s long. Running the ffmpeg command from above on the mp4 results in a 12.4 MB video, so it’s likely that developers followed a similar process to compress and encode the .webm variant as well. Perhaps having preload="auto" for 12.5 MB would not be so bad after all.

    The second video (drone footage inside the restaurant) is filmed in Full HD (1080p), but similarly gets compressed from 140MB to 35 MB. So, 120s with FFMPEG could reduce the video weight on this page from 160 MB to 57 MB. Flipping the webm/mp4 order would save an additional few MB for 95% of the browsers that can support that format.

    What if we wanted to do even better, perhaps make the videos responsive to various sized screens? Well, let’s get even smaller videos — with responsive videos!

    The <video> tag doesn’t support media queries to serve different video files to different screens, so we need a different way to provide videos sized for the device screen. The easiest way to achieve that is by using video streaming. This will add some Javascript and other assets for the video player that will be required, but the video savings will definitely make up for this extra data.

    We can create video streams with FFMPEG (I have used bash scripts like this in the past), but this requires us to know all the sizes and settings we’d like to use (and as mentioned before, FFMPEG has a lot of settings!).

    To make it easier to stream video, there are APIs (e.g. api.video and Mux) where you upload your video, and the tools create video streams and host your video for you. For full disclouse, I do work at the former one, so to simplify my video processing pipeline, I’ll use api.video, to transcode and host my videos. With the upload API, I can upload any video, and the tool will create a streaming version at many different dimensions and bitrates (currently 240p, 360p, 480p, 720p, 1080p and 4K).

    The bitrates for the smaller videos are greatly reduced, as the dimensions of the video decrease. This means that the video will require less network capacity on smaller screens and will play on slower networks.

    For brevity, we’ll test only the Pumpkin patch video. I’ve received similar results with the drone video (the other pizza video is just 360p, so it does not greatly benefit from smaller sizes).

    Note: Please recall that this video is currently a 1080p mp4 video at 60fps, and weighs 157 MB for all visitors.

    With some optimizations (CRF 28 and reducing the framerate to 30fps), the video was reduced to 35.7 MB. Using DevTools, we can emulate devices to see how much data is used for video playback of streaming video on different sized screens.

    The table below is showing the total amount of traffic used. With HLS video, there is a JavaScript player, CSS, fonts, etc. that add about 1 MB of additional overhead. This is included in the totals below:

    Device Video Size (Pixels) Video Size (MB) Bitrate (MBPS)
    Moto G4 (Portrait) 240p 3.1 MB 0.35
    Moto G4 (Landscape) 360p 7.5 MB 0.800
    Iphone 7/7/8 (Landscape) 480p 12.1 MB 1.40
    Ipad (Landscape) 720p 21.2 MB 2.6
    Ipad Pro (Landscape) 1080p 39.4 MB 4.4

    At 1080p, there is about 4MB additional assets downloaded for the stream, but for every other size, there are significant data savings with no loss in video quality. Not only will the video be sized properly for the devices, but it is much less likely to stall, as the bitrate is reduced for the devices most likely to be on slower mobile connections.

    Video streaming takes care of framerate, video size and quality concerns — ensuring fast playback on any size screen, and any speed network.

    Another advantage to video streaming: if the network is slow (or suddenly becomes slower), the player can adjust the video being shown, and play a lower quality version of the video — ensuring playback on the device — even in poor network conditions. (You can test the different videos with StreamOrNot, a little open source project that I’ve released a while back.

    Now, isn’t it a little bit too much overhead? Couldn’t we do the same (just much faster) with YouTube or Vimeo? We surely could, but then we wouldn’t be able to completely remove the branding or advertising from the video, not to mention the overhead of scripts loaded within the video player iframe. Plus, sometimes you might want to use the video as a background video on your product page, and avoid any kind of external branding at all.

    Conclusion

    We do not deploy images from our camera directly to the web, but we compress and resize them to balance quality and web performance. The same should be done for video files as well. Smaller videos start playing faster and stall less often, improving the user experience of the website.

    In this article, we’ve walked through a few simple steps to optimize our videos, e.g. by lowering the quality and its framerate. We also looked at how video streaming can allow us to build a more responsive video experience for the web — automatically serving videos that are properly sized for the screen of the device.

    Thanks for reading, and if you’d like to learn more, you may want to read more on video best practices here, on Smashing Magazine, and on my blog:

    Smashing Editorial
    (vf, il)

    Source link

    web design

    Methods Of Improving And Optimizing Performance In React Apps — Smashing Magazine

    07/16/2020

    About The Author

    Shedrack Akintayo is a software engineer from Lagos, Nigeria, who has a love for community building, open source and creating content and tech for the next …
    More about
    Shedrack

    Since React was introduced, it has transformed the way front-end developers build web applications, and its virtual DOM is famous for effectively rendering components. In this tutorial, we will discuss various methods of optimizing performance in React applications, and also the features of React that we can use to improve performance.

    React enables web applications to update their user interfaces (UIs) quickly, but that does not mean your medium or large React application will perform efficiently. Its performance will depend on how you use React when building it, and on your understanding of how React operates and the process through which components live through the various phases of their lifecycle. React offers a lot of performance improvements to a web app, and you can achieve these improvements through various techniques, features, and tools.

    In this tutorial, we will discuss various methods of optimizing performance in React applications, and also the features of React that we can use to improve performance.

    Where To Start Optimizing Performance In A React Application?

    We can’t begin to optimize an app without knowing exactly when and where to optimize. You might be asking, “Where do we start?”

    During the initial rendering process, React builds a DOM tree of components. So, when data changes in the DOM tree, we want React to re-render only those components that were affected by the change, skipping the other components in the tree that were not affected.

    However, React could end up re-rendering all components in the DOM tree, even though not all are affected. This will result in longer loading time, wasted time, and even wasted CPU resources. We need to prevent this from happening. So, this is where we will focus our optimization effort.

    In this situation, we could configure every component to only render or diff when necessary, to avoid wasting resources and time.

    Measuring Performance

    Never start the optimization process of your React application based on what you feel. Instead, use the measurement tools available to analyze the performance of your React app and get a detailed report of what might be slowing it down.

    Analyzing React Components With Chrome’s Performance Tab

    According to React’s documentation,, while you’re still in development mode, you can use the “Performance” tab in the Chrome browser to visualize how React components mount, update, and unmount.
    For example, the image below shows Chrome’s “Performance” tab profiling and analyzing my blog in development mode.

    Performance profiler summary
    Performance profiler summary (Large preview)

    To do this, follow these steps:

    1. Disable all extensions temporarily, especially React Developer Tools, because they can mess with the result of the analysis. You can easily disable extensions by running your browser in incognito mode.
    2. Make sure the application is running in development mode. That is, the application should be running on your localhost.
    3. Open Chrome’s Developer Tools, click on the “Performance” tab, and then click the “Record” button.
    4. Perform the actions you want to profile. Don’t record more than 20 seconds, or else Chrome might hang.
    5. Stop the recording.
    6. React events will be grouped under the “User Timing” label.

    The numbers from the profiler are relative. Most times and components will render more quickly in production. Nevertheless, this should help you to figure out when the UI is updated by mistake, as well as how deep and how often the UI updates occur.

    React Developer Tools Profiler

    According to React’s documentation, in react-dom 16.5+ and react-native 0.57+, enhanced profiling capabilities are available in developer mode using React Developer Tools Profiler. The profiler uses React’s experimental Profiler API to collate timing information about each component that’s rendered, in order to identify performance bottlenecks in a React application.

    Just download React Developer Tools for your browser, and then you can use the profiler tool that ships with it. The profiler can only be used either in development mode or in the production-profiling build of React v16.5+. The image below is the profiler summary of my blog in development mode using React Developer Tools Profiler:

    React Developer Tools Profiler flamegraph
    React Developer Tools Profiler flamegraph (Large preview)

    To achieve this, follow these steps:

    1. Download React Developer Tools.
    2. Make sure your React application is either in development mode or in the production-profiling build of React v16.5+.
    3. Open Chrome’s “Developer Tools” tab. A new tab named “Profiler” will be available, provided by React Developer Tools.
    4. Click the “Record” button, and perform the actions you want to profile. Ideally, stop recording after you have performed the actions you want to profile.
    5. A graph (known as a flamegraph) will appear with all of the event handlers and components of your React app.

    Note: See the documentation for more information.

    Memoization With React.memo()

    React v16 was released with an additional API, a higher-order component called React.memo(). According to the documentation, this exists only as a performance optimization.

    Its name, “memo” comes from memoization, which is basically a form of optimization used mainly to speed up code by storing the results of expensive function calls and returning the stored result whenever the same expensive function is called again.

    Memoization is a technique for executing a function once, usually a pure function, and then saving the result in memory. If we try to execute that function again, with the same arguments as before, it will just return the previously saved result from the first function’s execution, without executing the function again.

    Mapping the description above to the React ecosystem, the functions mentioned are React components and the arguments are props.

    The default behavior of a component declared using React.memo() is that it renders only if the props in the component have changed. It does a shallow comparison of the props to check this, but an option is available to override this.

    React.memo() boosts the performance of a React app by avoiding re-rendering components whose props haven’t changed or when re-rendering is not needed.

    The code below is the basic syntax of React.memo():

    const MemoizedComponent = React.memeo((props) => {
    // Component code goes in here
    })
    

    When To Use React.memo()

    • Pure functional component
      You can use React.memo() if your component is functional, is given the same props, and always renders the same output. You can also use React.memo() on non-pure-functional components with React hooks.
    • The component renders often
      You can use React.memo() to wrap a component that renders often.
    • The component re-renders with same props
      Use React.memo() to wrap a component that is usually provided with the same props during re-rendering.
    • Medium to high elements
      Use it for a component that contains a medium to high number of UI elements to check props for equality.

    Note: Be careful when memoizing components that make use of props as callbacks. Be sure to use the same callback function instance between renderings. This is because the parent component could provide different instances of the callback function on every render, which will cause the memoization process to break. To fix this, make sure that the memoized component always receives the same callback instance.

    Let’s see how we can use memoization in a real-world situation. The functional component below, called “Photo”, uses React.memo() to prevent re-rendering.

    export function Photo({ title, views }) {
      return (
        <div>
          <div>Photo title: {title}</div>
          <div>Location: {location}</div>
        </div>
      );
    }
    // memoize the component
    export const MemoizedPhoto = React.memo(Photo);
    

    The code above consists of a functional component that displays a div containing a photo title and the location of the subject in the photo. We are also memoizing the component by creating a new function and calling it MemoizedPhoto. Memoizing the photo component will prevent the component from re-rendering as long as the props, title, and location are the same on subsequent renderings.

    // On first render, React calls MemoizedPhoto function.
    <MemoizedPhoto
      title="Effiel Tower"
      location="Paris"
    />
    
    // On next render, React does not call MemoizedPhoto function,
    // preventing rendering
    <MemoizedPhoto
      title="Effiel Tower"
      location="Paris"
    />
    

    Here, React calls the memoized function only once. It won’t render the component in the next call as long as the props remain the same.

    Bundling And Minification

    In React single-page applications, we can bundle and minify all our JavaScript code into a single file. This is OK, as long as our application is relatively small.

    As our React application grows, bundling and minifying all of our JavaScript code into a single file becomes problematic, difficult to understand, and tedious. It will also affect the performance and loading time of our React app because we are sending a large JavaScript file to the browser. So, we need some process to help us split the code base into various files and deliver them to the browser in intervals as needed.

    In a situation like this, we can use some form of asset bundler like Webpack, and then leverage its code-splitting functionality to split our application into multiple files.

    Code-splitting is suggested in Webpack’s documentation as a means to improve the loading time of an application. It is also suggested in React’s documentation for lazy-loading (serving only the things currently needed by the user), which can dramatically improve performance.

    Webpack suggests three general approaches to code-splitting:

    • Entry points
      Manually split code using entry configuration.
    • Duplication prevention
      Use SplitChunksPlugin to de-duplicate and split chunks.
    • Dynamic imports
      Split code via inline function calls within modules.

    Benefits Of Code Splitting

    • Splitting code assists with the browser’s cache resources and with code that doesn’t change often.
    • It also helps the browser to download resources in parallel, which reduces the overall loading time of the application.
    • It enables us to split code into chunks that will be loaded on demand or as needed by the application.
    • It keeps the initial downloading of resources on first render relatively small, thereby reducing the loading time of the app.
    Bundling and minification process
    Bundling and minification process (Large preview)

    Immutable Data Structures

    React’s documentation talks of the power of not mutating data. Any data that cannot be changed is immutable. Immutability is a concept that React programmers should understand.

    An immutable value or object cannot be changed. So, when there is an update, a new value is created in memory, leaving the old one untouched.

    We can use immutable data structures and React.PureComponent to automatically check for a complex state change. For example, if the state in your application is immutable, you can actually save all state objects in a single store with a state-management library like Redux, enabling you to easily implement undo and redo functionality.

    Don’t forget that we cannot change immutable data once it’s created.

    Benefits Of Immutable Data Structures

    • They have no side effects.
    • Immutable data objects are easy to create, test, and use.
    • They help us to write logic that can be used to quickly check for updates in state, without having to check the data over and over again.
    • They help to prevent temporal coupling (a type of coupling in which code depends on the order of execution).

    The following libraries help to provide a set of immutable data structures:

    • immutability-helper
      Mutate a copy of data without changing the source.
    • Immutable.js
      Immutable persistent data collections for JavaScript increase efficiency and simplicity.
    • seamless-immutable
      Immutable data structures for JavaScript become backwards-compatible with normal JavaScript arrays and objects.
    • React-copy-write
      This gives immutable state with a mutable API.

    Other Methods Of Improving Performance

    Use A Production Build Before Deployment

    React’s documentation suggests using the minified production build when deploying your app.

    React Developer Tools’ “production build” warning
    React Developer Tools’ “production build” warning (Large preview)

    Avoid Anonymous Functions

    Because anonymous functions aren’t assigned an identifier (via const/let/var), they aren’t persistent whenever a component inevitably gets rendered again. This causes JavaScript to allocate new memory each time this component is re-rendered, instead of allocating a single piece of memory only once, like when named functions are being used.

    import React from 'react';
    
    // Don’t do this.
    class Dont extends Component {
      render() {
        return (
          <button onClick={() => console.log('Do not do this')}>
            Don’t
          </button>
        );
      }
    }
    
    // The better way
    class Do extends Component {
      handleClick = () => {
        console.log('This is OK');
      }
      render() {
        return (
          <button onClick={this.handleClick}>
            Do
          </button>
        );
      }
    }
    

    The code above shows two different ways to make a button perform an action on click. The first code block uses an anonymous function in the onClick() prop, and this would affect performance. The second code block uses a named function in the onClick() function, which is the correct way in this scenario.

    Mounting And Unmounting Components Often Is Expensive

    Using conditionals or tenaries to make a component disappear (i.e. to unmount it) is not advisable, because the component made to disappear will cause the browser to repaint and reflow. This is an expensive process because the positions and geometries of HTML elements in the document will have to be recalculated. Instead, we can use CSS’ opacity and visibility properties to hide the component. This way, the component will still be in the DOM but invisible, without any performance cost.

    Virtualize Long Lists

    The documentation suggests that if you are rendering a list with a large amount of data, you should render a small portion of the data in the list at a time within the visible viewport. Then, you can render more data as the list is being scrolled; hence, the data is displayed only when it is in the viewport. This process is called “windowing”. In windowing, a small subset of rows are rendered at any given time. There are popular libraries for doing this, two of which are maintained by Brian Vaughn:

    Conclusion

    There are several other methods of improving the performance of your React application. This article has discussed the most important and effective methods of performance optimization.

    I hope you’ve enjoyed reading through this tutorial. You can learn more via the resources listed below. If you have any questions, leave them in the comments section below. I’ll be happy to answer every one of them.

    Smashing Editorial
    (ks, ra, al, il)

    Source link