使用Meteor模拟服务器端渲染

时间:2014-05-23 17:26:48

标签: meteor meteor-blaze

众所周知,Meteor发送给客户端的初始有效负载包括(生产中)一个连接的javascript文件,其中包含Meteor平台,软件包以及解析为Meteor的反应模板系统的所有模板。服务器端呈现(其中模板呈现为HTML并在初始有效负载中发送到客户端)正在进行中,但还没有预期的发布日期。

鉴于Meteor 0.8.x中的可用功能,我正在寻找一种“破解”或近似服务器端渲染的方法。具体来说,我想:

  • 启用页面呈现其初始内容,而不用首先等待下载和解析数百KB Meteor平台javascript文件。
  • 或者,修改Meteor,使其只发送在javascript有效负载中呈现初始请求所需的模板,并在渲染完成后获取剩余的模板。

用例是http://q42.com。我认为Meteor不适合像这样的静态网站,但我想尝试看看我能走多远。目前Meteor平台的JS文件大小超过600 KB(gzip压缩为200 KB),如果可能的话,我想减小这个大小。

注意:我知道并且已经使用了Arunoda的快速渲染包,该包用于发送带有初始有效负载的数据。在这种情况下,我希望通过更快地降低模板本身来缩短首次渲染时间。

1 个答案:

答案 0 :(得分:2)

这有点棘手。但是你可以做一些事情。这可能不是最好的方法,但它可以帮助你以某种方式开始。

Meteor以许多软件包构建为“默认”,有时不需要。您可以删除standard-app-packages并添加此处列出的软件包(您需要并手动使用):https://github.com/meteor/meteor/blob/devel/packages/standard-app-packages/package.js

要减少模板,您必须包含您使用的裸模板,并单独包含其他模板,并可能通过集合发送模板信息,使用实时观察器句柄启动模板

你必须在服务器端“渲染”模板,或者使用Spacebars.compile包中的spacebars-compiler手动将它们存储在你的集合中,这有点棘手,但你可以做得很好:

这应该给你一个粗略的想法,不知道如何通过它的'eval'位:

/private/template.html

中的HTML文件
<template name="test">
    Hello {{name}}
</template>

/private/template.js中的JS文件

Template.test.name = function() { return "Bob" }

服务器端代码

var collection = new Meteor.Collection("templates");

var templateData = Assets.getText("template.html");
var templateJs = Assets.getText("template.js");

var compiled = Spacebars.compile(templateData).toString();
var jsData = templateJs;

collection.insert({templateName:"test", data: templateData, js:  templateJs});

客户端代码

collection.find().observeChanges({
    added: function(id, fields) {
        var template = fields.data,
            name = fields.name,
            js = fields.js;

        Template["name"] = UI.Component.extend({
            kind: "name",
            render: eval(template),
        });

        eval(js);
    }
});

然后只需订阅要求您的模板的集合,它应该存在。如果您使用iron-router我认为(不确定)您可以在呈现模板之前等待订阅,这样您就可以使用它。

同样这只是一个'hacky'解决方案,我个人不喜欢的一件事就是使用eval,但javascript需要以某种方式运行...

您可以使用fs = Npm.require('fs')遍历特定文件夹中的文件来渲染每个模板。

另一种方法是注入一个'script'标签,调用已编译的js模板和模板助手来让模板存在。