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
Inquries: i18n interpolation, first-page problem #227
Comments
For Q2 see #203 For Q1, I don't understand, why wouldn't the following suffice? h('p.message', {
h('a.link', {href: '/help'}, i18n.t('msg.error'))
}) |
@Zolmeister Thx for the reply, but I did read #203, see my OP, I am wondering the conclusion it reached: if we avoid patching real dom, then the only solution to me, is to replace it wholesale. As for Q1, you are missing out the interpolation part, imagine a i18n mapping like
To avoid interpolation you need to split welcome message into 5 strings, which doesn't make it easier to manage. |
My understanding is that you generate the first diff via html-to-vdom and simply apply it to the DOM as normal. As for the i18n interpolation, I guess I think interpolating over the html is a mistake (in general), and the answer really is to break it up into components |
Yeah ideally we wouldn't need interpolation with html, but human languages are not designed with programmers in mind, eg. word order changes, divide english sentences into word phrases (or divide them based on dom nodes), you will soon find yourself unable to translate them into other languages properly. I don't think there is a way to avoid html string being used in i18n interpolation, unless we explicitly structure sentences with templating language constraints in mind. For other templating system, these are often done through specifying the input is html safe. For Is it possible to extend |
For the client-side rendering problem, is I am not sure if it would be faster than just rendering the full document and replace it in one go? Can traversing real dom and patching them be slower? I see more researching are to come at #222 |
If you want different vnode structures for different phrases, you're going to have to build something on top of virtual-dom where you can define a vtree in some form that suits you, and create a lookup system for the structures, using i18n under the hood to do translations. If you are putting html in your translation strings you can probably parse the html and convert the structures to template functions using one of the html to vdom libraries out there. |
I have been dealing with this problem lately, and while approach like using 200kb+ minified js to be exact, since it depends on So for simplicity sake I still prefer wiping out existing server-rendered dom, and using virtual-dom to re-render the whole page again (when js are loaded and data are available, otherwise it behaves like a traditional page-based website). I believe |
Can you use https://github.com/marcelklehr/vdom-virtualize ? It does not require a parser since it uses innerHTML to parse into DOM node first then translates that into VDOM. |
Thx! I was pointed to https://github.com/tbranyen/diffhtml in another thread as well, use the same technique you mentioned. But we do need to wipe existing server-rendered dom and replace it with a virtual-dom, right? I don't know how
That's huge amount of automation (and probably a lot of code and tests). |
If you create an initial vtree from your existing HTML, then the resulting diff of the new tree should not produce any DOM operations if it hasn't change since you rendered from the server. It will not replace everything. |
Just trying to understand your problem...
What is the problem in re-rendering client-side? |
@alexmingoia I will dig into it further, what you describe sounds like what I expect from React. @staltz I think the main problem I had was: now we have a complete document from server, we should try to reuse those dom/data for as much as possible, to avoid replacing it again client-side, which can be bad for battery, network, or experience (say user has scrolled, re-render the whole document might cause jump). |
Unless you have a truly huge page, like some monolithic news paper site, client-side rendering should be normally in the milliseconds (10ms -- 150ms). It is not nearly enough processing to affect battery. User's experience should be unaffected too, since 150ms is too fast to read+interact. Of those, maybe only redundant network calls could be the problem. In fact, if rendering depends on network calls, then that could truly make client-side rendering pass the milliseconds mark. But in that case you should do something smarter, having some kind of flag given to the app, where flag=true on the server-side would make initial network requests, but flag=false on the client-side would not make initial requests. |
Zorium-seed does server-side network requests and pre-loads the data client-side: https://github.com/Zorium/zorium-seed |
@staltz @Zolmeister Thx for the breakdown and suggestions, but I do prefer PE considering other aspect of our site, which is mostly page-based, content-focus, and not single page application. You might argue My final question before closing this ticket: I would really love a simple explanation on how
Step 4 is where I am confused, this means as long as we know |
@bitinn yes, you can apply patches to any dom tree. if that dom tree matches the rendering of i'm not familiar with vdom-virtualize but in your 4 steps i'm not seeing where you would apply event handlers. does the first diff more or less just produce patches that only add event handlers? |
@neonstalwart It's a good question, so without |
To sum up our discussion so far,
|
@bitinn for number 3 you have to manage it yourself by injecting it into the DOM (via script tag). This is how Zorium does it: Edit: for number 2, it already just kind of works because the first v-dom diff does it |
@Zolmeister got it, so server render include inline data to be loaded by client, that's certainly a solution. |
I tested
Using a simple page with around 100 nodes: On my macbook air, solution 1 takes ~15ms, solution 2 takes ~30ms. If As for events, does it mean To be honest I don't have enough knowledge about Also whichever solution I use, I am running into this bug while updating my simple page: #176 If it's a |
That is not a bug in virtual-dom. You're creating a vdom node somewhere with contentEditable="" or there's a bug in vdom-virtualize. You need to find where in your vtree you're creating a node with contentEditable and why it has an empty value. |
@alexmingoia please see this reply in that thread: I think that's how innerHTML work, unless it's not supported by PS: we don't have anything with |
@Zolmeister saw your comment edits in response to item 2 Looking at In short, this is key factor on whether we can just diff existing dom by getting a vtree representation of it and get event attached for free; or we should replace existing dom with result from |
@bitinn I don't think you understand how virtual-dom works
edit: if the DOM node already exists, you never call |
@Zolmeister Great to hear, so it's the better case. But what's https://github.com/Matt-Esch/virtual-dom/blob/master/vdom/create-element.js#L34 |
@bitinn The first time you're not diffing an existing tree, and must create the nodes |
My understanding before starting this discussion is as you described:
But the discussion lead me to doubt myself :) for example, I don't fully understand @neonstalwart's question earlier #227 (comment), if diff/patch does the magic already, what else about events do I need to worry about? |
I used I am closing this ticket as all 3 features from React can be implemented in some way. Thx all for replying. |
A small update: after spending much time working on progressive enhancement with We use it in production, you are welcomed to try it out. |
I have been using virtual-dom for my projects in the past 6 months, while it's an absolute joy 99% of the time, these 2 topics bother me quite a bit:
(They bother me mostly because I don't know if I am doing them as elegantly as possible. And both are not direct problems with virtual-dom, but using virtual-dom with other modules.)
Q1 - We use node-polyglot for i18n, and like most i18n libraries they support string interpolation, but in order to mix polyglot output with virtual-dom, we need to do following:
<a href="/help" class="link">
should preferably be generated withh
p.message
flexible, we should avoidinnerHTML
approach as wellSo ideally we need to go
vnode -> string -> vnode
in order to use i18n interpolation involving html. That involves:h
and usevdom-to-html
to convert into stringpolyglot
, which produce the message content, as html stringhtml-to-vdom
to convert content into vnodes, pass them as children into vnodep.message
I am not sure how expensive this would be, should I just use innerHTML for performance?
Q2 - Existing frameworks like
mercury
focus on single page app (most examples are client-side rendering); we use virtual-dom extensively server-side for first-page view rendering, and want to add client-side rendering as a progressive enhancement.I have seen a few discussions (#49, #203) on this, and know that virtual-dom isn't looking to do complex client-side binding (that allows client-side rendering to kicks in when real dom already exists).
Does it mean currently the best approach for mixing server-side and client-side rendering, is to re-render the whole document again when client-side data is ready? I can't think of a better way, and would like to believe virtual-dom is fast enough when re-rendering full document.
How do you approach this problem?
mercury
encourages no manual dom manipulation, which I assume applies to virtual dom libraries in general.In short, sorry for posting 2 long questions, but hopefully these 2 questions are common enough to worth answering :)
The text was updated successfully, but these errors were encountered: