做者:Andrew Wong
編譯:鬍子大哈 html
翻譯原文:huziketang.com/blog/posts/…
英文原文:Improve Your UX by Dynamically Rendering Images via React前端
轉載請註明出處,保留原文連接以及做者信息react
市場上競爭是很是殘酷的,衆所周知,僅僅有一個好的 idea 不足以使你的公司成爲獨角獸,執行力也一樣重要。可是最終都會內化到產品中,進而歸結爲一個因素——用戶體驗。git
用戶體驗並非你的產品看起來多好看,還有它的性能如何?使用起來是否方便?——也就是讓你的用戶使用起來感到滿意。github
咱們都有過這樣的經歷,打開一個 app 或者網頁的時候看到以下的圖片,從上到下一點點顯示:瀏覽器
對於高分辨率的圖片和視網膜屏幕,像這種圖片從上到下慢慢展示的狀況很是常見,一般咱們只能靜靜地等着它渲染完畢。緩存
這個問題是能夠解決的服務器
一般有兩個很容易想到的解決方案:CDN 和本地緩存(你的瀏覽器會自動作本地緩存)均可以使圖片加載更快。可是從技術上,咱們還能夠用很 trick 的方法,經過使用戶感知產生錯覺而提高用戶體驗。app
下面就介紹兩步 trick 的方法提高富媒體應用的用戶體驗。dom
(用佔位符代表媒體正在加載)
佔位符是一個目前很流行的方法,之前一般是用一個加載轉輪來表示正在加載,使用佔位符是和用戶交流的一種方式,告訴用戶正在加載的內容是——圖片。
Facebook 和 LinkedIn 是使用技術來提高用戶體驗很好的兩個例子。
接下來優化方法是先把圖片徹底下載下來,再顯示在屏幕上。這樣就會避免邊下載邊顯示而產生的從上到下一點點渲染的狀況。咱們使用 React 的 onLoad
事件來實現這一功能。給服務器發送一個獲取圖片文件的請求,可是先不在 DOM 中渲染,直到整個文件都下載完成之後再渲染出來
佔位符是提早讓用戶產生預期,預期圖片正在加載。而動態加載是在圖片下載完成之後才顯示,有效地避免了圖片從上到下一點點渲染的狀況,進一步提高了用戶體驗。
對於佔位符組件(本例子中使用 LoadingItem
),咱們能夠隨心地展現想要展現的圖片,代碼以下:
export default function () {
return (
<ReactCSSTransitionGroup transitionName="loadingItem" transitionAppear={true} transitionAppearTimeout={500} transitionEnterTimeout={500} transitionLeaveTimeout={300}> <img className="feed__loading-item" src={img} /> </ReactCSSTransitionGroup> ) }複製代碼
在咱們的 Feed 組件的渲染中,只要還有 FeedItems
沒有加載完成,就可使用 LoadingItem
:
export default class Feed extends Component {
...
render() {
return (
<div className="feed"> ... {this.props.items.length > this.state.loadedItems.length && <LoadingItem /> } ... </div>
)
}
}複製代碼
onLoad
動態渲染圖片咱們的 Feed
組件代碼以下:
export default class Feed extends Component {
constructor(props) {
super(props)
this.state = { loadedItems: [] }
}
onLoad(feedItem) {
this.setState(({ loadedItems }) => {
return { loadedItems: loadedItems.concat(feedItem) }
})
}
render() {
return (
<div className="feed">
<h1 className="feed__h1">{this.props.name}</h1>
{this.state.loadedItems.map((item, i) =>
<FeedItem
imgPath={item.imgPath}
name={item.name}
renderModal={this.props.renderModal}
key={i} />
)}
{this.props.items.length > this.state.loadedItems.length &&
<LoadingItem />
}
<div className="hidden">
{this.props.items.map((item, i) =>
<img
src={item.imgPath}
onLoad={this.onLoad.bind(this, item)}
key={i} />
)}
</div>
</div>
)
}
}複製代碼
這段代碼中發生了什麼?底部有一個隱藏的 <div>
用來下載圖片文件。當文件下載完畢,onLoad
事件被觸發,更新狀態。那麼新的加載項,也就是剛剛下載好的圖片,將會被渲染到 DOM 中。
是否是很簡單,簡單的說明但願可以幫助正在受這一問題困擾的朋友。下面給出例子和代碼。
但願本文能對你的知識提高有所幫助,歡迎你們與我交流,關注個人【知乎專欄 - 前端大哈】 。
我最近正在寫一本《React.js 小書》,對 React.js 感興趣的童鞋,歡迎指點。