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

Defer babel loading #100

Merged
merged 8 commits into from Oct 11, 2017
Merged

Defer babel loading #100

merged 8 commits into from Oct 11, 2017

Conversation

renanpvaz
Copy link
Contributor

Created an utility function to asynchronously load Babel and Algolia attempting to fix #2.

@facebook-github-bot
Copy link
Collaborator

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have you on file. In order for us to review and merge your code, please sign up at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need the corporate CLA signed.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@reactjs-bot
Copy link

reactjs-bot commented Oct 9, 2017

Deploy preview ready!

Built with commit ba6a786

https://deploy-preview-100--reactjs.netlify.com

@facebook-github-bot
Copy link
Collaborator

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks!

apiKey: '36221914cce388c46d0420343e0bb32e',
indexName: 'react',
inputSelector: '#algolia-doc-search',
});
Copy link
Contributor

Choose a reason for hiding this comment

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

This will load the Algolia JS for every page. Even though the request will be cached, the browser might still end up wasting cycles processing/reprocessing the script.

Also, ideally, if we're going to defer loading Algolia- we should defer loading it until the user actually starts to search (eg clicks to focus in the search bar). So maybe we could do this async step there instead? Happy to (a) talk more about this or (b) split that part off into a separate, follow-up issue or task.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps this should be a separate issue.

mountCodeExample('timerExample', TIMER_COMPONENT);
mountCodeExample('todoExample', TODO_COMPONENT);
mountCodeExample('markdownExample', MARKDOWN_COMPONENT);
});
Copy link
Contributor

Choose a reason for hiding this comment

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

What are your thoughts about showing a loading placeholder in the 4 divs in question until Babel has finished loading?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good idea, I can see that it is flashing once it loads. To fix this should I style the divs at content/index.md?

Copy link
Contributor

Choose a reason for hiding this comment

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

