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

Preload extension: hx-boost, no side effects, HX-Preloaded header, form support, tests and JSDocs #106

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

marisst
Copy link

@marisst marisst commented Nov 5, 2024

Major update of the preload extension.

  • Hx-boost element preloading with correct request headers
  • No side-effects e.g. like visible loading indicators while preloading data
  • HX-Preload header
  • Form element smart preloading with alternated values
    • Currently <form hx-get="/link" preload> will preload the form with as-is values whenever user clicks or hovers (if preload="mouseover") on any of the forms elements.
    • However, if user clicks or hovers over <input type="radio">, <input type="checkbox"> or <select> elements, it is more likely that the value of those elements will be changed first and then the form submitted.
    • This update includes smarter preloading of these three input elements, sending preload request with the alternated values. Additionally, <form method="get" target="/link" preload> will also be preloaded. Elements other than radio buttons, checkboxes, select elements and submit buttons are not triggering form preloading.
    • Issue addressed: Ajax sending parameters htmx#105
  • Tests
    • Currently extension doesn't have any tests
    • Added 39 tests covering current and added functionality
    • Two issues were found and fixed during this process
      • <button hx-get="/link" hx-ext="preload" preload>Button</button> is not preloaded in current version, but it is preloaded with the change. The reason is that the extension currently does not consider the element in which the extension is registered among the pool of nodes it initializes.
      • touchstart event listener was added to node as an alternative to mousedown and mouseover events for touchscreens, but it was not working because the correct node.preloadState was not set when calling load(node)
  • JSDocs and improved code readability
    • JSDocs added to all functions
    • Code reorganized in top-down manner. Currently the main part of the code is on the bottom and the least important utility functions are on top, making it hard to read it. I replaced const funct = function(){} with function funct() {} declarations, which allow to change the order.
    • The node.preloadState values are currently confusing. PAUSE is used for when node is initialized, READY for when data is loading and DONE for when loading is complete. I have renamed PAUSE to READY, READY to LOADING and kept DONE. I also added a new state TIMEOUT used to check that user hovers over an element for at least 100ms before it starts loading.
  • preload="always" documentation and config flexibility
    • added documentation for preload="always" property
    • enabled use of preload="always", currently it can only be used together with preload mode e.g. preload="always mousedown"

Documentation is updated in a corresponding pull request in the main xtmx repository. bigskysoftware/htmx#3001

Copy link

netlify bot commented Nov 5, 2024

Deploy Preview for htmx-extensions canceled.

Name Link
🔨 Latest commit 0e4802c
🔍 Latest deploy log https://app.netlify.com/sites/htmx-extensions/deploys/674aff2182188500089f3873

@untitaker
Copy link

this patch is working great for me in combination with hx-boost. essentially it "just works" while the main branch version doesn't. however, the loading indicator is visible when pages are being preloaded.

@ALameLlama
Copy link

Looks greats so far but +1 on the indicators, I don't believe these should be visible for preloads.

@marisst
Copy link
Author

marisst commented Nov 11, 2024

@untitaker and @ALameLlama, thank you for reviewing my pull request. I agree with you. I implemented a change which prevents loading indicators to be shown while preloading nodes. I have also added a "HX-Preload": "true" header to all preload requests.

src/preload/preload.js Outdated Show resolved Hide resolved
@marisst marisst changed the title Preload extension: hx-boost and form element support, tests and JSDocs Preload extension: hx-boost, no side effects, HX-Preloaded header, form support, tests and JSDocs Nov 12, 2024
@yoonthegoon
Copy link

yoonthegoon commented Nov 21, 2024

EDIT:

ALameLlama helped pointing out I was missing Cache-Control from my response headers. All is good 😌


I hate to be the bearer of bad news, but I'm still getting two requests and the latter not being cached.
I attached screenshots on two browsers I've tested on.
I'm on macOS 15.0 24A335 arm64.

I suspect it's due to the additional HX-Preloaded header, as that's the only difference between the two requests.

GET /blog/inquit-incepta HTTP/1.1
Host: 127.0.0.1:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:132.0) Gecko/20100101 Firefox/132.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br, zstd
HX-Request: true
HX-Current-URL: http://127.0.0.1:3000/blog
HX-Boosted: true
- HX-Preloaded: true
Sec-GPC: 1
Connection: keep-alive
Referer: http://127.0.0.1:3000/blog
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
DNT: 1
Priority: u=0

Unfortunately, I wasn't able to modify your code to try removing the added header without breaking the way the script functioned.
I'll see if I can try again on a different operating system when I get the chance.

I left both screenshots filtered just to show other requests were being cached.

Zen Browser
1.0.1-a.19 (Firefox 132.0.1) (aarch64)

image

Safari
Version 18.0 (20619.1.26.31.6)

image

@ALameLlama
Copy link

What do your response headers look like? I have a feeling you're missing the Cache-Control.

https://htmx.org/extensions/preload/

Preloaded responses will only be cached in the browser if the response headers allow it. For example, the response header Cache-Control: private, max-age=60 allows the browser to cache the response, whereas Cache-Control: no-cache prevents it.

The new request header HX-Preloaded shouldn't have any effect on it. just give the BE more information about what triggered the request.

@yoonthegoon
Copy link

Oof I'm silly. I just added the Cache-Control header and it's all good now. (I blame axum and askama_axum for making adding that in so difficult :P )

Here was my old response headers.

HTTP/1.1 200 OK
content-type: text/html; charset=utf-8
content-length: 5740
- date: Thu, 21 Nov 2024 04:22:51 GMT
+ date: Thu, 21 Nov 2024 04:22:52 GMT

Also I tried the preload.js in 6944833 (where the request headers are exactly the same) and I still wasn't caching the second, so that clearly wasn't it.

@marisst
Copy link
Author

marisst commented Nov 27, 2024

It would be great to get somebody review this pull request. Merging it would allow us to close 10 issues, which is a lot given there are only roughly 30 issues reported in this repository.

@Telroshan seems that the most recent PRs in the repo have been reviewed by you. Have you had a chance or are you planning to look at this one? Do you have any worries about it? If helpful, we can connect.

The author of the original preload extension is @benpate bigskysoftware/htmx#273, and it was approved by @1cg. Maybe we can get some inputs from the original authors if they are still active in this repo?

@Telroshan
Copy link
Collaborator

Hey @marisst , first of all thanks for your work. Life's currently a bit hectic so I haven't had the chance yet to sit down and review this PR as it should be. Can't guarantee a date that I'll look into it, but I hope to do it in the upcoming weeks.
I know this can be frustrating, but rest assured that we'll get there eventually!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants