Menu
Menu Sheet Overlay
Search
Search Sheet

Download Management

    What is Download Management?

    The Google Lighthouse Time To Interactive metric is affected by the number of downloads that are in progress at any given time. The SDK contains a Download Manager that can limit the number of simultaneous downloads, and prioritize downloads so that more important assets are fetched sooner. This is especially useful on slower mobile networks, where attempting to download a large number of assets at the same time can result in all of them competing for bandwidth, and downloading slowly.

    How does the Download Manager work?

    The Download Manager uses the Service Worker installed as part of the PWA. The Mobify service worker code provided in the SDK includes a component that intercepts all requests generated by the PWA, including scripts, images, fonts, as well as any fetch requests started by the PWA code.

    The Download Manager only operates on browsers that support service workers. If the PWA is run on a browser that doesn’t support service workers, then the Download Manager will do nothing (configuration will succeed, but have no effect).

    The service worker keeps track of the number of current downloads (downloads that are in progress). It can be configured to set a maximum number of downloads. If a new request is made when the number of current downloads is at the maximum, that new request will be delayed until a current download completes.

    The worker will also prioritize delayed downloads. There are four priorities that can be assigned to a request: high, normal, low and unthrottled. Requests with the unthrottled priority will never be delayed, even if the maximum number of downloads has been reached. Other requests that have been delayed are started in priority order, from high through normal and low.

    You can configure the priorities assigned to requests by providing a list of Javascript regular expression strings to match the URLs of requests, along with the priority to be assigned to requests that match the regular expressions.

    Enabling and configuring the Download Manager

    Your code controls and configures the Download Manager via the Performance Manager. Here’s an example of how you would enable download management in the main.jsx file of your PWA:

    import {PerformanceManager} from 'progressive-web-sdk/dist/utils/performance-manager'
    
    const performanceManager = PerformanceManager.getManager()
    performanceManager.configureDownloads(
        {
            // Set the maximum number of downloads to 2
            maxDownloads: 2,
            priorityFilters: [
                {
                    // Set all our images to low priority
                    regexp: '.+\\.[jpg|jpeg|gif|png|webp].*',
                    priority: PerformanceManager.LOW
                },
                {
                    // Never throttle this important asset
                    regexp: '.+importantConfigData.json.*',
                    priority: PerformanceManager.UNTHROTTLED 
                }
            ]
        }
    ).then(
        () => {
            // Download management is set up: start rendering...
            render(<Router store={store} />, rootEl)
        }
    )
    

    The configureDownloads method returns a Promise that resolves when configuration is complete (when the service worker is installed and active). You may choose to wait until this Promise resolves before starting PWA rendering, as shown in the example above.

    If you are also enabling task-splitting, you should do that before configuring the Download Manager. For example:

    import {PerformanceManager} from 'progressive-web-sdk/dist/utils/performance-manager'
    
    const performanceManager = PerformanceManager.getManager()
    
    performanceManager.setTaskSplitting(true)
        .then(() => performanceManager.configureDownloads({maxDownloads: 2}))
        .then(
            () => {
                // Download management is set up: start rendering...
                render(<Router store={store} />, rootEl)
            }
        )