-
Notifications
You must be signed in to change notification settings - Fork 129
Server side rendering for scrolled entries #1552
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
Conversation
e85030e to
45f4074
Compare
aviav
left a comment
There was a problem hiding this 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
entry_types/paged/app/assets/javascripts/pageflow_paged/server_rendering.js
Outdated
Show resolved
Hide resolved
entry_types/paged/app/helpers/pageflow_paged/react_server_side_rendering_helper.rb
Outdated
Show resolved
Hide resolved
|
|
||
| function render(seed) { | ||
| ReactDOM.render(<Root seed={seed} />, document.getElementById('root')); | ||
| if (editMode) { |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
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
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
REDMINE-17566