腾讯新闻 React 同构直出优化实践

原文地址:https://github.com/lcxfs1991/blog/issues/10)
本文 starter kit:steamer-react

为什么做直出

就是为了“性能”!!!
按照经验来说,直出,能够减少20% - 50%不等的首屏时间,因此尽管增加一定维护成本,前端们还是前赴后继地在搞直出。

除此之外,有些特定的业务做直出能够弥补前后端分离带来的SEO问题。像这次选取的腾讯新闻,大多数页面首屏其实都是直出的(但肯定不是React直出)。

性能指标

刚提到的首屏时间,只是单纯内容的渲染,另外还有首屏可交互时间,即除了内容渲染之余,还能够让用户能够对首屏的内容进行交互,如点击、滚动等等。现在市面上有关React的性能报告,尤其是那些截了Chrome渲染映像的,都归到首屏时间。

为什么选择腾讯新闻

  1. 我并非腾讯新闻的业务相关方,可以比较大胆地作为例子使用

  2. 腾讯新闻页面更为丰富,可以做更多场景的实践

  3. 验证全套脱胎手Q家校群react的优化策略、实践方案和开发工具

由于只是实验,数据都是拉取腾讯新闻现网提供的,而样式简单地仿照了一下,做得略粗糙,请见谅。

参考的资料和使用的工具

做这次实践阅读了不少文章,文章提到过的内容我这里就不再赘述了,后文主要是做补充。
这次同构直出实践,我们使用的是脱胎于手Q家校群的react start kit,名曰steamer-react。目前可以试用。它有2个分支,一个是react分支,目前只是提供纯前端的boilerplate。另一个是react-isomorphic,同时包括前端和后台的boilerplate。有什么问题可以给我提issue。

文章:

  1. React+Redux 同构应用开发

  2. React 同构实践与思考

  3. React同构直出优化总结

  4. ReactJS 服务端同构实践QQ音乐web团队

  5. How to Implement Node + React Isomorphic JavaScript & Why it Matters

  6. 性能优化三部曲之三——Node直出让你的网页秒开

分析场景

这次我们选取的是腾讯新闻的列表页、详情页和评论页。平时我们浏览腾讯新闻的时候,都会发现从列表页进详情页,或者从详情页进入评论页,都需要跳转,就像steamer-react中,访问index.html页一样。这样对于用户体验欠佳,因此我做了另外一版,spa.html,使用react + react-router做了一版无跳转的单页面应用。

  1. 列表页

超级产品经理

); } else {  res.body = "404";}

});

客户端也需要做类似的写法,且我们不采用hashHistory,而是browserHistory

let history = syncHistoryWithStore(browserHistory, store);
const { pathname, search, hash } = window.location;
const location = ${pathname}${search}${hash};

match({ routes: routeConfig, location: location }, () => {
render(
// Redux相关

             // Router 相关    ,    document.getElementById('pages'))

});

在吐内容(html)的同时,请记得将store也吐一份到标签里,因为客户端的js中也需要用到。在首次吐出内容之后,你会发现还不能马上进行交互,需要客户端再次执行一行Root.js里面的代码,才能够将可交互的事件绑定。## 前端代码的改动前端的代码改动不大,不过前端这里主要完成最后关键的一步,事件挂载。### 事件挂载后台渲染完后,给客户端吐出html字符串,这时还没有任何事件的绑定,需要客户端的代码进行事件挂载,这里需要注意2点:保持dom结构一致否则会报错或者触发重新渲染1. 将部份事件放到componentDitMount中触发客户端的生命周期只走到componentWillMount,而客户端则会有完整的生命周期,因此部份事件可以挪到componentDidMount中处理。例如这次实践做的列表页有一个我的收藏功能,这里的数据存储用到localstorage。这个服务端无法渲染,因此会选择在componentDidMount的时候再去触发读取localstorage数据的action。1. 兼顾后台没有的对象除了以上提到的,前端部份的代码主要注意的是一些后台没有的对象,例如window。可以通过构建手段注入全局变量去替换或者在服务端渲染的时候不执行部份代码。## 构建的使用react-isomorphic比react的分支多了一个webpack.node.js,用于设置直出的相关构建内容。一些需要留意的配置如下:

target: 'node', // 构建输出node可以识别的内容
node: {
filename: true,
dirname: true
},
{
test: /.js?$/,
loader: 'babel',
query: {
cacheDirectory: '/webpack_cache/',
plugins: [
'transform-decorators-legacy',
[
"transform-runtime", {
"polyfill": false,
"regenerator": true // 识别regenerator
}
]
],
presets: [
'es2015-loose',
'react',
]
},
exclude: /node_modules/,
},
{
test: /.css$/,
loader: "ignore-loader", // ignore-loader对css/scss输出空内容
},
plugins: [
new webpack.BannerPlugin("module.exports = ", {entryOnly : true, raw: true}),
// react/node/asset/下的文件生产到/react/pub/node/之后,需要在最前面注入module.exports,
// 这样Koa才能正常引用
]

## 性能优化如下面两图,是直出前后的Chrome映像对比图,直出要比非直出快400ms,近40%的性能提升。除了直出之外,还采用了react-router,使页面可以无缝切换,大大提高了用户的体验。你可能还会担心这么多页面的逻辑放在一个js bundle会让js很大,如果js bundle膨胀到一定程度,你可以考虑使用webpack和react-router的特性进行拆包。## 总结可能你会惊诧于习惯写长文的我居然只写这么少,但React同构下出真的就是这么简单,而借助脱胎于手Q家校群,验证于腾讯新闻的steamer-react start kit,你会更事半功倍。如有错误,恳请斧正。#react.js、webpack、同构#

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部