{"id":13808407,"url":"https://github.com/mgechev/ngx-quicklink","last_synced_at":"2025-05-14T21:09:49.703Z","repository":{"id":33853489,"uuid":"163045982","full_name":"mgechev/ngx-quicklink","owner":"mgechev","description":"Quicklink prefetching strategy for the Angular router","archived":false,"fork":false,"pushed_at":"2024-11-26T00:17:33.000Z","size":1833,"stargazers_count":756,"open_issues_count":26,"forks_count":43,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-13T14:08:17.164Z","etag":null,"topics":["angular","intersection-observer","performance","prefetch","speed"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mgechev.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}},"created_at":"2018-12-25T04:28:37.000Z","updated_at":"2025-03-04T09:35:02.000Z","dependencies_parsed_at":"2024-03-20T04:30:28.246Z","dependency_job_id":"0a0a3eb2-8dde-4a11-bc8f-929761147b54","html_url":"https://github.com/mgechev/ngx-quicklink","commit_stats":{"total_commits":150,"total_committers":21,"mean_commits":7.142857142857143,"dds":0.4866666666666667,"last_synced_commit":"7fb84ebd6fa8efd51be19d4464c10572e37ccbd2"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgechev%2Fngx-quicklink","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgechev%2Fngx-quicklink/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgechev%2Fngx-quicklink/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mgechev%2Fngx-quicklink/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mgechev","download_url":"https://codeload.github.com/mgechev/ngx-quicklink/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248724633,"owners_count":21151561,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["angular","intersection-observer","performance","prefetch","speed"],"created_at":"2024-08-04T01:01:42.005Z","updated_at":"2025-04-13T14:08:21.287Z","avatar_url":"https://github.com/mgechev.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/mgechev/ngx-quicklink/blob/master/logos/logo.png?raw=true\" width=\"305px\"\u003e\n\u003c/div\u003e\n\n# ngx-quicklink\n\n[quicklink](https://github.com/GoogleChromeLabs/quicklink) implementation for Angular. It provides router preloading strategy which automatically downloads the lazy-loaded modules associated with all the visible links on the screen.\n\n## How it works\n\nQuicklink attempts to make navigations to subsequent pages load faster. It:\n\n* **Detects `routerLink`s within the viewport** (using [Intersection Observer](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API))\n* **Waits until the browser is idle** (using [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback))\n* **Checks if the user isn't on a slow connection** (using `navigator.connection.effectiveType`) or has data-saver enabled (using `navigator.connection.saveData`)\n* **Prefetches the lazy loaded modules** using Angular's prefetching strategy)\n\n## Why\n\nThis project aims to be a drop-in solution for sites to prefetch links based on what is in the user's viewport. It also aims to be small (**~2KB minified/gzipped**).\n\n## Usage\n\nFirst you need to install the project:\n\n```bash\nnpm i ngx-quicklink --save\n```\n\nAfter that import the `QuicklinkModule` to the `AppModule`, and use the `QuicklinkStrategy` as `preloadingStrategy` in the router's configuration. For example:\n\n```ts\n// ...\nimport { QuicklinkModule, QuicklinkStrategy } from 'ngx-quicklink';\n\n@NgModule({\n  declarations: [...],\n  imports: [\n    // ...\n    QuicklinkModule,\n    RouterModule.forRoot(routes, { preloadingStrategy: QuicklinkStrategy }),\n  ],\n  bootstrap: [...]\n})\nexport class AppModule {}\n```\n\nIf you want to add a route in the ignore list so that `ngx-quicklink` will not preload it use the `data` property:\n\n```ts\nexport const routes: Routes = [\n  {\n    path: 'contact',\n    loadChildren: import(() =\u003e './contact/contact.module').then(m =\u003e m.ContactModule),\n    data: {\n      preload: false\n    }\n  }\n];\n\n```\n\n**Note that to make the module available in lazy-loaded modules as well you need to import it in a shared module and export it.** Look at [this commit](https://github.com/mgechev/angular-realworld-example-app-qucklink/commit/33ea101c7d84bb5ca086f107148bbc958659f83f) to see how `ngx-quicklink` is integrated in the [angular-realworld-example-app](https://github.com/gothinkster/angular-realworld-example-app).\n\n## Debugging\n\n**Not getting routes preloaded?** Most likely the problem comes from a missing import of the `QuicklinkModule`. The `QuicklinkModule` exports a `LinkDirective` which matches the `[routerLink]` selector. It'll hook into all your router links in the scope of the module and observe their visibility. If you've not imported the `QuicklinkModule` correctly, this directive will be missing and the quicklink preloading strategy will not work.\n\n**How to verify Angular has made my links \"quicklinks\"?** Inspect a router link and check if it has `ngx-ql` attribute. If it does not, make sure you import `QuicklinkModule` in the module that defines the compilation context of the template where the router link is. Alternatively, if the `ngx-ql` attribute is there, but the prefetching does not work as expected, please open an issue.\n\n## Polyfills\n\n`ngx-quicklink`:\n\n* Includes a very small fallback for [requestIdleCallback](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback)\n* Optionally requires `IntersectionObserver` to be supported (see [CanIUse](https://caniuse.com/#feat=intersectionobserver)). On older browsers `ngx-quicklink` preloads all links on the page. If you want to enable the `IntersectionObserver` behavior on older browsers you can use conditional polyfill loading:\n\n```html\n\u003cscript src=\"https://polyfill.io/v2/polyfill.min.js?features=IntersectionObserver\"\u003e\u003c/script\u003e\n```\n\nAlternatively, see the [Intersection Observer polyfill](https://github.com/w3c/IntersectionObserver/tree/master/polyfill).\n\n## FAQ\n\n*What's the difference between quicklink and ngx-quicklink?*\n\n\u003equicklink prefetches the resource pointed by the `href` attribute of an anchor. This doesn't work for Angular because the value of the `href` attribute is not a JavaScript bundle but a path defined inside of the routing configuration. ngx-quicklink introduces some additional functionality to make the same strategy work well with Angular.\n\n*Should I use [Guess.js](https://github.com/guess-js/guess) or ngx-quicklink?*\n\n\u003eThe prefetching behavior of Guess.js would most likely be more accurate compared to ngx-quicklink, which will reduce the overfetching. Guess.js, however, may take a little more effort to setup. In case you don't want to integrate with the analytics of your website ngx-quicklink is the right choice for you.\n\n## Developing \u0026 releasing\n\nFor a demo:\n\n```shell\ngit clone git@github.com:mgechev/ngx-quicklink\ncd ngx-quicklink \u0026\u0026 npm i\nng build --project ngx-quicklink\nng serve\n```\n\nTo release first update the package version and after that:\n\n```shell\nnpm run release\ncd dist/ngx-quicklink\nnpm publish\n```\n\n## Contributors\n\n[\u003cimg alt=\"mgechev\" src=\"https://avatars.githubusercontent.com/u/455023?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/mgechev) |[\u003cimg alt=\"dependabot[bot]\" src=\"https://avatars.githubusercontent.com/in/29110?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/apps/dependabot) |[\u003cimg alt=\"wKoza\" src=\"https://avatars.githubusercontent.com/u/11403260?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/wKoza) |[\u003cimg alt=\"rolaveric\" src=\"https://avatars.githubusercontent.com/u/960670?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/rolaveric) |[\u003cimg alt=\"thekiba\" src=\"https://avatars.githubusercontent.com/u/1910515?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/thekiba) |[\u003cimg alt=\"Flyrell\" src=\"https://avatars.githubusercontent.com/u/19550608?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/Flyrell) |\n:---: |:---: |:---: |:---: |:---: |:---: |\n[mgechev](https://github.com/mgechev) |[dependabot[bot]](https://github.com/apps/dependabot) |[wKoza](https://github.com/wKoza) |[rolaveric](https://github.com/rolaveric) |[thekiba](https://github.com/thekiba) |[Flyrell](https://github.com/Flyrell) |\n\n[\u003cimg alt=\"Niaro\" src=\"https://avatars.githubusercontent.com/u/7147943?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/Niaro) |[\u003cimg alt=\"krzysztof-grzybek\" src=\"https://avatars.githubusercontent.com/u/6236664?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/krzysztof-grzybek) |[\u003cimg alt=\"tarsinzer\" src=\"https://avatars.githubusercontent.com/u/21989873?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/tarsinzer) |[\u003cimg alt=\"mehmet-erim\" src=\"https://avatars.githubusercontent.com/u/34455572?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/mehmet-erim) |[\u003cimg alt=\"Timebutt\" src=\"https://avatars.githubusercontent.com/u/10674081?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/Timebutt) |[\u003cimg alt=\"pshurygin\" src=\"https://avatars.githubusercontent.com/u/25816676?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/pshurygin) |\n:---: |:---: |:---: |:---: |:---: |:---: |\n[Niaro](https://github.com/Niaro) |[krzysztof-grzybek](https://github.com/krzysztof-grzybek) |[tarsinzer](https://github.com/tarsinzer) |[mehmet-erim](https://github.com/mehmet-erim) |[Timebutt](https://github.com/Timebutt) |[pshurygin](https://github.com/pshurygin) |\n\n[\u003cimg alt=\"thomashuston\" src=\"https://avatars.githubusercontent.com/u/733696?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/thomashuston) |[\u003cimg alt=\"Komock\" src=\"https://avatars.githubusercontent.com/u/7387686?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/Komock) |[\u003cimg alt=\"jlilly\" src=\"https://avatars.githubusercontent.com/u/2780209?v=4\u0026s=117\" width=\"117\"\u003e](https://github.com/jlilly) |\n:---: |:---: |:---: |\n[thomashuston](https://github.com/thomashuston) |[Komock](https://github.com/Komock) |[jlilly](https://github.com/jlilly) |\n\n## License\n\nMIT\n","funding_links":[],"categories":["`⚡ Performance Cheatsheet`","Third Party Components"],"sub_categories":["7. Use preloading strategy","Router"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgechev%2Fngx-quicklink","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmgechev%2Fngx-quicklink","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmgechev%2Fngx-quicklink/lists"}