isomorphic reactjs

isomorphic javascript

web应用从最早静态页面、到php后台框架输出、到mv*为主的SPA、到基于node中层的直出,目前有人提出web的下次改变可能将是基于isomorphic javascript的前后台同构应用。

一、目前主流web app的特点

目前主要的应用都是基于mv*基础上(backbone、ember、angular等)或工程师自己的mvc思想上的应用。

通常做法是,页面所有的数据交互在客户端(一般指浏览器或移动webview)完成,后台只负责输出数据或一个初始的空白页面,而页面的数据则通过加载后的js进行加载渲染,一般用户和开发者的体验都会比较好,but存在很多问题:

  • SEO不可做。除了基础的meta信息,基本没有全文信息。搜索引擎爬虫并不能获取页面内容。
  • 性能仍有问题。大量的内容渲染,逻辑判断、dom操作、网络交互都在客户端完成,页面上的空白时间很容易让用户厌烦。
  • 可维护性。有些低耦合的逻辑模块希望在前后台复用,例如时间格式化,表单验证,我们考虑到某些因素都会前后都做一次。

二、Isomorphic JavaScript

通过nodejs,可以轻松创建一个web server,运行js模板将页面输出给浏览器。但是Isomorphic JavaScript使用的是在服务端和客户端运行的一套代码,可以运行js模板或者前端的框架,这就是 “Isomorphic JavaScript”(同构的JavaScript),借用一个图~

要做到这件事,有几件事情必须要解决:

  • 抽象
  • 路由
  • 获取数据
  • 视图渲染
  • 自动构建打包

三、 Isomorphic reactjs

基于这个思想,有人提出使用reactjs来进行直出,大致看下是怎么做的。 mv*驱动在客户端的dom渲染效率是很慢的,例如一个vm的生成要去扫描dom所有属性节点来获取directives、filter或者表达式。而且还有上面提到的三个问题,但是如果在服务端去做就可以解决这些性能问题。 但是问题来了,如何提前扫描节点生成vm,将里面所有的directive、filter和表达式输出呢?可行的做法是在构建混淆阶段去render出来,而且要对每个定义的节点属性的指令表达式去render,这样就行了。不过自己去做工作量就有些了,而且容易出问题

那用reactjs可以怎么搞? http://reactjsnews.com/isomorphic-javascript-with-react-node/ 看来又有人干了这件事情,思路类似,reactjs实现的原理是:使用react.renderToString方法将virtual dom转换为string输出到页面上。这样前端的react代码就完美在服务器跑起来了。

安装node-jsx,处理jsx语法:

npm install node-jsx

除了必要的工厂抽象模块,依然可以像原来一样书写react模块,这样既可以被前端打包处理,也可以通过node router render出来。

 /** @jsx React.DOM */

var React = require('react/addons');
var Mock = require('mockjs');
var Griddle = React.createFactory(require('griddle-react'));
var resultsPerPage = 10;

var columnMeta = Mock.mock({
    'column': ['id', '姓名', '语文', '数学', '英语', '历史', '生物'],
    'order|+1': 1,
    'locked': false,
    'visible': true,
});

var fakeData = Mock.mock({
    'list|45': [{
        'id|+1': 1,
        '姓名': '@chineseName',
        '语文 |40-100': 100,
        '数学 |40-100': 100,
        '英语 |40-100': 100,
        '历史 |40-100': 100,
        '生物 |40-100': 100
    }]
}).list;

var ReactApp = React.createClass({

    componentDidMount: function() {
        console.log(fakeData);
    },

    render: function() {
        return ( < div id = 'table-area' >
            < Griddle results = {
                fakeData
            }
            columnMetadata = {
                columnMeta
            }
            resultsPerPage = {
                resultsPerPage
            }
            tableClassName = 'table' / >
            < /div>
        )
    }
});

/* Module.exports instead of normal dom mounting */
module.exports = ReactApp;

解决路由问题:

var React = require('react/addons'),
ReactApp = React.createFactory(require('../components/ReactApp'));
module.exports = function(app) {
    app.get('/', function(req, res){
        var reactHtml = React.renderToString(ReactApp({}));
        res.render('index.ejs', {reactOutput: reactHtml});
    });

}

这里是关键,这里的renderToString将virtual dom直接转化成为html,这样就实现了直出的转换。

输出模板则可以这样写:

<!doctype html>
<html>
  <head>
    <title>react output demo</title>
    <link href='/styles.css' rel="stylesheet">
  </head>
  <body>
    <h1 id="main-title">react output demo-成绩表</h1>
    <div id="react-main-mount">
      <%- reactOutput %>
    </div>
    <!-- comment out main.js to see server side only rendering -->
    <script src="/main.js"></script>

  </body>
</html>

具体看个例子

https://github.com/ouvens/Isomorphic-reactjs/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏漫话前端

浏览器已原生支持 ES 模块,这对前端开发来说意味着什么?

还记得当初入门前端开发的时候写过的 Hello World 么?一开始我们先创建了一个 HTML 文件,在 <body> 标签里写上网页内容;后来需要学习页面交...

3017
来自专栏微信小程序开发

微信小程序开发常见问题(二)

知晓程序员,专注微信小程序开发的程序员! 今天再给大家分享几个微信小程序开发的常见问题,顺便吐槽一下,武汉的冬天太TM冷了,没有暖气的冬天真的很难过,写文章的心...

4275
来自专栏andychai

前端静态资源缓存策略

页面加载提速是战场,首当其冲要优化的就是 静态资源(js|css) 的加载速度。我们小组去年基于Vue开发了一个积分商城单页面应用。本文旨在与大家分享在单页应用...

1888
来自专栏IT大咖说

vSAN常见错误故障排错

内容来源:2018 年 8 月 7 日,VMware大中华区原厂高级技术讲师史峻在“VMware直播分享 第二期”进行《vSAN常见错误故障排错》演讲分享。IT...

4823
来自专栏JAVA后端开发

巧用vue组件实现人员id及名称的转换

我们开发时,后台很多时候都只存储一个用户Id,如创建人,修改人等,但我们前台显示时,又需要将Id转成人员名称显示。   一般很多时候在后台通过这条Id找到人名...

924
来自专栏更流畅、简洁的软件开发方式

【自然框架】重新整理后的自然框架源码!

  整理后的自然框架源码,有九个项目,可以看下面的脑图,带“对号”的表示是一个独立的项目。后面的是主要内容。 欢迎下载http://www.naturefw....

2208
来自专栏FreeBuf

登录框的另类思考:来自客户端的欺骗

前几天刚见人发了《一个登录框引发的血案》,而常规的爆破有风控和各种变态验证码,或者大型的电商都会用SSO实现登录,密码找回逻辑看似天衣无缝,又或者采用第三方的O...

1020
来自专栏西安-晁州

vuejs、eggjs、mqtt全栈式开发设备管理系统

vuejs、eggjs、mqtt全栈式开发简单设备管理系统 业余时间用eggjs、vuejs开发了一个设备管理系统,通过mqtt协议上传设备数据至web端实时展...

1.5K7
来自专栏谈补锅

<转>iOS性能优化:Instruments使用实战

最近采用Instruments 来分析整个应用程序的性能.发现很多有意思的点,以及性能优化和一些分析性能消耗的技巧,小结如下。

882
来自专栏linux驱动个人学习

Linux下1号进程的前世(kernel_init)今生(init进程)----Linux进程的管理与调度(六)

前面我们了解到了0号进程是系统所有进程的先祖, 它的进程描述符init_task是内核静态创建的, 而它在进行初始化的时候, 通过kernel_thread的方...

961

扫码关注云+社区