External image, CSS, and JavaScript file sizes are not added to the byte total when you measure HTML page weight — an HTML page weight analyzer counts only the pasted response body, so each external file contributes just the characters used by its tag and URL. That distinction matters because the analyzer never fetches your page, never executes the markup, and never downloads the referenced files; it parses the text you hand it inside a detached template fragment and reports the UTF-8 byte length of that text plus a structured breakdown of what fills it. Linked stylesheets, scripts, images, frames, preloads, and media references are recognized by their attributes and shown in an inventory, but the inventory lists URLs, not file sizes. Googlebot and the Web Rendering Service may later fetch each referenced resource with its own per-URL allowance, and that fetch is governed by separate limits. Inside the analyzer, an external reference is just characters in the HTML source. To confirm this in your own workflow, open the HTML Page Weight Analyzer, paste an unmodified HTML response, and check that the external-resource inventory lists URLs while the headline byte total reflects only the pasted body.

are external image css and javascript file sizes included when i use html page weight html page size analyzer
are external image css and javascript file sizes included when i use html page weight html page size analyzer

What the HTML Page Weight Analyzer Actually Counts

The analyzer runs entirely in your browser and reads only what you paste. It measures the original input as UTF-8 bytes using the browser's TextEncoder API, counts Unicode code points, and parses a detached template fragment that never attaches to your live document. That fragment is never executed, so scripts do not run, forms do not submit, and image, iframe, stylesheet, or script URLs are never requested. Everything you see in the result is text the analyzer pulled out of the pasted source.

Within that pasted source, the analyzer distinguishes three groups of bytes. Inline script and style text are extracted from each <script> and <style> element and reported as their own byte totals and percentage shares of the body. Embedded data URI payloads, anything that begins with data: in a supported direct resource attribute, are counted once as they appear in the source, without re-decoding Base64 and adding the decoded bytes again, because that would double-count bytes already present in the markup. Finally, a bounded inventory of external resource references is built from the src, href, and other direct attributes the parser recognizes.

Why External Resource Sizes Stay Out of the Total

An external stylesheet, script, image, frame, preload, or media reference contributes only the characters that appear in the HTML response. The analyzer lists these references so you can tell the difference between a heavy document and a document that merely points to heavy files, but it never downloads those files or claims to know their sizes. Googlebot and the Web Rendering Service may fetch referenced resources separately, and each fetch is governed by its own per-URL allowance rather than being folded into the parent document's measurement.

The parser uses the browser's native HTML tokenizer inside a detached template, which matters for raw-text boundaries such as <textarea>, <title>, <script>, and <style> that a regular expression can misread. Nested template content remains inert and outside the resource inventory. Counts and displayed values are bounded so a very large pasted document cannot create an unbounded result view, and a strict input limit plus a shared element cap protect the main thread from accidental full-site dumps or adversarial markup. The tool is not a network waterfall, compression calculator, or Core Web Vitals test; it does not know gzip or Brotli transfer size, server headers, cache behavior, late client-side DOM mutations, resource response sizes, execution cost, rendering cost, or what Google actually indexed.

What appears in the pasted HTMLCounted toward the body byte total?What the analyzer actually does
Inline <script> textYesMeasured as UTF-8 bytes and reported as a share of the body
Inline <style> textYesMeasured as UTF-8 bytes and reported as a share of the body
data: URIs in supported attributesYesCounted once, exactly as the attribute value appears in the source
<script src="..."> URL textYes (URL characters only)Listed by URL, the file is never downloaded
<link rel="stylesheet" href="...">Yes (URL characters only)Identified by the rel token and listed without a payload
<img src="external.jpg">Yes (URL characters only)Inventoried as a reference, no transfer size added
External CSS, JS, or image file payloadNoThe file is never fetched and no size is guessed
HTTP response headersNoNot present in the pasted body, cannot be measured

