-
Notifications
You must be signed in to change notification settings - Fork 2k
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
support server side rendering #3955
Comments
Check out: https://pimterry.github.io/server-components/ https://scotch.io/tutorials/server-side-web-components-how-and-why On Wed, Sep 14, 2016 at 8:02 AM jay8t6 [email protected] wrote:
|
Wondering if that would speed up adoption. |
The real challenges about server side rendering with web components are:
Even if (1) seems on its way for native Web Components, (2) could be very hard to handle for Polymer, isn't it ? I'm wondering to integrate Polymer (or more globally Web Components) in our app but server side rendering lack might be a major blocking issue. Going deeper in the reflexion, this seems a bit paradoxal for the Web Components spec itself that want to bring us back to use "native" elements (HTML first, ...) while those "native" elements needs to be pre-rendered for performance, SEO, ... -_-' |
In the last couple day after I watched @jakearchibald's talk for the Chrome Dev Summit, I thought a lot about how to improve initial page load with Polymer (using Server Side rendering), but I couldn't find a convincing solution without rewriting Polymer. So I just came up with that idea: How about you can tell Polymer that you already piped a Polymer page throw Chrome V8 on the server? window.Polymer = {
dom: 'shadow',
serverRendered: true
}; So Polymer knows, that you already rendered all elements and run all ready/attached callbacks on the server, so Polymer skips them and only adds the EventListeners for property change events to make all necessary runtime changes after running the initial Javascript. I hope this is possible somehow and I know that I didn't thought over all possible scenarios and features Polymer has, it's only a concept in my head. But I think this should be possible somehow. This should boost performance on initial page load. |
Additional opinion on what @vpusher mentioned:
I would like to start a discussion about this topic. |
I'm not a Polymer dev but having done quite a bit of experimentation around this with web components, I may be able to add some insight. Infrastructure for rendering DOM on the server is the easy part. There's two hard parts about this that come to mind:
The first part isn't as easy as it sounds because you need to represent the shadow root in HTML. Once you do that, you need to also represent the slotted content and the state in which the slots are (displaying slotted content or default content). This also needs to be done in a way where styling works both inside and outside of the shadow root, depending on what you need the server rendered content for. Rehydrating is an easier task, but requires a lot of work on the client and some potential reflows. The declared shadow root must be imperatively initialised and templated. Then all slotted nodes must be moved to light DOM so they can be slotted. I'd venture to say that since you're doing that much work already on the client, that you may as well just render in the client. You have to do this anyway and would just be adding more work for the client to do by having custom distribution logic on connected. In doing SSR, you'd also be delivering more page weight to the client than you would be if it was just your CE definitions. I'm interested in exploring some alternate approaches here, if anyone has any. Every time I've approached it, it seems to lead down the path described above. Either that, or it becomes very coupled to the framework. Even then, if you're using shadow DOM, a lot of the same principles apply. |
This is no problem if you use 'shady dom', but that is not the target. I didn't thought of shadow DOM as I suggested this. As I understood it, to set up all shadow roots you have to run Javascript first, right? |
The only issue is the on-connected “starters-pistol”, which represents the the first time an element, module, or full App can inspect its children, measure, make adjustments, share properties, etc. So come of the more commonplace pre-render stuff is made more complex by the need to register an element. Elements can, of course, be pre-registered as object apis, although i have no idea how that affects a polymer set of tools.
|
Currently in native, yes.
There is an issue relating to this in the w3c/webcomponents repo, but it was closed due to no concrete proposals. I definitely think it's worth revisiting at a spec level, and experimenting with at a polyfill level to see what's possible. Without native support, though, I think PRPL will get you a lot further in terms of performance (even with native support). |
Wouldn't SSR work best with "view" components that could be created without shadow dom? |
Currently yes, because Shadow DOM can only be applied imperatively after the page is loaded using JavaScript and not declaratively using HTML. The spec is missing there a part. It would be great if the browser would create shadow dom out of a streamed HTML file. This would solve so many problems with SSR. |
SSR +1 |
Just want to chime in. Last month I gave a presentation on exactly this topic of first load performance. In general, SSR is not required, but is usually the solution applied when the first paint is significantly delayed due to big scripts being parsed and executed. Instead of rendering on the server, I propose(d) to serve a fully working HTML response and then make use of custom elements upgrade mechanism to load all other components. The results for our website (https://symposium.ch.tudelft.nl/2017/) were spectacular, in the sense that the first paint and first meaningful interaction are very very fast. After the first paint is done, it loads the other dependencies with the HTML imports and executes the scripts of Polymer. Then the custom elements are upgraded (which use shadow dom) to make sure that styles are not leaking and the rest of the website is functional. You can view my slides at https://timvdlippe.github.io/presentation/browser-as-our-framework/#0 I am not sure how useful they are without me talking. After slide 12, I start my section on load performance. Slide 18 shows the problem we encountered on 3G. Slide 20 shows a direct comparison to before (left) and after (right). On 3G that is 12 seconds -> 6 seconds (e.g. 50% off). In essence, the index.html is scaffolded with an initial fully working response, as shown on slide 24. I hope this information is useful and show why SSR might not be required. Looking forward to your response! |
SSR +1 |
We've started working on SSR over here: https://github.com/skatejs/ssr. It's not Skate specific, however, Polymer likely uses more DOM interfaces than Undom implements (which it uses currently behind the scenes. Skate uses a very minimal subset of the DOM APIs while still being pure web components, which is why it works well. It's likely to work with Vanilla custom elements / shadow DOM if you limited yourself to a small subset or used something like Preact to render the element. JSDOM support is in progress over here jsdom/jsdom#1872, which would enable broader coverage of the DOM APIs. The roadmap for our SSR library is to eventually be able to use any server-DOM impl (Undom, JSDOM, etc) and focus solely on serialisation / rehydration. |
Closing per above comment. Make sure you check out @treshugart talk at the summit! https://summit.polymer-project.org/schedule called "SSR Web Components" |
From the talks it seemed we should do SSR using Rendertron, e.g. with Firebase functions. |
Is the (main) hurdle here the fact that Polymer/Web Components don't have a virtual DOM? |
No, you can use virtual DOM with polymer elements. |
Good to know, thanks. |
@KSuttle-cng and just to clarify—I don't think there's any connection between virtual DOM and SSR. The issue with SSR and shadow DOM is that you can't serialize shadow DOM into HTML markup—right now, a shadow root can only be created using JavaScript. Rendertron works around this by using the shady DOM/shady CSS polyfills, which simulate shadow trees using regular DOM trees + JS patching and assorted CSS tricks. The result is a tree that can be serialized and sent down to the browser. Virtual DOM is a strategy for updating the DOM tree after the browser has created it. The server is still sending markup down to the browser, and the browser is parsing it into a DOM tree. JavaScript code (react-dom or preact or whatever) maintains the "virtual DOM" and uses it to determine how to update the "real" DOM—the nodes the browser actually displays. |
@TimvdLippe I don't follow. The link you closed this by does not apply to Polymer, skatejs/ssr only works for vanilla HTMLElement. I haven't figured out why, but Polymer will not compile on the server using skatejs. |
@yorrd Polymer components are web components and should therefore "just" work with Skate SSR. If you are encountering any issues, I advise you to open an issue over there to investigate and resolve your problem. |
@TimvdLippe thanks for your stand on this. I think I'll be waiting for the smaller |
Running Electron in headless mode works great. All Chrome APIs are available there. You can run the app in Electron, then get the The best part about it is that you can run both your front end and back end tests all in one setup (i.e. you have a Node.js backend which can use the Node.js APIs exposed in Electron). The new Google Carlo (official Chrome + Node.js integration) project might be a nice alternative soon too. |
It won't just work because if a Polymer element tries to create its own shadow root, it may fail when there's already one created by the client-side Skate SSR script. If Basically, if a web component can detect and use an existing shadow root when there is one, and otherwise make a new one, then it should theoretically work with Skate SSR. Now, getting Polymer to run in an undom or jsdom environment, that's a another issue (see the headless browser suggestions above instead of using undom or jsdom). |
I just did a quick search for Skate SSR (currently) makes a shadow root on a rehydrated element with So, it should "just" work. There's some things to consider:
TLDR, if you always use "open" shadow roots, it should work. The hardest part is getting the code running on the backend, not the Shadow DOM stuff. |
I know this is not currently in the roadmap, but it would be great if you guys can support server side rendering like riot.js
The text was updated successfully, but these errors were encountered: