We're sorry but this app doesn't work properly without JavaScript enabled. Please enable it to continue.

This lesson's interactive features are locked, please to keep using them

Concurrency

Your web crawler works – but it's crawling pages one at a time. It would take us a really long time to crawl a large website. Let's make it faster using Promise-based concurrency. This is another long step, but don't get discouraged!

Assignment

We will be using the p-limit package to help us add concurrency to our project.

  1. npm install p-limit
    
    • baseURL (the starting URL)
    • pages (our Record of page visit counts)
    • limit (a function created with pLimit(maxConcurrency))
  2. private addPageVisit(normalizedURL: string): boolean
    
    • Take a normalized URL
    • Update the pages object like you did before
    • Return true if it's the first time visiting the page, otherwise return false
  3. private async getHTML(currentURL: string): Promise<string>
    
    • Wrap the same fetch logic and error handling we had before in our new limit function and return the result:
      return await this.limit(async () => {
        // same fetch logic and error handling as before
        // return res.text() here
      });
      

    Wrapping our getHTML logic inside the limit function, gives us control over how many concurrent fetches run at once. This can be adjusted by changing the value of maxConcurrency. Keeping this low helps us avoid hammering the target server with too many requests.

  4. private async crawlPage(currentURL: string): Promise<void>
    
    • Call your new addPageVisit method, if it is not a new page return early
    • Get the HTML from the current URL using your new getHTML method
    • Get all the URLs from the response body HTML
    • Create an array of promises for each URL by calling this.crawlPage(nextURL)
    • Use Promise.all() to await all the concurrent crawl promises
    • Creates a ConcurrentCrawler instance
    • Calls and awaits the crawl() method
    • Returns the final pages Record

Tips

  • Make sure you're not crawling the same page multiple times. That's why my addPageVisit method returns a boolean: to indicate if it's the first time we've seen the page.
  • Ensure you are only crawling URLs that belong to the same domain.
  • Use Promise.all() to handle multiple concurrent requests efficiently