Skip to content

Commit 12ca7d9

Browse files
committed
adding a small entry about ajax code splitting
1 parent 165432f commit 12ca7d9

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

frontend.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Optimizing
5858

5959
* :doc:`Versioning (and the entrypoints.json/manifest.json files) </frontend/encore/versioning>`
6060
* :doc:`Using a CDN </frontend/encore/cdn>`
61+
* :doc:`/frontend/encore/code-splitting`
6162
* :doc:`/frontend/encore/split-chunks`
6263
* :doc:`Creating a "Shared" entry for re-used modules </frontend/encore/shared-entry>`
6364
* :doc:`/frontend/encore/url-loader`

frontend/encore/code-splitting.rst

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Async Code Splitting
2+
====================
3+
4+
When you require/import a JavaScript or CSS module, Webpack compiles that code into
5+
the final JavaScript or CSS file. Usually, that's exactly what you want. But what
6+
if you only need to use a piece of code under certain conditions? For example,
7+
what if you want to use `video.js`_ to play a video, but only once a user has
8+
clicked a link:
9+
10+
.. code-block:: javascript
11+
12+
// assets/js/app.js
13+
14+
import $ from 'jquery';
15+
// a fictional "large" module (e.g. it imports video.js internally)
16+
import VideoPlayer from './components/VideoPlayer';
17+
18+
$('.js-open-video').on('click', function() {
19+
// use the larger VideoPlayer module
20+
const player = new VideoPlayer('some-element');
21+
});
22+
23+
In this example, the VidePlayer module and everything it imports will be packaged
24+
into the final, built JavaScript file, even though it may not be very common for
25+
someone to actually need it. A better solution is to use `dynamic imports`_: load
26+
the code via AJAX when it's needed:
27+
28+
.. code-block:: javascript
29+
30+
// assets/js/app.js
31+
32+
import $ from 'jquery';
33+
34+
$('.js-open-video').on('click', function() {
35+
// you could start a loading animation here
36+
37+
// use import() as a function - it returns a Promise
38+
import('./components/VideoPlayer').then(({ default: VideoPlayer }) => {
39+
// you could stop a loading animation here
40+
41+
// use the larger VideoPlayer module
42+
const player = new VideoPlayer('some-element');
43+
44+
}).catch(error => 'An error occurred while loading the component');
45+
});
46+
47+
By using ``import()`` like a function, the module will be downloaded async and
48+
the ``.then()`` callback will be executed when it's finished. The ``VideoPlayer``
49+
argument to the callback will be the loaded module. In other words, it works like
50+
normal AJAX calls! Behind the scenes, Webpack will package the ``VideoPlayer`` module
51+
into a separate file (e.g. ``0.js``) so it can be downloaded. All the details are
52+
handled for you.
53+
54+
The ``{ default: VideoPlayer }`` part may look strange. When using the async
55+
import, your ``.then()`` callback is passed an object, where the *actual* module
56+
is on a ``.default`` key. There are reasons why this is done, but it does look
57+
quirky. The ``{ default: VideoPlayer }`` code makes sure that the ``VideoPlayer``
58+
module we want is read from this ``.default`` property.
59+
60+
For more details and configuration options, see `dynamic imports`_ on Webpack's
61+
documentation.
62+
63+
.. _`video.js`: https://videojs.com/
64+
.. _`dynamic imports`: https://webpack.js.org/guides/code-splitting/#dynamic-imports

0 commit comments

Comments
 (0)