perf: defer athena.js and all.js footer scripts#13133
Draft
lokesh wants to merge 1 commit into
Draft
Conversation
Both scripts loaded synchronously at the end of body: athena.js (analytics, proxied to archive.org) blocked all.js on its download, and both blocked the parser for the tail of the document. Add defer to both as a pair. defer preserves document order, which matters because initAnalytics in all.js requires window.archive_analytics from athena.js at execution time (Carousel.js also calls ol_send_event_ping unguarded), so athena.js must never be deferred or made async alone. Deferred scripts run before DOMContentLoaded, so the send_pageview hook in ol.analytics.js is unaffected. This also fixes the server_ms stat: initAnalytics reads .analytics-stats-time-calculator, which is parsed after the old synchronous all.js tag executed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ky5Sc19MGPkDgbgTWWWET
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #
Performance fix: takes the two main JS payloads off the HTML parser's critical path on every page, and lets the browser schedule their fetches earlier.
Estimated performance gain
Roughly 50 ms (fast broadband) to 1 s+ (slow 3G) of parser-blocking time removed at the end of every page load, on every page. Today the parser stalls at the two script tags until athena.js (external-upstream-proxied) and all.js (~155 KB gz) download and execute; with
deferthe parser finishes the document (including the analytics div and closing markup) without waiting, and both fetches can be scheduled by the preload scanner during parse. Estimates below assume the ~155 KB gz all.js plus a typical proxied athena response; connection-level numbers are ballparks by network profile, not measurements:xychart-beta title "Est. parser-blocking script time removed per page (ms)" x-axis ["Fast broadband", "4G", "Slow 3G"] y-axis "blocked ms (estimate)" 0 --> 1200 bar [50, 400, 1100]Two caveats for honesty: (1) the tags sit at the end of
<body>, so first paint of above-the-fold content was already unblocked — the win is in DOM-complete/DOMContentLoadedtiming, tail-of-page content, and resilience to a slow archive.org analytics upstream (previously a hung athena.js held the parser andall.jshostage; now it cannot delay parsing at all). (2) Deferred scripts still execute in document order, so a slow athena still delaysall.jsexecution — full decoupling needs the #4474 follow-up. Additionally,server_msanalytics (previously always empty due to a read-before-parse bug) starts reporting real values — a measurement gain rather than a speed gain.Technical
Problem.
templates/site/footer.htmlloaded both scripts synchronously:/cdn/archive.org/athena.jsis proxied through OL's own FastAPI (openlibrary/fastapi/cdn.py) to archive.org. As a synchronous script it blocks everything after it — includingall.js(~155 KB gz: jQuery, jquery-ui, colorbox, Sentry, core OL code) — on an external upstream's response time.Why not just
async/deferon athena.js alone — the load-bearing detail: there is a real synchronous ordering dependency.initAnalytics()(js/ol.analytics.js, called atall.jsexecution — the code itself notes it "needs to be run synchronously" and warns about #4474) requireswindow.archive_analyticsto already exist, andjs/carousel/Carousel.jscallswindow.archive_analytics.ol_send_event_ping(...)unguarded. Making athena.jsasync, or deferring it whileall.jsstays synchronous, can executeall.jsfirst and break event tracking (and throw in the carousel handlers).Fix:
deferon both tags, as a pair. Deferred classic scripts execute in document order (athena → all.js) and beforeDOMContentLoaded, so:window.archive_analyticsordering contract is preserved;send_pageview({})DOMContentLoaded hook inol.analytics.jsstill fires after both have run;ol-components.jsmodule tag (already implicitly deferred) still executes after them, unchanged.Bonus correctness fix:
initAnalyticsreads$('.analytics-stats-time-calculator').data('time')for theserver_msstat, but that div sits after theall.jstag in the footer — with synchronous execution it wasn't parsed yet at read time. Withdefer, execution happens after the full parse, so the value is actually available.Testing
make test-py-uv PYTEST_ARGS="openlibrary/tests/test_templates.py"— 763 passed (template render smoke tests).pre-commit run --files openlibrary/templates/site/footer.html— all hooks pass.Manual verification steps for reviewers (devtools):
defersemantics and execute in order (athena first), beforeDOMContentLoaded._paq/athena network beacons).ol_send_event_pingconsole errors.server_msis now populated in the analytics ping (previously read before the div was parsed).Screenshot
N/A — no visual change.
Stakeholders
Part of a performance-review series; see the review report branch
claude/performance-review-top-changes-5wcs7g.🤖 Generated with Claude Code
https://claude.ai/code/session_015ky5Sc19MGPkDgbgTWWWET