{"id":19356897,"url":"https://github.com/alexfigliolia/react-lazy","last_synced_at":"2026-03-07T00:31:00.562Z","repository":{"id":244109529,"uuid":"814278657","full_name":"alexfigliolia/react-lazy","owner":"alexfigliolia","description":"Lazy components that dynamically load on mount and support preloading","archived":false,"fork":false,"pushed_at":"2025-05-17T23:39:49.000Z","size":264,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-22T19:13:29.109Z","etag":null,"topics":["code-splitting","lazy-loading","performance","react"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@figliolia/react-lazy","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexfigliolia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-12T17:28:43.000Z","updated_at":"2025-05-17T23:39:53.000Z","dependencies_parsed_at":"2024-06-13T00:27:12.385Z","dependency_job_id":"726dfd86-cc4a-4abd-b905-bb2020a37cd6","html_url":"https://github.com/alexfigliolia/react-lazy","commit_stats":null,"previous_names":["alexfigliolia/react-lazy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alexfigliolia/react-lazy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexfigliolia%2Freact-lazy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexfigliolia%2Freact-lazy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexfigliolia%2Freact-lazy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexfigliolia%2Freact-lazy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexfigliolia","download_url":"https://codeload.github.com/alexfigliolia/react-lazy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexfigliolia%2Freact-lazy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30204154,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"ssl_error","status_checked_at":"2026-03-06T18:57:34.882Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code-splitting","lazy-loading","performance","react"],"created_at":"2024-11-10T07:05:47.122Z","updated_at":"2026-03-07T00:31:00.539Z","avatar_url":"https://github.com/alexfigliolia.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Lazy\nLazy components that support preloading and dynamically load on mount. \n\n## Installation \n```bash\nnpm i -S @figliolia/react-lazy\n#or\nyarn add @figliolia/react-lazy\n```\n\n## Basic Usage\n```tsx\nimport type { ErrorInfo } from \"react\";\nimport { CreateLazyComponent } from \"@figliolia/react-lazy\";\n\nconst MyLazyComponent = CreateLazyComponent({\n  fallback: \u003cdiv\u003eLoading\u003c/div\u003e, \n  errorBoundary: \u003cdiv\u003eWhoops!\u003c/div\u003e,\n  loader: () =\u003e import(\"./path/to/Component\"),\n  onError: (error: Error, errorInfo: ErrorInfo) =\u003e {}\n});\n\n// Optionally Preload your component using:\nvoid MyLazyComponent.preload()\n\n// Render your component without preloading and it'll\n// load on mount\nexport const MyApp () =\u003e {\n  return (\n    \u003cmain\u003e\n      \u003cMyLazyComponent {...lazyComponentProps} /\u003e\n      {/* your other component markup */}\n    \u003c/main\u003e\n  );\n}\n```\n\n## CreateLazyComponent()\n### Parameters\n`loader`: An async function that resolves to `{ default: ComponentType\u003cT\u003e }`. This function is passed to `React.lazy()`.\n\n`fallback`: (optional) A `ReactNode` to display while to the lazy component is suspended\n\n`errorBoundary`: (optional) A `ReactNode` to display if the lazy component throws an error\n\n`onError`: (optional) A callback to execute if the lazy component throws an error.\n\n### Returns\nA `LazyComponent` instance\n\n## Advanced Usage - Preloading\nThis feature is an additional optimization that allows you to optimistically load dynamic components ahead of when they're actually needed.\n\nConsider a case where you have a user logging into your application for the first time. When they press your login button, you'll probably send a request to your server to validate the user's credentials - then, if they are valid, you'll redirect the user into your app.\n\nWhile the credentials are being sent to the server, it may also be prudent to *securely* `preload` some of the components that are sitting behind your authentication. A working example may look something like the following:\n\n```tsx\nimport { useRef, useCallback } from \"react\";\nimport { LazyHeader, LazyContent, LazyFooter } from \"./your-app-components\";\n\nexport const LoginScreen = () =\u003e {\n  const preloaded = useRef(false);\n\n  const preloadComponents = useCallback(async () =\u003e {\n    if(preloaded.current) {\n      return;\n    }\n    try {\n      await Promise.all([\n        LazyHeader.preload(),\n        LazyContent.preload(),\n        LazyFooter.preload(),\n      ]);\n      preloaded.current = true;\n    } catch() {\n      // silence\n    }\n  }, [preloaded])\n\n  const onSubmit = useCallback(async (e) =\u003e {\n    e.preventDefault();\n    void preloadComponents();\n    try {\n      await fetch(\"/api/auth\", {\n        method: \"POST\",\n        body: JSON.stringify(/* Login Credentials */)\n      });\n      redirect(\"to/your/app\");\n    } catch(e) {\n      // handle error\n    }\n  }, [preloadComponents]);\n\n  return (\n    \u003cform onSubmit={onSubmit}\u003e\n      {/* login inputs */}\n      \u003cbutton type=\"submit\" value=\"Login\" /\u003e\n    \u003c/form\u003e\n  );\n}\n```\nUsing this technique, we can utilize the time that an API request is already in-flight to cache component assets in the browser. This way when authentication completes the redirect to our main application content is instantaneous.\n\n## Advanced Usage - Priority Queue\nFor very large applications, it's expected that many components will be lazy loaded. For instances such as these, it may make sense to yield the main thread back to the end user and pause loading JavaScript temporarily.\n\nThis pattern has been in use at companies like Facebook for several years. Check out [Facebook's blog post](https://engineering.fb.com/2019/04/22/developer-tools/isinputpending-api/) on how they handle large numbers of asynchronous tasks.\n\nThis library comes with a solution for cases such as these:\n```tsx\nimport { PriorityQueue, LazyComponentFactory } from \"@figliolia/react-lazy\"\n\nexport const LoadingQueue = new PriorityQueue(\n  5 /* milliseconds to yield to the main thread */\n);\n\nexport const CreateLazyComponent = LazyComponentFactory(LoadingQueue);\n```\n\nThe `LoadingQueue` in the example above is a priority queue that'll handle loading lazy components created using `CreateLazyComponent()`. The `LoadingQueue` will detect when a user is attempting to interact with the page and pause loading for a specified number of milliseconds to allow events to dispatch on the main thread.\n\nIn addition to user-input awareness, the `CreateLazyComponent` function generated by `LazyComponentFactory` now comes with the ability to prioritize loading certain components against others using a `PriorityLevel`:\n\n```tsx\nimport { PriorityQueue, LazyComponentFactory, PriorityLevel } from \"@figliolia/react-lazy\"\n\nexport const LoadingQueue = new PriorityQueue(\n  5 /* milliseconds to yield to the main thread */\n);\nexport const CreateLazyComponent = LazyComponentFactory(LoadingQueue);\n\nconst MyHighPriorityComponent = CreateLazyComponent({\n  priority: PriorityLevel.Immediate,\n  loader: () =\u003e import(\"./HighPriorityComponent\")\n});\n\nconst MyLowPriorityComponent = CreateLazyComponent({\n  priority: PriorityLevel.Background,\n  loader: () =\u003e import(\"./LowPriorityComponent\")\n});\n```\n\nBy default `Priority.Immediate` components will be loaded ahead of `Priority.Background` components.\n\nA good use of `Priority.Immediate` would be for components that are core to your UI's most basic functionality, such as headers and sidebars. Similarly, for components that are conditionally used such as modals or drawer menus `Priority.Background` is more appropriate.\n\nUtilitizing this pattern in large applications can have a great effect on your core metrics such as `FMP` and `TTI`.\n\nIn addition to loading components, the `LoadingQueue` in the example above can also be used for just about any asynchronous task. You can use it to load a large javascript library in the background or even preload images that might be below the fold:\n\n```typescript\nimport { PriorityQueue, PriorityLevel } from \"@figliolia/react-lazy\";\n\nexport const LoadingQueue = new PriorityQueue();\n\nLoadingQueue.enqueue(\n  PriorityLevel.Background,\n  () =\u003e import(\"expensive-node-module\").then(() =\u003e {\n    // do something with your expensive module when\n    // it loads\n  })\n)\n\nLoadingQueue.enqueue(\n  PriorityLevel.Background,\n  () =\u003e new Promise(resolve =\u003e {\n    const image = new Image();\n    image.onload = resolve;\n    image.onerror = resolve;\n    image.src = \"path/to/large-image.jpeg\";\n  })\n)\n```\n\nYour expensive JS module and large image will now load optimistically, but behind any Components or tasks with `Priority.Immediate`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexfigliolia%2Freact-lazy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexfigliolia%2Freact-lazy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexfigliolia%2Freact-lazy/lists"}