Vue 首屏加载优化(非服务器渲染)

2019-02-21 13:50 #旧文章

以我的这个博客作为例子,文章的数据要通过后端的一个接口获取,而只有在页面加载完成,beforeMount 被调用时才会去调用这个接口获取文章数据,这就导致网页加载出来后还要显示一会 Loading 才能显示出文章。对于用户来说使体验下降了,特别是网络不好的用户;对于搜索引擎来说,搜索引擎不会等待异步加载的数据,所以搜索引擎无法获取到有价值的信息。

作为对策,我们可以使用 Vue 的服务器渲染框架,但我的服务器内存并不是特别大,并不打算用这个方案。于是我又想到了一个方案。

前端修改

Vue 网页都会有一个 HTML 文档,在这个文档上我们可以在 body 的开头(保证这段代码在 Vue 加载前执行)加上这几行代码

<script>
try {
var INIT_DATA = JSON.parse("{{.data}}");
} catch (ignore) {} // error means that this page wasn't fulfilled by backend
</script>

这几行代码会尝试将一个字符串解析成 json 对象,如果解析失败就直接忽略掉错误。

后端修改

前端给出了这一串代码,接下来就是后端去填充数据了。我后端用的是 iris,我新建了一个和前端相同的路由

app.Get("/article/{id:int64}/*", controller.Article.RenderArticle)

然后用这个控制器去向 HTML 中填充数据

func (c *articleCtrl) RenderArticle(ctx iris.Context) {
articleId, err := ctx.Params().GetInt64("id")
var data []byte
data, err = json.Marshal(c.getArticle(ctx, articleId))
if err == nil {
ctx.ViewData("data", string(data))
}
_ = ctx.View("index.html")
}

这样服务器就将前端页面中的 {{.data}} 替换成了本来应该通过 axios 获取的数据,节省了一次异步数据加载。

现在直接访问我的文章时会直接返回这样的数据

INIT_DATA已被替换
INIT_DATA 已被替换

这样就完成了优化,其他后端语言可以根据原理类推。