-
Notifications
You must be signed in to change notification settings - Fork 51
RFC: Layout and ItemLayout render a big amount of nested DOM nodes #241
Description
Layout and ItemLayout render a big amount of nested DOM nodes
Steps
I was trying to reuse and ItemLayout (and Layout) Stardust components to re-write the Chat.Message component since it looked that I can leverage the logic provided by ItemLayout props (media, endMedia, header, headerMedia, etc) to add author and date props to Chat.Message.
However, I realized these layout components render a big amount of redundant DOM nodes; here is an example for a very simple Chat.Message implemented with ItemLayout:
Example code:
const messages = [
{
key: 1,
author: 'John Doe',
date: 'Mon Sep 17 2018 13:54:05',
content: 'Hello',
mine: true,
avatar: { src: 'public/images/avatar/small/matt.jpg', status: availableStatus },
},
]
const ChatExampleAvatar = () => <Chat messages={messages} />
export default ChatExampleAvatarScreenshot:
Rendered DOM:
<li date="Mon Sep 17 2018 13:54:05" class="ui-layout ui-itemlayout ui-chat__message">
<div class="ui-layout__main">
<div class="ui-item-layout__main" style="grid-template-rows:1fr 1fr">
<div class="ui-layout ui-item-layout__header">
<div class="ui-layout__main">John Doe</div>
<span class="ui-layout__gap"></span>
<div class="ui-layout__end">
<span class="ui-item-layout__headerMedia">Mon Sep 17 2018 13:54:05</span>
</div>
</div>
<div class="ui-layout ui-item-layout__content">
<div class="ui-layout__main">Hello</div>
</div>
</div>
</div>
<span class="ui-layout__gap"></span>
<div class="ui-layout__end">
<span class="ui-item-layout__endMedia">
<div class="ui-avatar">
<img aria-hidden="true" src="public/images/avatar/small/matt.jpg" class="ui-image"/>
<span title="Available" class="ui-status">
<span class="ui-icon" aria-hidden="true"></span>
</span>
</div>
</span>
</div>
</li>Implementation:
<ItemLayout
as={as}
{...rest}
className={cx(classes.root, classes.content)}
media={!mine && this.renderAvatar(avatar, styles, variables)}
endMedia={mine && this.renderAvatar(avatar, styles, variables)}
header={author}
headerMedia={date}
content={content}
truncateHeader={true}
/>Issue:
Expected Result
The DOM tree has a reasonable depths (let's say a max of 4 nodes).
Actual Result
The DOM tree has a depth of 6 just for this basic example!
Proposed solution
Add better conditions to Layout and ItemLayout components in order to prevent additional DOM elements in the tree when a certain rendered area (start, main, end, header, media, etc) is represented by:
- another
ItemLayout/Layoutcomponent - single DOM node
What we do now is to add a wrapper DOM element (divusually) to wrap content for a layout slot. We can use the single node itself for that and apply the layouting styles directly.
Version
0.5.2
