Skip to content

network-priority/third-party-impact-mapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

third-party-impact-mapper

Ingest a HAR file and quantify the cost of every third-party origin on a page, then produce a prioritized defer / remove / self-host / facade recommendation report. Zero runtime dependencies, pure Node (>=18).

It is designed to be a shareable performance-audit asset: run it in CI, paste the Markdown into a pull request, or send the standalone HTML report to a stakeholder.

What it does

Given a HAR (HTTP Archive) export, the tool:

  • Groups every request by registrable domain (eTLD+1) and separates first-party from third-party origins.
  • Computes, per third-party origin: request count, transfer bytes, uncompressed content bytes, a by-resource-type breakdown, total wall time, an approximate blocking time, an estimated JS main-thread cost, and how early it loads.
  • Ranks origins by a documented impact score (0–100).
  • Emits a recommendation per origin (remove, defer, self-host, facade, preconnect, or review) with a short rationale and an estimated saving.
  • Renders the result as a colored terminal table, JSON, a Markdown audit report, or a self-contained HTML report with an inline SVG chart.

For background on the technique, see Third-party resource impact mapping.

How to capture a HAR

Chrome / Edge DevTools

  1. Open DevTools (F12 or Cmd/Ctrl+Shift+I) and select the Network tab.
  2. Tick Preserve log and (optionally) Disable cache for a cold-load view.
  3. Reload the page and let it finish loading.
  4. Right-click any request in the list and choose Save all as HAR with content (or click the Export HAR / download icon in the Network toolbar).
  5. Save the .har file and point the tool at it.

WebPageTest

  1. Run a test at WebPageTest.
  2. Open the result, then use Export → Export HAR (available from the result's detail view) to download the .har.

Install

This is a standalone repository. It is not published to npm.

# 1. Clone
git clone https://github.com/network-priority/third-party-impact-mapper.git
cd third-party-impact-mapper

# 2. Run directly (no dependencies to install)
node bin/third-party-impact-mapper examples/example.har

# 3. Optional: expose it on your PATH as a global command
npm link
third-party-impact-mapper examples/example.har

Usage

third-party-impact-mapper <file.har> [options]

Options

Option Description
--first-party <domain> Treat this registrable domain (eTLD+1) as first party instead of inferring it from the document URL.
--json Emit machine-readable JSON.
--md Emit a Markdown audit report (great for PRs/issues).
--html Emit a standalone, self-contained HTML report.
--top <n> Limit the ranked output to the top N origins.
--ms-per-kb <n> Main-thread estimate factor (ms of main-thread work per KB of executable JS). Default 1.5.
--sort <key> Sort by impact (default), bytes, requests, or time.
--min-bytes <n> Hide third parties transferring fewer than N bytes.
--no-color Disable ANSI colors in terminal output.
--version Print version and exit.
--help Print help and exit.

The command exits 0 on success and non-zero on bad input (missing file, unreadable file, invalid JSON, or an unusable HAR).

Examples

third-party-impact-mapper page.har
third-party-impact-mapper page.har --first-party example.com --top 10
third-party-impact-mapper page.har --md > report.md
third-party-impact-mapper page.har --html > report.html
third-party-impact-mapper page.har --json --sort bytes

A runnable sample HAR and a committed report live in the examples folder.

Output formats

Terminal (default)

A colored table ranked by impact, with a summary block (total third-party bytes, share of page weight, origin count, worst offender) and the top recommendations.

   #  Origin              Category     Reqs  Transfer  MainThr*  Early  Impact  Action
  ───────────────────────────────────────────────────────────────────────────────────
   1  YouTube Images      Video           2  125.4 KB    498 ms    46%    91.9  facade
   2  Intercom            Support         1   68.6 KB    308 ms    31%    52.9  facade
   3  Google DoubleClick  Ads             1   43.2 KB    190 ms    88%    46.2  remove

JSON (--json)

A structured object with page metadata, config (including the scoring weights), totals, and a full origins array. Ideal for CI budgets or dashboards.

{
  "tool": "third-party-impact-mapper",
  "totals": { "thirdPartyOrigins": 10, "thirdPartyBytes": 425510, "thirdPartyPct": 67.5 },
  "origins": [
    { "domain": "ytimg.com", "impact": 91.9, "recommendation": { "type": "facade" } }
  ]
}

Markdown (--md)

A shareable audit report with a summary table, a ranked table, per-origin recommendations, and the scoring methodology. See the example report.

HTML (--html)

A single self-contained .html file (all CSS inline, chart drawn as inline SVG, no external requests) that renders in light or dark mode. Safe to email or attach to a review.

The impact score formula

Each third-party origin gets an impact score from 0 to 100:

impact = 100 * (
    0.35 * (transferBytes / maxTransferBytes)
  + 0.35 * (mainThreadEst / maxMainThreadEst)
  + 0.15 * (requests      / maxRequests)
  + 0.15 * earliness
)

Each term explained:

  • Transfer bytes — weight 0.35. Bytes on the wire are the most portable proxy for network cost. Normalised against the heaviest third party on the page.
  • Main-thread estimate — weight 0.35. Estimated JS execution time (see the caveat below); usually the real interactivity bottleneck. Normalised against the worst third party.
  • Request count — weight 0.15. Each request adds connection and scheduling overhead. Normalised against the worst third party.
  • Earliness — weight 0.15. A 0..1 value where 1.0 means the origin's first request starts at page start and 0.0 means it starts at or after the reference time (page onLoad, falling back to onContentLoad or the latest observed start). Earlier resources compete with critical content, so earliness amplifies harm.

Because the first three terms are normalised against the worst third party on the page being audited, the score is relative to that page: a score of 100 means "the single worst offender on some axis." This makes scores comparable within a report, not across unrelated pages.

The main-thread estimate caveat

A HAR file contains no CPU data. It records network activity, not how long the browser's main thread spent parsing, compiling, and executing scripts. The mainThreadEst value is therefore a deliberately simple heuristic:

mainThreadEst(ms) = (uncompressed JS content bytes / 1024) * msPerKb

The default msPerKb is 1.5, a rough mid-tier figure; tune it with --ms-per-kb. Treat this number as a relative ranking signal, not a measurement. For real main-thread timings, profile with the DevTools Performance panel or Lighthouse. For the specific case of tag managers, see Measuring tag-manager blocking time.

Recommendation types explained

  • remove — analytics or ads carrying real cost that the page does not depend on functionally. Removing (or replacing with a lighter, consent-gated, or server-side alternative) reclaims the whole cost.
  • defer — a script that loads early and has a meaningful main-thread estimate. Add async/defer or load it after first paint to keep it off the critical path.
  • facade — a heavy social, video, or chat embed. Replace it with a lightweight click-to-load placeholder so its weight is paid only on interaction. See Replacing third-party embeds with facades.
  • self-host — fonts or CDN assets that add an extra connection. Self-host the asset (or at least preconnect) to remove the DNS+TCP+TLS handshake and gain caching control.
  • preconnect — an origin used early that would benefit from an early connection hint. A HAR cannot reveal existing preconnect/dns-prefetch hints, so verify before adding. See Strategic preconnect / dns-prefetch usage.
  • review — a lower-impact third party with no clear pattern from the HAR alone. Worth a manual look.

Limitations of HAR-based analysis

  • No CPU/main-thread data. See the caveat above; script execution cost is estimated, not measured.
  • async/defer is invisible. A HAR does not record how a script was requested, so "render-blocking-ish" is approximated as scripts requested early — an upper bound.
  • Existing resource hints are invisible. preconnect/dns-prefetch already in the page cannot be seen, so preconnect suggestions may be redundant — verify first.
  • Transfer sizes vary by exporter. The tool prefers Chrome's _transferSize, then bodySize (+ header bytes), then decompressed content size. Different tools populate these differently.
  • Bundled public-suffix subset. eTLD+1 grouping uses a small built-in subset of the Public Suffix List, not the full list. Common suffixes (including multi-label ones like co.uk) are covered; exotic suffixes fall back to a "last two labels" heuristic. Verify unusual domains manually.
  • Provider database is finite. Unknown origins are labelled other; you can still act on their metrics, they just lack a friendly name and category.
  • Single page per run. Only the first log.pages[0] timing context is used.

Further reading

Contributing

Issues and pull requests are welcome. The project has zero runtime dependencies by design; please keep it that way.

node --test        # run the full test suite

Please add or update node:test tests for any behavior change, and run the tool against the example HAR in each output mode before opening a pull request.

License

MIT © 2026 Network Priority. See LICENSE.


Built by Network Priority — practical guidance on browser loading mechanics and resource prioritization.

About

Turn a HAR file into a ranked third-party cost report with defer/remove/self-host/facade recommendations (terminal, JSON, Markdown, HTML).

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors