A non render-blocking alternative to the Meteor-core boilerplate-generator package.
Loading meteor sometimes take a long time. It is huge compared to a traditional site. For your regular mobile user (~750Kbps) it will take 6 seconds to load. This makes for an awful UX. With altboiler you can serve static HTML first and then load meteor in the background. You could for example serve a loading screen first. Or you could also preload the whole site without the parts that need a connection to the server.
meteor install kriegslustig:altboiler
server/
// Render a file saved in private/myLoadScreen.html as the loading screen
altboiler.config({
action: Assets.getText('myLoadScreen.html'),
// Render a file saved in private/myLoadScript.js as JS inside the loading screen
js: Assets.getText('myLoadScript.js'),
// Render a file saved in private/myLoadStyles.css as CSS inside the loading screen
css: Assets.getText('myLoadScript.css')
})
To see an example using all features, check the example page's repository
altboiler
caches the generated files fairly aggressively. The file-cache isn't invalidated when you make changes in your client-side code. That's a reason why you should avoid running altboiler
while developing. It's only invalidated when the server is restarted. altboiler
also uses HTTP head-fields to cache client-side.
altboiler
merges all loaded scripts into a singe main.js
. I have to do that, to insure load order. That often poses a problem when debugging. You can use the showLoader
option to turn altboiler off. You may use an env-var to set the option on inside your dev environment.
server/
if(process.env.meteor_environment) altboiler.config({ showLoader: false })
I chose the name altboiler because it's function is to replace the core boilerplate-generator
package. So it's alternative boilerplate_. The package installs two main connect
-handles. One on WebApp.rawConnectHandlers
and one on WebApp.connectHandlers
. The latter serves the loader (load-screen) if the showLoader
option is set to a truthy value. It also prevents the meteor core from loading. The former, raw handler is for the app-script. It compiles all files inside the manifest and serves it as one file.
When a client hits the server it responds with the rendered altboiler Boilerplate
. Its basically rendering assets/main.html
. Here's an overview of what happens inside;
- First your styles (
altboiler.configuration.css
) gets loaded - Your content-HTML loads (
altboiler.configuration.content
) - Your action-HTML loads (
altboiler.configuration.action
) - Your script loads (
altboiler.configuration.js
) - The loader-script (
assets/loader
) gets loaded - All the
altboiler.configuration.onLoad
-hooks get installed - The app-script is loaded over the raw connect-handler
onLoad
hook triggers- All the temporary HTML gets removed
config - Object
: An object holding configuration options. They will be deep-merged with the current configuration. When properties already exist, the new one will be used. Check the configuration-section for more info
This configures altboiler. Certain options must be set on the client, but most can be set on both sides. The configuration is saved in altboiler.configuration
.
Inside the action you might render a template and bind some data-context. To make the server's first response as quick as possible, you'll want to decrease the times a loading template is rendered. If your data is static, that's easy to do. You can just put the call to altboiler.config
inside a Meteor.startup
call and pass the rendered template instead of passing the render function. That way the template is only rendered once. If you are displaying data that could change, you'll need to put the call to altboiler.config
outside of the Meteor.startup
call. This makes things slower dough. Now every time a client requests your site, the template is rendered server-side. What you could do is use a cursor.observe
and then call altboiler.config
every time something changes. That'll make responses just as fast as they were before.
config - Object
: An object holding configuration options. They will be merged with the current configuration. When properties already exist, the temp one will be used. Check the configuration-section for more info
This function sets temporary configuration options. The object passed to this function is used to render the boilerplate once and is emptied after that. It's saved inside altboiler.tmpConf
. This object is deep-merged with the altboiler.configuration
object. By deep-merge I mean that if an option inside altboiler.configuration
is set to an array, the values inside it will persist. The following will output "Thanks for all the fish!" when meteor is loaded.
lib/loader.js
altboiler.config({
onLoad: [function () {
console.log('Thanks for')
}]
})
altboiler.set({
onLoad: function () {
console.log('all the fish!')
}
})
You may want to use different loading screens for different routes. That's what altboiler.set
is for. Here's a minimal example using iron:router
:
server/routes.js
Router.route('/', function () {
altboiler.set({
action: 'Welcome to the front page!'
})
this.next()
}, {where: 'server'})
client/routes.js
Router.route('/', {
name: 'home'
})
All the properties set using altboiler.config
will be saved inside altboiler.configuration
. The structure of that object is documented here. Normally you don't need to access this object directly. Some properties need to be configured on client and server. They are marked with common in the title.
An array of strings of CSS or a string of CSS. The CSS added via this option will be rendered into the loading template. The best way to use this is with Assets
. The CSS added via this option will not be deleted onLoad. The CSS defined here will also be requested by the client when showLoader
is falsy
Same as the css option. The configured JS will be executed right after assets/loader.js
. The array may also contain functions. toString
will be called on these and they will be wrapped in a closure ((yourfunction)()
). It is then executed after the HTML and CSS is loaded. There is a little problem with this tough. The HTML is not guaranteed to be rendered when this is loaded tough. So you might want to wrap you script inside a setTimeout(someFunc, 0)
. By default altboiler.configuration.js
is an array containing a script that makes the load screen nicely fade in and out. So if you want to keep this functionality you may want to use altboiler.configuration.js.push
.
Note: I'm actually a bit unsure as to wether or not it's a good idea to make the fade-in/-out script the default for altboiler.configuration.js
. I think it might be a better idea to add another option called beforeScript
or something. The downside of this would of course be a more complicated API. I'd love to get some feedback on this.
This is what will be served to all routes before meteor. The best way to use this, is to create a .html
file as an asset and then call Assets.getText
. You might also want to use meteorhacks:SSR
.
An array of strings or functions to be triggered when the app-scripts are loaded. The functions have to take one argument next
which calls the next function inside the onLoad
queue. You can interact with the script inside the boilerplate.configuration.js
. You may get variables from the window
object, instead of searching them inside the global-scope. This is because the onLoad listener is installed before boilerplate.configuration.js
is executed. So you'll get an is undefined
error when you try to get a variable defined inside boilerplate.configuration.js
directly.
This option basically does what its name says. It is checked before the loader is served. If the value inside it is truthy, the loader is rendered, otherwise normal meteor is rendered (technically next
is called). If you pass an array, _.every
is used to check every values truthyness. The configured functions recieve a single argument URL
which is a string containing the requests URL.
The configured object is used inside the connectHandlers.use
call. You might need to use this to circumvent altboiler when serving static HTML. Normally this isn't necessary, because the connectHandlers.use
call is deferred using setTimeout
. But there could be cases where you too want to make sure you connectHandlers.use
call is made last.
The string defined here will be rendered into the server static HTML. It's different from action is that it isn't removed from the page when the meteor-core is loaded.
config - Object
: An object holding configuration options. If this is not defined altboiler.configuration
will be used. Check the configuration-section for more info
req - Object
: A request-obeject as defined by the node-docs
res - Object
: A response-obeject as defined by the node-docs
next - Function
: The next function on the stack check the connect docs for more info
This function is largely for internal use. It wraps the altboiler.Boilerplate
function, checks altboiler.configuration.showLoader
and merges the tmpConf
(the options from altboiler.set
).
option - A key inside the configuration
object.
This deep-merges tmpConf
and configuration
and returns the new value. If an option is passed, the value of that key is returned.
- Evaluate other options for serving the CSS configured via altboiler when
showLoader
is falsy.