• Skip to main content
  • Skip to secondary menu
  • Skip to primary sidebar
  • Home
  • Contact Us

iHash

News and How to's

  • HP ProDesk 600G5 Desktop Hexa Core Intel i5 (3.2GHz) 16GB DDR4 RAM 500GB SSD Windows 11 Pro (Refurbished) for $584

    HP ProDesk 600G5 Desktop Hexa Core Intel i5 (3.2GHz) 16GB DDR4 RAM 500GB SSD Windows 11 Pro (Refurbished) for $584
  • Dell OptiPlex 7010 RGB Desktop Quad Core Intel i5 (3.2GHz) 8GB DDR3 RAM 250GB SSD Windows 10 Pro (Refurbished) for $162

    Dell OptiPlex 7010 RGB Desktop Quad Core Intel i5 (3.2GHz) 8GB DDR3 RAM 250GB SSD Windows 10 Pro (Refurbished) for $162
  • Dell OptiPlex 5040 (RGB) Desktop Quad Core Intel i5 (3.2GHz) 16GB DDR3 RAM 500GB SSD Windows 10 Pro (Refurbished) for $249

    Dell OptiPlex 5040 (RGB) Desktop Quad Core Intel i5 (3.2GHz) 16GB DDR3 RAM 500GB SSD Windows 10 Pro (Refurbished) for $249
  • Zerrio: The Ultimate All-In-One Business Management Toolkit (Lifetime Subscription) for $59

    Zerrio: The Ultimate All-In-One Business Management Toolkit (Lifetime Subscription) for $59
  • DNS FireWall: Lifetime Subscription for $59

    DNS FireWall: Lifetime Subscription for $59
  • News
    • Rumor
    • Design
    • Concept
    • WWDC
    • Security
    • BigData
  • Apps
    • Free Apps
    • OS X
    • iOS
    • iTunes
      • Music
      • Movie
      • Books
  • How to
    • OS X
      • OS X Mavericks
      • OS X Yosemite
      • Where Download OS X 10.9 Mavericks
    • iOS
      • iOS 7
      • iOS 8
      • iPhone Firmware
      • iPad Firmware
      • iPod touch
      • AppleTV Firmware
      • Where Download iOS 7 Beta
      • Jailbreak News
      • iOS 8 Beta/GM Download Links (mega links) and How to Upgrade
      • iPhone Recovery Mode
      • iPhone DFU Mode
      • How to Upgrade iOS 6 to iOS 7
      • How To Downgrade From iOS 7 Beta to iOS 6
    • Other
      • Disable Apple Remote Control
      • Pair Apple Remote Control
      • Unpair Apple Remote Control
  • Special Offers
  • Contact us

Retry Dynamic Imports with “React.lazy”

Mar 15, 2023 by iHash Leave a Comment


In the modern web, code splitting is essential. You want to keep your app slim, with a small bundle size, while having “First Contentful Paint” as fast as possible. But what happens when a dynamic module fails to fetch? In this short article, we’ll see how to overcome such difficulties.

Table of Contents

  • Code Splitting
  • The Problem
  • Solution — the naive way
  • Solution — refined
  • Demonstration
  • Real-life data
  • References
  • Full example repository
  • Note
  • EDIT: 22–02–2023

Code Splitting

An app that splits its code by routes might look something like this:

import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';

const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </Suspense>
  </Router>
);

This means that navigating to /about will fetch the About component “on-demand”, and it won’t be part of the app’s main bundle, allowing the app to be thinner in bundle size.

You can read more about splitting your code in react’s official docs.

The Problem

What will happen if the file cannot download at the time of navigation? the app will crash, as React.lazy failed to import.

In cases of issues with the user’s Internet connection, this might be an actual problem. At my workplace, Logz.io, we are running an app with thousands of online users, and it’s common to see failures in module fetching.

You might have seen this error once:

Failed to fetch dynamically imported module: https://example.com/assets/Home.tsx

It might be caused by numerous network issues; slow connection, timeouts, WIFI hiccups, changing VPN, DNS issues, fragile hotspots — the list goes on.

Solution — the naive way

Now that we know modules can sometimes fail to download, we can try re-fetching it. Using React.lazy function definition, we can create a wrapper, and re-execute the importer over and over.

const lazyReactNaiveRetry: typeof React.lazy = (importer) => {
  const retryImport = async () => {
    try {
      return await importer();
    } catch (error) {
      // retry 5 times with 1 second delay
      for (let i = 0; i < 5; i++) {
        await new Promise((resolve) => setTimeout(resolve, 1000w));
        try {
          return await importer();
        } catch (e) {
          console.log("retrying import");
        }
      }
      throw error;
    }
  };
  return React.lazy(retryImport);
};

This LazyReactNaiveRetry has the same signature as React.lazy. It just wraps the importer with a simple retry mechanism.

The usage will look something like this:

const LazyAbout = LazyReactNaiveRetry(() => import("./components/About"));
const LazyHome = LazyReactNaiveRetry(() => import("./components/Home"));

const App = () => (
  <Router>
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<LazyHome />} />
        <Route path="/about" element={<LazyAbout />} />
      </Routes>
    </Suspense>
  </Router>
);

The above approach won’t work. When the browser is fetching a file, no matter what’s coming back, it will cache the response, even if it’s a failed response. Thus, each time we call import again, it won’t initiate a new network call, and will immediately return the cached response, and in case of failure, a failed response.

Solution — refined

Let’s try again. We need some way to tell the browser that we want to retry fetching the module. We can do it using a mechanism called cache-busting. We can add a dynamic search parameter for each network call. It will force the browser to fetch the module again, without harming the actual content.

  1. https://example.com/assets/Home.tsx
  2. https://example.com/assets/Home.tsx?t=1671503807894
  3. https://example.com/assets/Home.tsx?t=1671503829688
export const lazyWithRetries: typeof React.lazy = (importer) => {
  const retryImport = async () => {
    try {
      return await importer();
    } catch (error: any) {
      // retry 5 times with 2 second delay and backoff factor of 2 (2, 4, 8, 16, 32 seconds)
      for (let i = 0; i < 5; i++) {
        await new Promise((resolve) => setTimeout(resolve, 1000 * 2 ** i));
        // this assumes that the exception will contain this specific text with the url of the module
        // if not, the url will not be able to parse and we'll get an error on that
        // eg. "Failed to fetch dynamically imported module: https://example.com/assets/Home.tsx"
        const url = new URL(
          error.message
            .replace("Failed to fetch dynamically imported module: ", "")
            .trim()
        );
        // add a timestamp to the url to force a reload the module (and not use the cached version - cache busting)
        url.searchParams.set("t", `${+new Date()}`);

        try {
          return await import(url.href);
        } catch (e) {
          console.log("retrying import");
        }
      }
      throw error;
    }
  };
  return React.lazy(retryImport);
};

While the usage remains the same:

LazyReact is now wrapped with a working retry mechanism.

Voilà! We now have a working proof-of-concept of retrying a failed dynamic module fetching.

Demonstration

Here we are temporarily blocking the request in Chrome using the Chrome -dev tools. After several failures, we stop blocking and allowing the module to be loaded (status 200). Emulating a real network issue on the users’ side.

Real-life data

A revision of this code is deployed to Logz.io. Since this has been deployed, we are seeing a decrease of 94% in failures to fetch dynamic modules with the expected error: Failed to fetch dynamically imported module

References

It turns out that this is a known issue and is being discussed in the community for some time.

Full example repository

I’ve created a Github repo with the full code working.

Note

This mechanism can be used not only in react, but on every framework. as dynamic import is a javascript feature. The trick here is cache-busting.

EDIT: 22–02–2023

The above solution support only one chain of the file import tree. meaning, that if we have this import relation parent.js => child.js the retry can only succeed on the first file parent.js . The reason is that the cache-busting mechanism would only affect the first import URL. but the second file would not be re-fetched. That is why it’s important to solve this issue from the root, internally by the browser mechanism, as mentioned in the references section above.



Source link

Share this:

  • Facebook
  • Twitter
  • Pinterest
  • LinkedIn

Filed Under: News Tagged With: Dynamic, Imports, React.lazy, Retry

Special Offers

  • HP ProDesk 600G5 Desktop Hexa Core Intel i5 (3.2GHz) 16GB DDR4 RAM 500GB SSD Windows 11 Pro (Refurbished) for $584

    HP ProDesk 600G5 Desktop Hexa Core Intel i5 (3.2GHz) 16GB DDR4 RAM 500GB SSD Windows 11 Pro (Refurbished) for $584
  • Dell OptiPlex 7010 RGB Desktop Quad Core Intel i5 (3.2GHz) 8GB DDR3 RAM 250GB SSD Windows 10 Pro (Refurbished) for $162

    Dell OptiPlex 7010 RGB Desktop Quad Core Intel i5 (3.2GHz) 8GB DDR3 RAM 250GB SSD Windows 10 Pro (Refurbished) for $162
  • Dell OptiPlex 5040 (RGB) Desktop Quad Core Intel i5 (3.2GHz) 16GB DDR3 RAM 500GB SSD Windows 10 Pro (Refurbished) for $249

    Dell OptiPlex 5040 (RGB) Desktop Quad Core Intel i5 (3.2GHz) 16GB DDR3 RAM 500GB SSD Windows 10 Pro (Refurbished) for $249
  • Zerrio: The Ultimate All-In-One Business Management Toolkit (Lifetime Subscription) for $59

    Zerrio: The Ultimate All-In-One Business Management Toolkit (Lifetime Subscription) for $59
  • DNS FireWall: Lifetime Subscription for $59

    DNS FireWall: Lifetime Subscription for $59

Reader Interactions

Leave a Reply Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

  • Facebook
  • GitHub
  • Instagram
  • Pinterest
  • Twitter
  • YouTube

More to See

HP ProDesk 600G5 Desktop Hexa Core Intel i5 (3.2GHz) 16GB DDR4 RAM 500GB SSD Windows 11 Pro (Refurbished) for $584

Jun 7, 2023 By iHash

Dell OptiPlex 7010 RGB Desktop Quad Core Intel i5 (3.2GHz) 8GB DDR3 RAM 250GB SSD Windows 10 Pro (Refurbished) for $162

Jun 7, 2023 By iHash

Tags

* Apple Cisco computer security cyber attacks cyber crime cyber news cybersecurity Cyber Security cyber security news cyber security news today cyber security updates cyber threats cyber updates data data breach data breaches google hacker hacker news Hackers hacking hacking news how to hack incident response information security iOS 7 iOS 8 iPhone Malware microsoft network security ransomware ransomware malware risk management Secure security security breaches security vulnerabilities software vulnerability the hacker news Threat update video web applications

Latest

The Role of the Ransomware Negotiator

Get exclusive insights from a real ransomware negotiator who shares authentic stories from network hostage situations and how he managed them. The Ransomware Industry Ransomware is an industry. As such, it has its own business logic: organizations pay money, in crypto-currency, in order to regain control over their systems and data. This industry’s landscape is […]

Dell OptiPlex 5040 (RGB) Desktop Quad Core Intel i5 (3.2GHz) 16GB DDR3 RAM 500GB SSD Windows 10 Pro (Refurbished) for $249

Expires April 11, 2123 22:07 PST Buy now and get 52% off KEY FEATURES The Dell OptiPlex 5040 Desktop is the perfect home or office PC for professional multitasking, high-speed web browsing, and multimedia applications. Powered by a Quad-Core Intel i5 processor running at 3.2GHz, this refurbished desktop boasts 16GB DDR3 RAM and a 500GB […]

Apple announces winners of the 2023 Apple Design Awards

June 5, 2023 UPDATE Apple announces winners of the 2023 Apple Design Awards At WWDC23, winners are recognized for excellence in innovation, ingenuity, and technical achievement in app and game design Today, Apple proudly unveiled the winners of its annual Apple Design Awards, celebrating 12 best-in-class apps and games. This year’s winners, spanning development teams around […]

DNS FireWall: Lifetime Subscription for $59

Expires June 04, 2024 23:59 PST Buy now and get 70% off KEY FEATURES DNS Firewall is a security app developed to protect users from online threats, such as malware, phishing, and botnets. It operates at the DNS level, filtering and blocking malicious websites before they can reach the user’s network. DNS Firewall maintains an […]

KeepSolid SmartDNS: Lifetime Subscription for $59

Expires June 05, 2024 23:59 PST Buy now and get 70% off KEY FEATURES Seamless streaming made possible! SmartDNS is a solution to bypass geo-restrictions and access regionally blocked content on various streaming platforms and video services. By redirecting DNS queries through their SmartDNS servers, users can unlock access to content that is typically unavailable […]

Dotan Horovits

From Spotify to Open Source: The Backstory of Backstage

Technology juggernauts–despite their larger staffs and budgets–still face the “cognitive load” for DevOps that many organizations deal with day-to-day. That’s what led Spotify to build Backstage, which supports DevOps and platform engineering practices for the creation of developer portals. Eventually, Spotify made the decision to open source Backstage and donate it to the Cloud Native […]

Jailbreak

Pangu Releases Updated Jailbreak of iOS 9 Pangu9 v1.2.0

Pangu has updated its jailbreak utility for iOS 9.0 to 9.0.2 with a fix for the manage storage bug and the latest version of Cydia. Change log V1.2.0 (2015-10-27) 1. Bundle latest Cydia with new Patcyh which fixed failure to open url scheme in MobileSafari 2. Fixed the bug that “preferences -> Storage&iCloud Usage -> […]

Apple Blocks Pangu Jailbreak Exploits With Release of iOS 9.1

Apple has blocked exploits used by the Pangu Jailbreak with the release of iOS 9.1. Pangu was able to jailbreak iOS 9.0 to 9.0.2; however, in Apple’s document on the security content of iOS 9.1, PanguTeam is credited with discovering two vulnerabilities that have been patched.

Pangu Releases Updated Jailbreak of iOS 9 Pangu9 v1.1.0

  Pangu has released an update to its jailbreak utility for iOS 9 that improves its reliability and success rate.   Change log V1.1.0 (2015-10-21) 1. Improve the success rate and reliability of jailbreak program for 64bit devices 2. Optimize backup process and improve jailbreak speed, and fix an issue that leads to fail to […]

Activator 1.9.6 Released With Support for iOS 9, 3D Touch

  Ryan Petrich has released Activator 1.9.6, an update to the centralized gesture, button, and shortcut manager, that brings support for iOS 9 and 3D Touch.

Copyright iHash.eu © 2023
We use cookies on this website. By using this site, you agree that we may store and access cookies on your device. Accept Read More
Privacy & Cookies Policy

Privacy Overview

This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary
Always Enabled
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Non-necessary
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
SAVE & ACCEPT