Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add preload Link header only to HTML pages #1500

Merged
merged 3 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 29 additions & 34 deletions weasyl/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,52 +298,47 @@ def cleanup(request):
return database_session_cleanup_tween


def _generate_http2_server_push_headers():
"""
Generates the Link headers to load HTTP/2 Server Push resources which are needed on each pageload. Written
as a separate function to only execute this code a single time, since we just need to generate this each
time the code is relaunched (e.g., each time the web workers are kicked to a new version of the code).

A component of ``http2_server_push_tween_factory``
:return: An ASCII encoded string to be loaded into the Link header set inside of ``http2_server_push_tween_factory``
"""
css_preload = [
'<' + item + '>; rel=preload; as=style' for item in [
d.get_resource_path('css/site.css'),
# The value of the `Link` header that will be set in the `preload_tween_factory` function below.
# Only constructed once on application load; not affected by `WEASYL_RELOAD_ASSETS`.
_WEBPAGE_PRELOADS_LINK = ", ".join([
# CSS
*(
f"<{d.get_resource_path(item)}>;rel=preload;as=style" for item in [
"css/site.css",
]
]
),

js_preload = [
'<' + item + '>; rel=preload; as=script' for item in [
d.get_resource_path('js/jquery-2.2.4.min.js'),
d.get_resource_path('js/scripts.js'),
# JavaScript
*(
f"<{d.get_resource_path(item)}>;rel=preload;as=script" for item in [
"js/jquery-2.2.4.min.js",
"js/scripts.js",
]
]
),

esm_preload = [
'<' + item + '>; rel=modulepreload' for item in [
d.get_resource_path('js/main.js'),
# ES modules
*(
f"<{d.get_resource_path(item)}>;rel=modulepreload" for item in [
"js/main.js",
]
]

return ", ".join(css_preload + js_preload + esm_preload)
),
])


# Part of the `Link` header that will be set in the `http2_server_push_tween_factory` function, below
HTTP2_LINK_HEADER_PRELOADS = _generate_http2_server_push_headers()


def http2_server_push_tween_factory(handler, registry):
def preload_tween_factory(handler, registry):
"""
Add the 'Link' header to outgoing responses to HTTP/2 Server Push render-blocking resources
Add the `Link` header to outgoing responses to preload resources needed on every webpage, which is served ahead of time by Cloudflare as an HTTP 103 Early Hints message.
"""
def http2_server_push(request):
def preload_tween(request):
resp = handler(request)

# Combined HTTP/2 headers indicating which resources to server push
resp.headers['Link'] = HTTP2_LINK_HEADER_PRELOADS
content_type = resp.headers.get('Content-Type')

if content_type is not None and content_type.startswith("text/html"):
resp.headers['Link'] = _WEBPAGE_PRELOADS_LINK

return resp
return http2_server_push
return preload_tween


# Properties and methods to enhance the pyramid `request`.
Expand Down
2 changes: 1 addition & 1 deletion weasyl/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
config.add_tween("weasyl.middleware.db_timer_tween_factory")
config.add_tween("weasyl.middleware.cache_clear_tween_factory")
config.add_tween("weasyl.middleware.database_session_cleanup_tween_factory")
config.add_tween("weasyl.middleware.http2_server_push_tween_factory")
config.add_tween("weasyl.middleware.preload_tween_factory")
config.add_tween("weasyl.middleware.query_debug_tween_factory")
config.add_tween("pyramid.tweens.excview_tween_factory") # Required to catch exceptions thrown in tweens.
config.add_tween("weasyl.middleware.utf8_path_tween_factory")
Expand Down
Loading