diff --git a/docs/guides/options.md b/docs/guides/options.md
index b86cfc112e..89dda7782d 100644
--- a/docs/guides/options.md
+++ b/docs/guides/options.md
@@ -58,6 +58,7 @@
     * [nativeAudioTracks](#nativeaudiotracks)
     * [nativeTextTracks](#nativetexttracks)
     * [nativeVideoTracks](#nativevideotracks)
+    * [preloadTextTracks](#preloadtexttracks)
 
 ## Standard `<video>` Element Options
 
@@ -607,6 +608,14 @@ Can be set to `false` to force emulation of text tracks instead of native suppor
 
 Can be set to `false` to disable native video track support. Most commonly used with [videojs-contrib-hls][videojs-contrib-hls].
 
+#### `preloadTextTracks`
+
+> Type: `boolean`
+
+Can be set to `false` to delay loading of non-active text tracks until use. This can cause a short delay when switching captions during which there may be missing captions.
+
+The default behavior is to preload all text tracks.
+
 [plugins]: /docs/guides/plugins.md
 
 [languages]: /docs/guides/languages.md
diff --git a/src/js/tech/tech.js b/src/js/tech/tech.js
index 41a13b22ab..f1b8dc43d1 100644
--- a/src/js/tech/tech.js
+++ b/src/js/tech/tech.js
@@ -141,6 +141,8 @@ class Tech extends Component {
       this.emulateTextTracks();
     }
 
+    this.preloadTextTracks = options.preloadTextTracks !== false;
+
     this.autoRemoteTextTracks_ = new TRACK_TYPES.ALL.text.ListClass();
 
     this.initTrackListeners();
diff --git a/src/js/tracks/text-track.js b/src/js/tracks/text-track.js
index ea05e680a1..fe96496719 100644
--- a/src/js/tracks/text-track.js
+++ b/src/js/tracks/text-track.js
@@ -172,6 +172,8 @@ class TextTrack extends Track {
     this.cues_ = [];
     this.activeCues_ = [];
 
+    this.preload_ = this.tech_.preloadTextTracks !== false;
+
     const cues = new TextTrackCueList(this.cues_);
     const activeCues = new TextTrackCueList(this.activeCues_);
     let changed = false;
@@ -229,6 +231,10 @@ class TextTrack extends Track {
             return;
           }
           mode = newMode;
+          if (!this.preload_ && mode !== 'disabled' && this.cues.length === 0) {
+            // On-demand load.
+            loadTrack(this.src, this);
+          }
           if (mode !== 'disabled') {
             this.tech_.ready(() => {
               this.tech_.on('timeupdate', timeupdateHandler);
@@ -324,7 +330,14 @@ class TextTrack extends Track {
 
     if (settings.src) {
       this.src = settings.src;
-      loadTrack(settings.src, this);
+      if (!this.preload_) {
+        // Tracks will load on-demand.
+        // Act like we're loaded for other purposes.
+        this.loaded_ = true;
+      }
+      if (this.preload_ || default_ || (settings.kind !== 'subtitles' && settings.kind !== 'captions')) {
+        loadTrack(this.src, this);
+      }
     } else {
       this.loaded_ = true;
     }