Deferred loading

Improve performing by delaying the loading of Pragmatic drag and drop.

If you want to, you can defer the loading of Pragmatic drag and drop (and other packages) at a point after initial page load using dynamic imports.

Deferring the loading of drag and drop behavior has some advantages:

  • Faster initial page loads
  • The ability to load in drag and drop behavior when it is needed, rather than in the critical bundle

There are also some drawbacks:

  • Additional complexity as you are no longer simply importing a module and using it
  • Potential to miss an interaction: let's say a user starts trying to drag before @atlaskit/pragmatic-drag-and-drop is loaded, then the user would not be able to perform a drag operation. You can add some instrumentation to detect when these 'misses' occur. In our initial observations we have found the 'readiness' gap to be extremely small.

Given @atlaskit/pragmatic-drag-and-drop is tiny, you will already get great performance by simply using the library. Deferred loading unlocks another level of wins.

Dynamic imports

Modern bundles often support dynamic imports; which sounds scary, but in user land it is straightforward:

import('module-name').then((module) => {
    // use the module
});

// or using await
const module = await import('@atlaskit/pragmatic-drag-and-drop/element');

You can use dynamic imports to do things like deferring the import of a module until a react useEffect.

import React, { useEffect } from 'react';

function Card() {
  const ref = useRef<HTMLDivElement | null>(null);

  useEffect(() => {
    const controller = new AbortController();

    (async () => {
      const { draggable } = await import('@atlaskit/pragmatic-drag-and-drop/element/adapter');
      if (controller.signal.aborted) {
        return;
      }
      const el = ref.current;
      if(!el) {
        return;
      }

      const cleanup = draggable({
        element: el,
      });
      controller.signal.addEventListener('abort', cleanup, { once: true });
    })();

    return () => {
      controller.abort();
    };
  }, []);

  return <div ref={ref}>Drag me<div>
});

For Atlassian's we recommend using the new @atlaskit/react-async.

Other environment specific techniques:

Was this page helpful?
We use this feedback to improve our documentation.
Navigated to Deferred loading