Search code examples
javascriptuserscripts

How do I prevent the browser from preloading the <video> tag?


I have written a user script extension for Chrome with JavaScript in order to prevent video and audio tags from downloading automatically on pageload

This is the code:

var videoTags = document.getElementsByTagName("Video");
var i;
for(i=0; i<videoTags.length; i++)
{
    videoTags[i].setAttribute("preload", "none");
    videoTags[i].removeAttribute("autoplay");
}

var audioTags = document.getElementsByTagName("audio");
var i;
for(i=0; i<audioTags.length; i++)
{
    audioTags[i].setAttribute("preload", "none");
    audioTags[i].removeAttribute("autoplay");
}

And this is the manifest.json file:

   {
      "content_scripts": [ {
      "exclude_globs": [  ],
      "exclude_matches": [  ],
      "include_globs": [ "*" ],
      "js": [ "script.js" ],
      "matches": [ "http://*/*", "https://*/*" ],
      "run_at": "document_start"
   } ],
      "converted_from_user_script": true,
      "description": "",
      "key": "an2xaeZJluPfnpmcsHPXI4aajQPL1cBm5C2kKjaQwXA=",
      "name": "test.user.js",
      "version": "1.0"
  }

The problem is that my script runs after a moment and until then the browser (Chrome) downloads a part of video/audio file.


Solution

  • One dirty solution that seems to work is to use a MutationObserver from your userscript, once you're sure it does run at document-start.

    This TamperMonkey script does work for me :

    // ==UserScript==
    // @name         Block videos preloading
    // @include      *
    // @run-at document-start
    // ==/UserScript==
    
    (function() {
      'use strict';
      var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
          var nodes = mutation.addedNodes;
          for (var i = 0; i < nodes.length; i++) {
            if (nodes[i].nodeName == "VIDEO") {
              nodes[i].setAttribute('preload', 'none');
              nodes[i].removeAttribute('autoplay');
            }
          }
        })
      });
      observer.observe(document.documentElement, {
        childList: true,
        subtree: true
      });
    
    })();
    

    You may want to call observer.disconnect() on DOMContentLoaded, if you're not expecting other video elements for being inserted afterwards by scripts.