Probably not. (We actually need to clean up index.md, see #97)

I would try maybe temporarily rendering a placeholder into the container from the Home template.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So you mean that I should use ReactDOM.render like mountCodeExample does?

Copy link
Contributor

Choose a reason for hiding this comment

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

Probably 😄

Copy link
Contributor

@bvaughn bvaughn left a comment

Choose a reason for hiding this comment

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

Noticed 2 small things. Sorry if you're still working on these files and my comments are premature.

@@ -19,6 +19,8 @@ import Flex from 'components/Flex';
import Footer from 'components/LayoutFooter';
import Header from 'components/LayoutHeader';
import {media} from 'theme';
import loadScript from 'utils/loadScript';
import {algoliaURL} from 'site-constants';
Copy link
Contributor

Choose a reason for hiding this comment

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

These imports can be removed ^


export {urlRoot, version};
export {urlRoot, version, babelURL,};
Copy link
Contributor

Choose a reason for hiding this comment

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

Run yarn prettier to fix this formatting ^ (the trailing comma should be removed)

Copy link
Contributor

@bvaughn bvaughn left a comment

Choose a reason for hiding this comment

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

I'm curious about all of these changes to CodeEditor markup/styles. Why are they needed for deferred Babel loading?

I'm a bit reluctant to change this markup much since we've fixed a lot of edge-cases with scrolling and responsive behavior for this specific component. Is there a way we could do the deferred loading that didn't require so many changes?

I had envisioned something like this:

  • When the page initially mounts, render some placeholder "Loading code example..." type string into the 4 container <div>s
  • Lazy-load Babel (like this PR does)
  • Then mount the CodeEditor component and compiled results into the 4 container <div>s, replacing the placeholder content.

@renanpvaz
Copy link
Contributor Author

Well, most of the changes are not related to Babel, I was having trouble trying to render the placeholders because of the way that mountCodeExample works and the html structure of the examples. Trying not to touch index.md and thinking that you meant a more elaborate placeholder, I decided to remove all the specific styling that CodeEditor had for children and instead did something similar inside mountCodeExample. Besides that, one of the things I was trying to solve is the "raw" appearance (with the backticks) of the examples before mountCodeExample is called.

Anyways, if you're unsure about the changes I could do what you envisioned, but I think that the transition would still look rough once Babel loads.

@bvaughn
Copy link
Contributor

bvaughn commented Oct 11, 2017

Thanks for explaining. 😄

I'd like to avoid making any changes (at least bigs ones) to CodeEditor for the time being. We've done a lot of iterating on that component to get it to look and work right.

We don't have to use the mountCodeExample util to set the placeholder. It's just a convenience wrapper for code that is controlled by the CodeEditor. Our placeholders could just be mounted with ReactDOM.render(...)

Let's do with a simple placeholder right now (just a string is fine) and myself and/or @joecritch will follow up on it.

@bvaughn
Copy link
Contributor

bvaughn commented Oct 11, 2017

Apologies for forgetting about the hackiness we were doing inside of mountCodeExample. Now I understand why you took the original approach you did with this PR.

The home page content and markdown is all pretty janky until #97 gets resolved unfortunately, so
it's probably okay for now to just live with a less-than-perfect solution.

Ideally we'd show a nice placeholder when loading is in progress and a nice error if loading failed. When I say "nice" I don't mean "fancy" just- something that will prevent the page from re-flowing text drastically when things load in. Unfortunately this isn't possible without more hacking b'c of how our content is put together and what we're doing in mountCodeExample.

How do you feel about (for now) further simplifying this to:

diff --git a/src/templates/home.js b/src/templates/home.js
index 5131557e3..cb32c683c 100644
--- a/src/templates/home.js
+++ b/src/templates/home.js
@@ -21,10 +21,10 @@ import ReactDOM from 'react-dom';
 
 class Home extends Component {
   componentDidMount() {
-    this.renderExamplePlaceholder('helloExample');
-    this.renderExamplePlaceholder('timerExample');
-    this.renderExamplePlaceholder('todoExample');
-    this.renderExamplePlaceholder('markdownExample');
+    renderExamplePlaceholder('helloExample');
+    renderExamplePlaceholder('timerExample');
+    renderExamplePlaceholder('todoExample');
+    renderExamplePlaceholder('markdownExample');
 
     loadScript(babelURL).then(() => {
       mountCodeExample('helloExample', HELLO_COMPONENT);
@@ -34,25 +34,6 @@ class Home extends Component {
     });
   }
 
-  renderExamplePlaceholder(containerId) {
-    ReactDOM.render(
-      <strong
-        css={{
-          transform: 'translate(65%, -5em)',
-          display: 'block',
-
-          [media.lessThan('xlarge')]: {
-            transform: 'none',
-            marginTop: 15,
-            textAlign: 'center',
-          },
-        }}>
-        Loading code example...
-      </strong>,
-      document.getElementById(containerId),
-    );
-  }
-
   render() {
     const {data} = this.props;
     const title = 'React - A JavaScript library for building user interfaces';
@@ -341,6 +322,16 @@ const markdownStyles = {
   },
 };
 
+// TODO Improve this temporarily placeholder as part of 
+// converting the home page from markdown template to a Gatsby
+// page (see issue #2)
+function renderExamplePlaceholder(containerId) {
+  ReactDOM.render(
+    <h4>Loading code example...</h4>,
+    document.getElementById(containerId),
+  );
+}
+
 // TODO Move these hard-coded examples into example files and out of the template?
 // Alternately, move them into the markdown and transform them during build?
 // This could be done via a new Gatsby transform plug-in that auto-converts to runnable REPLs?

The reasons I propose these changes are:

  • Moving the placeholder text up via a negative offset seemed kind of hacky and caused inconsistent vertical alignment. Since text reflows anyway when the code loads in (at least currently) the hack wasn't buying us much anyway.
  • nit: There's no need for the util method to be an instance method since it doesn't access anything on the instance

@renanpvaz
Copy link
Contributor Author

Sure thing! Oh, and thanks for all the patience since this is my first PR with actual code.

@bvaughn
Copy link
Contributor

bvaughn commented Oct 11, 2017

No thanks needed! Thanks for contributing and being so easy to work with and iterate on this stuff 😄

Copy link
Contributor

@bvaughn bvaughn left a comment

Choose a reason for hiding this comment

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

I dig it

@bvaughn bvaughn merged commit 85a70b7 into reactjs:master Oct 11, 2017
jhonmike pushed a commit to jhonmike/reactjs.org that referenced this pull request Jul 1, 2020
* docs: Translation of Forms page

* docs: Small corrections in "Forms" page

Co-Authored-By: Halian Vilela <halian-vilela@users.noreply.github.com>

* docs: Removing accent from an example on the Forms page

Co-Authored-By: glaucia86 <glaucia_lemos86@hotmail.com>
BetterZxx pushed a commit to BetterZxx/react.dev that referenced this pull request Mar 21, 2023
…hinese (reactjs#100)

translate content/docs/reference-react-dom-server.md into Chinese
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Defer loading Babel until it is needed
4 participants