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

Handle <script async> transparently #1099

Closed
wants to merge 1 commit into from

Conversation

squadette
Copy link
Contributor

@squadette squadette commented Jun 8, 2018

I believe that this commit fixes #290, transparently handling <script async> tag. If the document was already loaded, the DOMContentLoaded event handler no longer fires, so we just execute it directly, the same way as jQuery does in $.ready().


This change is Reviewable

@squadette squadette changed the title Script async Handle <script async> transparently Jun 8, 2018
@coveralls
Copy link

coveralls commented Jun 8, 2018

Coverage Status

Coverage remained the same at ?% when pulling d164e75 on squadette:script-async into e86090f on shakacode:master.

This handles <script async> transparently
@justin808
Copy link
Member

Possibly related links:

@nateberkopec, any chance that you can help us review this one?

@alexeyMohnatkin can you provide more examples of this and documentation?

Can you demonstrate the fix working and not working? Maybe modify the spec/dummy app and add the async tags?

How about https://github.com/shakacode/react-webpack-rails-tutorial? Can you demonstrate what would be the effect with and without this little change?


Reviewed 2 of 2 files at r1.
Review status: all files reviewed, 1 unresolved discussion (waiting on @squadette)


node_package/src/clientStartup.js, line 214 at r1 (raw file):

            'NOT USING TURBOLINKS: DOMContentLoaded event, calling reactOnRailsPageLoaded',
          );
          reactOnRailsPageLoaded();

@alexeyMohnatkin is this related? an example? https://github.com/turbolinks/turbolinks/pull/274/files

Previous code always waited for the event.

Any more comments on why this fix works?


Comments from Reviewable

@squadette
Copy link
Contributor Author

hi,

first, you're summoning a random guy who has similar last name to mine. :)

second, yes, all three turbolinks links are trying to solve the same issue. (And that issue is also solved by jQuery's ready() function: https://github.com/jquery/jquery/blob/bd984f0ee2cf40107a669d80d92566b8625b1e6b/src/core/ready.js#L67).

third, I believe that this issue needs to be fixed separately for turbolinks and non-turbolinks cases. I don't use turbolinks so I'm not trying to even try handling it: looks like they should solve it on their side (if needed).

fourth, it's quite hard to demonstrate that it's working, because you cannot make sure that async script tag finishes execution reliably before or reliable after DOMContentLoaded event fires.

We know that if you add async tag to current react_on_rails-based project the page does not work (so, nobody probably does that). We know that this change does not break ordinary script tag. Seems that the only way to check if async tag works is to test it in real world.

...to be continued.

@justin808
Copy link
Member

@squadette Looking forward to a heads up on this one. I just want to be sure we don't break any existing code.

@@ -196,6 +196,27 @@ export function clientStartup(context) {

debugTurbolinks('Adding DOMContentLoaded event to install event listeners.');

window.setTimeout(() => {
if (!turbolinksInstalled() || !turbolinksSupported()) {
if (document.readyState === 'complete' ||

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this break if the readyState is interactive?

@squadette
Copy link
Contributor Author

squadette commented Jun 21, 2018 via email

@justin808
Copy link
Member

@nateberkopec Do you feel OK with @squadette's suggestion?

@squadette, is there any chance that we could make an adjustment to the /spec/dummy app to verify this? If you tell me manually, I'll try it out. Like set some script to async?

@justin808
Copy link
Member

Maybe changing these 2 lines

  <%= javascript_pack_tag('vendor-bundle', 'data-turbolinks-track': true) %>
  <%= javascript_pack_tag('app-bundle', 'data-turbolinks-track': true) %>

Also, how does the browser and webpack know that the second file app-bundle has to load after vendor-bundle.

justin808 added a commit that referenced this pull request Jun 24, 2018
Fixes #290, transparently handling <script async> tag. If the document was already loaded,
the DOMContentLoaded event handler no longer fires, so we just execute it directly, the
same way as jQuery does in $.ready().

Co-authored-by: Alexey Makhotkin
justin808 added a commit that referenced this pull request Jun 25, 2018
* Handle <script async> transparently #1099

Fixes #290, transparently handling <script async> tag. If the document was already loaded,
the DOMContentLoaded event handler no longer fires, so we just execute it directly, the
same way as jQuery does in $.ready().

* Added async tag to spec/dummy


Co-authored-by: Alexey Makhotkin
@justin808
Copy link
Member

Closed in #1107.

@justin808 justin808 closed this Jun 26, 2018
@squadette
Copy link
Contributor Author

@justin808, I've missed your question about splitted bundles. I don't know exactly how Webpack splitted bundles work, but if they depend on global names then splitted bundles will not work with async (but will work with defer).

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

Successfully merging this pull request may close these issues.

React on Rails and async loading of application.js
4 participants