So, I think this is a client-side behavior of the requirejs wrapper we use that isn't correctly preventing multiple requests for the same file/url. Repro case is checking out https://github.com/Polymer/polymer/tree/3.x-tests and polymer serve --module-resolution node --npm and using Firefox to request http://127.0.0.1:8081/test/unit/utils/resolve-url.js
Have a look at the duplicates in the network tab:

/cc @kevinpschaaf @aomarks
diff --git a/test/unit/sub/resolveurl-elements.js b/test/unit/sub/resolveurl-elements.js
index f8219309..cfb18916 100644
--- a/test/unit/sub/resolveurl-elements.js
+++ b/test/unit/sub/resolveurl-elements.js
@@ -12,7 +12,7 @@ import { html } from '../../../lib/utils/html-tag.js';
import { PolymerElement } from '../../../polymer-element.js';
import { DomModule } from '../../../lib/elements/dom-module.js';
import { Polymer } from '../../../lib/legacy/polymer-fn.js';
-import { pathFromUrl } from '../utils/resolve-url.js';
+import { pathFromUrl } from '../../../lib/utils/resolve-url.js';
const $_documentContainer = document.createElement('div');
$_documentContainer.setAttribute('style', 'display: none;');
const baseAssetPath = pathFromUrl(import.meta.url);
^ need to do this in order to run the test...
Probably related to #203, I have also noticed such kind of requests there (Firefox and Edge).
This is highest on my list.
I believe the issue is that RequireJS does not (actually I think _cannot_) resolve relative module dependency URLs the way we assumed. RequireJS always resolves dependencies relative to the document base URL (or an override in a global config). So if /index.html loads "./foo/foo.js" which then loads "./bar.js", then the absolute URL that is fetched is /bar.js, not, as I naively assumed, /foo/bar.js. This is because /foo/foo.js does not know that it's within the /foo path component (incidentally, this is what import.meta.url solves).
The reason this manifests in the particular report filed here is that resolveurl.html imports "../../polymer-element.js" and "./sub/resolveurl-elements.js". resolveurl-elements.js then imports "../../../polymer-element.js". That's all correct with ES module path resolution. However, RequireJS will _not_ dedupe those URLs, because when those two paths are resolved relative to resolveurl.html, they are indeed different paths (one is a directory higher than the other). A request is then issued for both URLs, but in fact because our HTML file was only 2 path components deep, the browser ends up requesting the same absolute URL even for the ../../../ case (since that's what happens when you traverse above the root).
So, we're going to have to change the way we emit module IDs/dependency specifiers in the AMD transform. Investigating now.
Actually my above description wasn't quite right. There is a problem with resolution of relative paths, but it is not as severe as I first thought. In general, RequireJS does resolve relative paths relative to the module ID that is requiring it, but it seems to have a bug in its normalization logic relating to relative paths reaching above the HTML base URL. Filed https://github.com/requirejs/requirejs/issues/1732 on RequireJS which describes in more detail.
Most helpful comment
This is highest on my list.
I believe the issue is that RequireJS does not (actually I think _cannot_) resolve relative module dependency URLs the way we assumed. RequireJS always resolves dependencies relative to the document base URL (or an override in a global config). So if/index.htmlloads"./foo/foo.js"which then loads"./bar.js", then the absolute URL that is fetched is/bar.js, not, as I naively assumed,/foo/bar.js. This is because/foo/foo.jsdoes not know that it's within the/foopath component (incidentally, this is whatimport.meta.urlsolves).The reason this manifests in the particular report filed here is thatresolveurl.htmlimports"../../polymer-element.js"and"./sub/resolveurl-elements.js".resolveurl-elements.jsthen imports"../../../polymer-element.js". That's all correct with ES module path resolution. However, RequireJS will _not_ dedupe those URLs, because when those two paths are resolved relative toresolveurl.html, they are indeed different paths (one is a directory higher than the other). A request is then issued for both URLs, but in fact because our HTML file was only 2 path components deep, the browser ends up requesting the same absolute URL even for the../../../case (since that's what happens when you traverse above the root).So, we're going to have to change the way we emit module IDs/dependency specifiers in the AMD transform. Investigating now.