How to Measure Your HTML Body Weight

  1. Paste the original uncompressed HTML response body, captured from View Source or an authorized curl response rather than a mutated Elements panel.
  2. Run the analysis and review the total UTF-8 bytes, the 2 MB reference position, inline script and style shares, data URI weight, and the bounded external-resource inventory.
  3. Fix the largest source-level hotspot you can attribute to the pasted source, then remeasure the deployed response and remember that HTTP headers and separately fetched resources remain outside this pasted-body calculation.

The View Source view, a saved response body, or an authorized curl capture is a better input than the Elements panel because JavaScript can mutate the live DOM after the response arrives, which inserts changes that were not in the server output and drops source details that were. If your server varies its response by user agent, locale, authentication, or device, test the representative response you actually intend to ship rather than averaging across anonymous variants.

Reading the Inline, Data URI, and External Reference Breakdown

Byte size is different from JavaScript string length. A browser string counts UTF-16 code units, while an HTML response is normally transferred as encoded bytes, and the two diverge quickly outside ASCII. ASCII characters usually occupy one UTF-8 byte, but accented letters, CJK text, and emoji occupy more. For a worked example, take a 1,000-character string made entirely of ASCII letters: byte_total = 1,000 × 1 = 1,000 UTF-8 bytes. Now take the same string but replace 100 of those letters with accented characters, where each accented character takes two bytes: byte_total = (1,000 − 100) × 1 + 100 × 2 = 900 + 200 = 1,100 UTF-8 bytes. The analyzer applies that same encoding arithmetic across the entire paste, so the headline total reflects transferred bytes rather than a character count that would mislead once the document includes any non-ASCII content.

The 2 MB reference shown beside your body total is a transparent decimal 2,000,000-byte comparison, deliberately conservative rather than a certification. Google's current documentation states that Googlebot crawls the first 2 MB of a supported file and stops fetching at the cutoff, and that the limit applies to uncompressed data. A later technical explanation adds that HTTP headers consume part of the per-URL allowance. Because the analyzer receives only a pasted response body, it cannot measure the real response headers or prove exactly where Googlebot will stop, so the interface labels 2 MB as a decimal 2,000,000-byte body reference and shows remaining bytes below that line or overage above it while keeping the header caveat visible.

Inline code does count toward the document body. The analyzer measures the text inside each inline script and style element as UTF-8 and reports both byte totals and percentages of the complete source. External script elements are listed by src instead. Stylesheet and preload links are identified through rel tokens, and common direct image, media, and frame attributes are inventoried. A srcset value is preserved as one declaration because data URLs make naive comma splitting unsafe, which means a stray comma inside a data URI cannot accidentally multiply the reference count.

Layer Googlebot handles separatelyWhere the 2 MB allowance applies
HTML response bodyCounts toward the first 2 MB of the response
HTTP response headersConsume part of the per-URL allowance alongside the body
External CSS or JS filesEach fetched with its own per-URL allowance
External images and mediaEach fetched with its own per-URL allowance

Common Hotspots That Quietly Inflate Body Weight

Treat the breakdown as a debugging map rather than a score. Large inline script bytes may point to serialized application state, duplicated hydration data, or embedded libraries that could move to cacheable external files. Large inline style bytes may indicate repeated critical CSS that should be consolidated or trimmed. Large data URI totals can reveal Base64 images or fonts embedded directly in markup, which are convenient but expensive; a single high-resolution Base64 image can add tens or hundreds of kilobytes that would shrink dramatically once served as a separate, cacheable file. A long external-resource inventory may reveal duplicate tags, though reference count alone is not a performance signal.

After finding a hotspot, make the smallest truthful change and remeasure the real response. Move appropriate code to cacheable external files, remove duplicated serialized data, avoid embedding large binary payloads in data URIs, and place critical metadata and content early in the response. Then verify the deployed bytes, response headers, rendered page, and indexing evidence through DevTools, curl, and Search Console rather than assuming a smaller number guarantees crawling, indexing, or ranking. Google's documented limits can also change over time, so treat the source link and reference date on the analyzer interface as more authoritative than any single byte threshold. Google's March 2026 update to the Inside Googlebot post is one place to watch for the current wording.