Skip to content

Conversation

@tf
Copy link
Member

@tf tf commented Aug 7, 2020

REDMINE-17566

@coveralls
Copy link

coveralls commented Aug 7, 2020

Coverage Status

Coverage remained the same at 99.191% when pulling 80d25f9 on tf:ssr into 1cb852d on codevise:master.

@tf tf force-pushed the ssr branch 5 times, most recently from e85030e to 45f4074 Compare August 10, 2020 11:20
@tf tf changed the title [WIP] Server side rendering for scrolled entries Server side rendering for scrolled entries Aug 10, 2020
Copy link
Contributor

@aviav aviav left a comment

Choose a reason for hiding this comment

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

Depending on your view on this, I could also directly merge this.

I haven't checked anything in the browser yet -- this I would normally do once the feedback is dealt with. I'll take a look at staging now, since I didn't spot major flaws, but while I do that, you could already have a look at the review


function render(seed) {
ReactDOM.render(<Root seed={seed} />, document.getElementById('root'));
if (editMode) {
Copy link
Contributor

Choose a reason for hiding this comment

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

suggestion(if-minor): The caller of this method also makes the same case distinction. Maybe it would make sense to split the branches into different methods now. Related to question above

Copy link
Member Author

Choose a reason for hiding this comment

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

Both times (edit mode or not) the function is called from one the same place [1, 2]. Detecting edit mode there seems worse.

I tried inlining render, but it also did not make things clearer IMO.

Copy link
Contributor

Choose a reason for hiding this comment

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

To clarify: The caller of render would be pageflowScrolledRender, and in both of these methods, we have a branching against the same editMode variable. This means that we'd really only need to branch once, which would be more streamlined

Copy link
Contributor

@aviav aviav Aug 11, 2020

Choose a reason for hiding this comment

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

What I just described is what you mean by inlining render, right? In case you think it'd make the code worse, let's leave it like this

Copy link
Member Author

@tf tf Aug 11, 2020

Choose a reason for hiding this comment

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

What I tried was:

global.pageflowScrolledRender = function(seed) {
  setupI18n(seed.i18n);

  browser.detectFeatures().then(function(){
    const rootElement = document.getElementById('root');
    const root = <Root seed={seed} />;

    if (editMode) {
      loadInlineEditingComponents().then(() =>
        ReactDOM.render(root, rootElement)
      );
    }
    else {
      ReactDOM.hydrate(root, rootElement);
    }
  });
}

This only branches once. Still, I do not like it better. Duplicating the conditional actually makes the difference stick out more for me: Once it's about using render vs hydrate, the other time about loading inline editing components or not.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'll not impose my opinion here. Both ways, the PR as is brings a meaningful improvement. I like one way better, you like the other way better.

My preference is mostly based on the feeling that I might be missing an aspect of the branching logic that might lead to combinations like either first true branch then false branch or the other way around. Having the code as in your previous comment makes it clearer that true then true and false then false are the only possible cases, and we don't need to look out for side effects that suddenly toggle editMode.

I see how the exact same indentation of the ReactDOM API usages can provide another sort of clarity

@tf tf changed the title Server side rendering for scrolled entries [WIP] Server side rendering for scrolled entries Aug 11, 2020
tf added 8 commits August 11, 2020 14:57
Use vendored React 15 version and require it from paged specific
vendor file. Scrolled gets its React build via Webpack.

This will let us upgrade to a newer version of `react-rails` without
affecting Paged.

REDMINE-17566
* `react-rails` tries to autodetect the asset container by default and
  prefers Webpacker if it present. Since Webpacker is present in host
  applications that use Scrolled, we need to tell `react-rails` to use
  the Sprockets asset container explicitly. Since there is only a
  global config, we need to create our own renderer which specifies
  the asset container explicitly.

* `react-rails` now requires a `server_rendering.js` file to load
  dependencies. We do not want to force each host application to
  create this file. So we let Paged provide its own. This also lets us
  use the vendored React version for server side rendering.

REDMINE-17566
`classlist-polyfill` mentions window in its detection code.

REDMINE-17566
* Check before using browser globals

* Remove legacy iOS 7 hack which mentions `navigator`.

REDMINE-17566
`useLayoutEffect` is not available in SSR. We need to fallback to
`useEffect`.

REDMINE-17566
Make sure HTML content of the entry is present in the server rendered
response. Before, all visible content was only rendered client side
based on the JSON seed embedded in the document. Now we can at least
display the textual content even if the user has JS turned off. Images
and media will not be visible since lazy loading still depends on
JS. This is also an improvement in regard to SEO since scrapers will
not need to run JS to obtain the content.

REDMINE-17566
Previously, CSS modules styles where injected via client side
JS. Ensure styles are available right from the start when displaying
server side rendered HTML. This prevents a "flash of unstyled content"
when the server side rendered HTML is already present but styles have
not yet been injected. It also makes sure the page has CSS when JS is
disabled.

REDMINE-17566
@tf tf changed the title [WIP] Server side rendering for scrolled entries Server side rendering for scrolled entries Aug 11, 2020
@aviav aviav merged commit 72d34b9 into codevise:master Aug 11, 2020
@tf tf deleted the ssr branch August 11, 2020 14:28
@tf tf added this to the v15.3 milestone Aug 12, 2020
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.

3 participants