Giter Site home page Giter Site logo

Comments (10)

afcapel avatar afcapel commented on August 17, 2024

@RemcodM can you provide a minimal rails app showcasing the problem?

from turbo.

Ambient-Impact avatar Ambient-Impact commented on August 17, 2024

I've also been seeing the same re-evaluation of scripts on our Drupal site: you can trigger the re-evaluation by going to any article (e.g. the Omnipedia article) and clicking the Edit tab which gives you a 403 error; after navigating to one or two other 200 response links, you'll start seeing the console debug messages duplicate. I can try and put together a reduced test case when I have some time.

from turbo.

Ambient-Impact avatar Ambient-Impact commented on August 17, 2024

I just poked around in the Firefox dev tools a bit to try and see what's going on, and what I noticed is that the <head> element in the 200 response pages is no longer in the DOM after a visit to the 4xx page, where a different <head> element is present - I have no idea why this would be happening, but it would certainly explain the re-evaluation of scripts if it is indeed a new <head> element being added to the DOM with the <script> elements from the previous visit already present.

from turbo.

afcapel avatar afcapel commented on August 17, 2024

Yes, Turbo does this intentionally when you mark a script tag with data-turbo-track="reload". It's the only way to ensure the client runs the latest JS after a deploy.

from turbo.

afcapel avatar afcapel commented on August 17, 2024

I'm going to close this, since it seems expected behavior. But feel free to reopen with a test case if you find a bug.

from turbo.

Ambient-Impact avatar Ambient-Impact commented on August 17, 2024

@afcapel We don't mark the scripts with the attribute at all if you view source, and what occurs is still a Turbo visit, not a full page load. If this was intended behaviour, shouldn't it force a full page load instead of doing a Turbo visit?

from turbo.

afcapel avatar afcapel commented on August 17, 2024

Seems that you have a meta tag with data-turbo-track="reload"?

Screenshot 2024-02-21 at 15 50 58

I'd try removing it and see if that helps. But, also, as I said, happy to reopen the issue if you can provide a minimal reproduction.

from turbo.

Ambient-Impact avatar Ambient-Impact commented on August 17, 2024

@afcapel I just tried removing it but it had no effect. That meta tag only ever changes when navigating between the site front-end and admin sections, where the Drupal theme changes and it does force a full page load as it's supposed to, so I would have been surprised if it had an effect. I appreciate you getting back to me, and I'll see if I can throw together a minimal reproduction.

from turbo.

Ambient-Impact avatar Ambient-Impact commented on August 17, 2024

So I did some debugging in dev tools and discovered that the ErrorRenderer class always replaces the <head> outright:

documentElement.replaceChild(this.newHead, head)

This probably makes sense for some apps, but in our cases it seems like it's creating a weird in between state where a full page load has not occurred so scripts executed previously still linger in the JavaScript environment but the scripts get re-evaluated by ErrorRenderer:

this.activateScriptElements()

In our Drupal app, the 4xx pages contain the same linked JavaScript files as most other pages, so this means Turbo re-evaluates all the same JavaScript files on an error response.

The full stack trace:

replaceHeadAndBody (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#3719)
render (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#3713)
renderSnapshot (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#1535)
render (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#1495)
renderError (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#4985)
loadResponse (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2506)
render (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2710)
loadResponse (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2495)
visitRequestFailedWithStatusCode (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2780)
recordResponse (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2482)
requestFailedWithResponse (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2616)
receive (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#856)
perform (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#831)
issueRequest (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2458)
visitStarted (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2751)
start (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2408)
startVisit (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#3290)
visitProposedToLocation (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#2742)
visitProposedToLocation (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#5337)
proposeVisit (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#3280)
visit (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#5201)
followedLinkToLocation (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#5326)
clickBubbled (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#1635)
clickCaptured (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#1624)
start (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#1610)
start (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#5155)
start (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#5602)
<anonymous> (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#6573)
<anonymous> (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#8)
<anonymous> (https://omnipedia.ddev.site/modules/contrib/refreshless/modules/refreshless_turbo/vendor/%40hotwired/turbo/dist/turbo.es2017-umd.js?v=8.0.2#9)

Using that clue, I took a look at Visit.loadResponse():

await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this)

and replaced that line with:

await this.renderPageSnapshot(PageSnapshot.fromHTMLString(responseHTML), false);

reloaded the page, and bingo, it no longer re-evaluates all of our JavaScript no matter how many 4xx error pages I visit. It's probably not the best way to do this and may break stuff I'm not aware of.


Given that, is there a way to configure Turbo to use the normal renderer rather than the error renderer?

from turbo.

fschwahn avatar fschwahn commented on August 17, 2024

@afcapel we are running into the same issue: we are rendering our error pages in the full application layout (ie. also the complete <head> with all javascript files) from our normal pages. This leads to our entire javascript being loaded twice (eg. all click handlers are there 2 times, etc.)

I tried following your advice and removed all data-turbo-track attributes, but this does not make a difference. It still double loads the Javascript code:
image

I don't think this problem is related to data-turbo-track. Do you have any pointers how to create a minimal test case? I believe it should be simple (just a JS file which is loaded in both the normal visit and the error visit which sets a global const should be sufficient).

I looked if I can somehow force a hard-reload on error pages, but I couldn't find a solution which worked in all cases:

  • <meta name="turbo-visit-control" content="reload"> does not seem to work as the ErrorRenderer does not seem to pick it up
  • using turbo:before-fetch-response-event was tricky due to prefetching

It would be great if I could indicate in a response header that a full page visit should happen, but I haven't found such a thing.

from turbo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.