未加星标

Server-side Svelte

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2017 | 作者 红领巾 ] 0人收藏点击收藏

Most of the time you will probably run your Svelte code client-side, but there are scenarios where you can benefit from server-side Svelte rendering.

SEO

In my opinion the primary use case for server-side rendering is SEO. Doing an initial rendering on the server will make your website much more crawler accessible. Crawlers typically support some javascript execution, but a complex JavaScript application is unlikely to be indexed correctly.

My experience is that applications that make ajax calls to fetch data are particularly challenging to index. The crawler might successfully render the initial static part of the application, but the data will be missing since the crawler won't make the necessary ajax calls.

Doing the initial rendering on the server allows crawlers to download the application as fully constructed html. There is no need to execute JavaScript on the client to compose the initial view since the view was already built on the server.

Server-side vs Client-side

Technically you could build a Svelte application without any client side components, but it would be completely static. Basically the application would behave much like an old server-sidephp application. Great for crawlers, but real users typically expect a richer user experience.

This is where server-side meets client-side.

Once the server generated html is fully rendered in the browser, we can start a client-side counterpart of the application. The client-side version picks up where the server side application left off.

Both versions of the application may use the same Svelte components, but it's important to understand that they execute independently of each other. The server-side version does not know about the client-side version and vice versa.

It's also important to understand that there is no default state sharing between client and server (e.g. data property).

Article Carousel

I decided to use server side Svelte to build an article carousel for the landing page of my blog. The idea is to use a Svelte component to cycle through articles in four of my article categories.

The carousel should load instantly on page load, so I decided to render the initial view on the server. Once the page has loaded I start the client-side counterpart of the Svelte component to dynamically cycle through the articles.

I am not known for css or design skills, so don't expect a pretty UI, but here's how I wired everything up.

I start by creating an Article component that will be used to render the articles in the carousel. The component should probably be split into two components, but keeping it as one for the purposes of this blog post.

<div class="row"> <span class="slide-show-card col-sm-3"> <h4>Angular</h4> <h5><a class="slide-show-link" href="{{angularUrl}}">{{angularTitle}}</a></h5> <div class="label label-success slide-show-count">Viewed {{angular.viewCount}} times</div> <div>{{angularIntro}}</div> </span> <span class="slide-show-card col-sm-3"> <h4>JavaScript</h4> <h5><a class="slide-show-link" href="{{javascriptUrl}}">{{javascriptTitle}}</a></h5> <div class="label label-success slide-show-count">Viewed {{javascript.viewCount}} times</div> <div>{{javascriptIntro}}</div> </span> <span class="slide-show-card col-sm-3"> <h4>Svelte</h4> <h5><a class="slide-show-link" href="{{svelteUrl}}">{{svelteTitle}}</a></h5> <div class="label label-success slide-show-count">Viewed {{svelte.viewCount}} times</div> <div>{{svelteIntro}}</div> </span> <span class="slide-show-card col-sm-3"> <h4>React</h4> <h5><a class="slide-show-link" href="{{reactUrl}}">{{reactTitle}}</a></h5> <div class="label label-success slide-show-count">Viewed {{react.viewCount}} times</div> <div>{{reactIntro}}</div> </span> </div> <script> class ArticleService { constructor() { this.articles = []; this.index = { 'angular': -1, 'javascript': -1, 'svelte': -1, 'react': -1 }; } getArticles() { return fetch('/full-article-list-json') .then((data) => { return data.json(); }) .then((articles) => { this.articles = articles; return articles; }); } getNextArticle(key) { this.index[key] = (this.index[key] + 1) % this.articles[key].length; let a = this.articles[key][this.index[key]]; return a; } } let articleService = new ArticleService(); export default { onrender() { let update = () => { this.set({angular: articleService.getNextArticle('angular')}); this.set({javascript: articleService.getNextArticle('javascript')}); this.set({svelte: articleService.getNextArticle('svelte')}); this.set({react: articleService.getNextArticle('react')}); }; articleService.getArticles() .then((articles) => { update(); if(typeof global === 'undefined') { document.querySelector('#articles').innerHTML = ''; document.querySelector('#articles-client-side').style.display = "block"; } }) .then(() => { setInterval(() => { articleService.getArticles() .then((articles) => { update(); }); }, 5000); }); }, data () { return {} }, computed: { angularTitle: angular => angular.title || '', angularIntro: angular => angular.intro || '', angularUrl: angular => `viewarticle/${angular.friendlyUrl}`, javascriptTitle: javascript => javascript.title || '', javascriptIntro: javascript => javascript.intro || '', javascriptUrl: javascript => `viewarticle/${javascript.friendlyUrl}`, svelteTitle: svelte => svelte.title || '', svelteIntro: svelte => svelte.intro || '', svelteUrl: svelte => `viewarticle/${svelte.friendlyUrl}`, reactTitle: react => react.title || '', reactIntro: react => react.intro || '', reactUrl: react => `viewarticle/${react.friendlyUrl}`, } } </script> Server

Let's take a look at the server code.

The first thing we have to do is activate the compiler by requiring svelte/ssr/register

require( 'svelte/ssr/register' );

Next we have to require the component html file to get a handle to the component.

We then call the render method and pass it an initial data object. The data object is a standard Svelte data object.

app.get('/', function(req, res) { var component = require('./app/article-show/Articles.html'); var articles = component.render({ angular: articles.angular, svelte: articles.svelte, react: articles.react, javascript: articles.javascript }); res.render('index.html', {articles: articles}); });

After calling render we get back a fully rendered component. We now have to pass this to the node view engine.

In my case I am using Express with Mustache, so I can just pass the component as an object to the render method. Then in my index.html page I use Mustache view syntax with triple curly braces to render the component on the page like so.

{{{articles}}}

Client

What we have so far is enough to render the initial view of my component, but it won't support cycling through new articles every few seconds.

To achieve this we have to start up a client-side version of the Article component.

The client side version is loaded as a standard Svelte client-side component.

import articles from './articles'; var articlesSection = new articles({ target: document.querySelector( 'main' ), data: {angular: {}, javascript: {}, svelte: {}, react: {}} });

Once the client-side version is activated we will have two components in the DOM. As soon as the client-side version is ready to take over I wipe out the server-side version.

There might be a more elegant way to do this, but I simply clear out the server generated DOM element and flip a style on the client-side version.

Demo

If you want to test out my server-side vs client-side view you can find ithere.

In addition to the article carousel I also built my main navigation as a Svelte server side component. The nav is a pure server side component with no client side counterpart.

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: JavaScriptJavaSEOReactPHPHTML
分页:12
转载请注明
本文标题:Server-side Svelte
本站链接:http://www.codesec.net/view/523391.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(38)