伺服器端渲染現在非常流行。但它也並非沒有缺點。預渲染是一種替代方法,在某些情況下甚至可能更好。下面我們來看看如何預先渲染vue.js應用程式。
在本文中,我們將探討預先渲染如何與vue.js一起運作,並看兩個範例:一個是node.js項目,一個是laravel專案。
相關教學推薦:node js教學 、vue.js教學 、laravel教學
#一、服務端渲染
基於javascript的應用程式的一個缺點是,瀏覽器從伺服器接收到的頁面基本上是空的。在下載並執行Javascript之前,無法建置DOM。
這意味著使用者必須等待更長的時間才能看到任何東西。如果爬蟲程式無法快速查看頁面內容,它也會對SEO產生影響。
伺服器端呈現(SSR)透過在伺服器上呈現應用程式來克服這個問題,以便客戶端在載入頁面時(甚至在Javascript運行之前)接收完整的DOM內容。
而不是瀏覽器從伺服器接收這個:
1 2 3 4 5 6 | <head> ... </head>
<body>
<div id= "app" >
<!--This is empty, Javascript will populate it later-->
</app>
</body>
|
登入後複製
使用SSR,它接收一個完整的內容頁面:
1 2 3 4 5 6 7 8 9 10 | <head> ... </head>
<body>
<div id= "app" >
<div class= "container" >
<h1>Your Server-Side Rendered App</h1>
<div class= "component-1" >
<p>Hello World</p>
<!--etc etc. This was all rendered on the server-->
</app>
</body>
|
登入後複製
伺服器端渲染缺點
你的應用程式需要在伺服器上可執行,所以你需要設計你的程式碼是“通用的”,也就是說,它可以在瀏覽器和節點伺服器上工作。
您的應用程式將運行在每個請求到伺服器,添加一個傳統的負載和緩慢的回應。快取可以部分緩解這種情況。
你只能用Node.js做SSR。如果您的主後端是Laravel、Django等,那麼您必須在主後端執行節點伺服器來處理SSR。
二、預先渲染
還有另一種方法可以解決空頁問題:預先渲染。使用這種方法,您可以在部署應用程式之前運行應用程序,捕獲頁面輸出並用捕獲的輸出替換HTML檔案。
它基本上與SSR的概念相同,只是它是在開發環境中預先部署的,而不是在活動伺服器中。
預渲染通常使用像PhantomJS這樣的無頭瀏覽器來執行,並且可以與Webpack、Gulp等一起整合到建置流程中。
預先渲染的優點
預先渲染的缺點
對照表
##額外的伺服器負載NoYesNo個人化使用者資料? N/AYesNo#
三、Vue.js预渲染示例
让我们做一个简单的例子来预渲染一个vue.js应用程序,一次在node.js环境中,一次在laravel环境中。
在这些示例中,我们将使用webpack和pre render spa插件来执行预渲染。
1、Vue和Node
第1步:项目安装
我们将使用vue-cli和webpack-simple模板。
1 2 3 | $ vue init webpack-simple vue-node-pr-test
$ cd vue-node-pr-test
$ npm install
|
登入後複製
我们还需要另外三个模块,后面还有解释。
1 | $ npm install --save-dev http-server html-webpack-plugin prerender-spa-plugin
|
登入後複製
第2步:在Webpack构建中包含index.html
Webpack -simple模板在Webpack构建输出中不包含index.html文件。然而,当我们预渲染应用程序时,我们需要覆盖我们的索引。因此,让我们将它添加到输出中,以免破坏原始的。
在我们的Webpack .config.js文件中使用html-webpack-plugin将文件包含在Webpack构建中:
1 2 3 4 5 6 7 8 | var HtmlWebpackPlugin = require(& #39;html-webpack-plugin');
module.exports.plugins.push(
new HtmlWebpackPlugin({
template: & #39;./index.html',
inject: false
}),
);
|
登入後複製
现在我们改变了我们的Webpack公共路径,因为index.html现在和其他静态资产在同一个文件夹中:
1 2 3 4 5 | output: {
path: path.resolve(__dirname, & #39;./dist'),
filename: & #39;build.js',
publicPath: & #39;/', // was originally 'dist'
},
|
登入後複製
由于路径的变化,我们还需要将index.html中的更改为。
第3步:测试Webpack生成版本
现在我们建造:
我们的dist文件夹应该是这样的:
1 2 3 4 | - dist
-- build.js
-- index.html
-- logo.png
|
登入後複製
如果我们检查dist/index.html,它会是这样的:
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html>
<html>
<head>
<meta charset= "utf-8" >
<title>vue-node-pr-test</title>
</head>
<body>
<div id= "app" ></div>
<script type= "text/javascript" src= "/build.js" ></script>
</body>
</html>
|
登入後複製
现在我们可以使用http-server并从dist文件夹中提供应用程序。默认情况下,它将运行在localhost:8080:
1 | $ ./node_modules/.bin/http-server ./dist
|
登入後複製
第4步:预渲染应用程序
现在我们的index.html文件在Webpack构建中,我们可以使用预呈现的HTML更新它。
首先,我们需要在webpack配置中添加prerender-spa-plugin。确保它在html-webpack-plugin之后。
1 2 3 4 5 6 7 8 | var PrerenderSpaPlugin = require(& #39;prerender-spa-plugin');
module.exports.plugins.push(
new PrerenderSpaPlugin(
path.join(__dirname, & #39;./dist'),
[ & #39;/' ]
)
);
|
登入後複製
PrerenderSpaPlugin的第一个参数是index.html文件的位置,第二个参数是应用程序中的路由列表。在这个例子中,我们只有一条路径。
现在我们再次建造:
我们的构建将比以前花费更长的时间,因为预渲染插件正在做的事情:
它创建一个Phantom JS实例并运行应用程序
获取DOM的快照
将快照输出到生成文件夹中的HTML文件
它会对每条路径重复这个过程,所以如果你有很多页面,构建应用程序可能需要相当长的时间。
在建立后,我们的dist/index.html现在应该包括所有预渲染的HTML:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< title >prerender-test</ title >
< style type = "text/css" >#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px
}
h1, h2 {
font-weight: 400
}
ul {
list-style-type: none;
padding: 0
}
li {
display: inline-block;
margin: 0 10px
}
a {
color: #42b983
}</ style >
</ head >
< body >
< div id = "app" >< img src = "/logo.png?82b9c7a5a3f405032b1db71a25f67021" >
< h1 ></ h1 >
< h2 >Essential Links</ h2 >
< ul >
< li >< a href = "https://vuejs.org" target = "_blank" >Core Docs</ a ></ li >
< li >< a href = "https://forum.vuejs.org" target = "_blank" >Forum</ a ></ li >
< li >< a href = "https://gitter.im/vuejs/vue" target = "_blank" >Gitter Chat</ a ></ li >
< li >< a href = "https://twitter.com/vuejs" target = "_blank" >Twitter</ a ></ li >
</ ul >
< h2 >Ecosystem</ h2 >
< ul >
< li >< a href = "http://router.vuejs.org/" target = "_blank" >vue-router</ a ></ li >
< li >< a href = "http://vuex.vuejs.org/" target = "_blank" >vuex</ a ></ li >
< li >< a href = "http://vue-loader.vuejs.org/" target = "_blank" >vue-loader</ a ></ li >
< li >< a href = "https://github.com/vuejs/awesome-vue" target = "_blank" >awesome-vue</ a ></ li >
</ ul >
</ div >
< script type = "text/javascript" src = "/build.js" ></ script >
</ body >
</ html >
|
登入後複製
2、Vue 和 Laravel
如果您跳过了Vue和Node示例,我建议您先回去阅读它,因为它包含了对任何常见步骤的更全面的解释。
第1步:项目安装
首先,我们将设置一个新的Laravel项目。
1 2 3 | $ laravel new vue-laravel-pr-test
$ cd vue-laravel-pr-test
$ npm install
|
登入後複製
我们还将增加两个我们需要的NPM模块:
1 | $ npm install --save-dev html-webpack-plugin prerender-spa-plugin
|
登入後複製
第2步:提供一个普通的HTML文件
默认情况下,Laravel在根URL处提供Blade模板文件。 为了使示例简单,我们将使用我们将在resources / views / index.html创建的以下纯HTML文件替换它
1 2 3 4 5 6 7 8 9 10 11 12 13 | <!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< title >Laravel</ title >
< link rel = "stylesheet" href = "/css/app.css" >
< body >
< div id = "app" >
< example ></ example >
</ div >
< script type = "text/javascript" src = "/js/app.js" ></ script >
</ body >
</ html >
|
登入後複製
现在,我们需要在根路径上提供该文件,而不是刀片服务器模板。将route /web.php更改为:
1 2 3 | Route::get(& #39;/', function () {
return File::get(public_path() . & #39;/index.html');
});
|
登入後複製
这实际上指向我们的build文件夹,我们很快就会生成它。
第3步:将HTML文件添加到构建中
像在节点示例中一样,我们希望在Webpack构建中包含index.html,以便稍后使用预呈现的HTML覆盖它。
我们需要做一些Webpack配置。在本例中,我使用的是Laravel 5.4,它使用的是Laravel Mix。Mix没有提供本地webpack配置文件,因为它使用自己的默认文件,所以让我们从laravel-mix模块复制一个配置文件:
1 | $ cp ./node_modules/laravel-mix/setup/webpack.config.js .
|
登入後複製
我们还需要让我们的NPM生产脚本指向这个配置文件,因此编辑包。json,并将生产脚本更改为:
1 2 | cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js
--progress --hide-modules --config=webpack.config.js
|
登入後複製
现在我们将html-webpack-plugin添加到webpack.config.js文件中。把这个添加到文件的底部上面的混合定型部分:
1 2 3 4 5 6 7 8 | var HtmlWebpackPlugin = require(& #39;html-webpack-plugin');
module.exports.plugins.push(
new HtmlWebpackPlugin({
template: Mix.Paths.root(& #39;resources/views/index.html'),
inject: false
});
);
|
登入後複製
第4步:测试Weback生成版本
现在让我们为生产和服务:
1 2 | $ npm run production
$ php artisan serve
|
登入後複製
不过,在运行应用程序时,浏览器中可能会出现错误,因为我们从未为window.Laravel.csrfToken设置值。对于这个简单的例子,注释掉会更快,所以像这样修改resources/assets/js/bootsta .js:
1 2 3 4 | window.axios.defaults.headers.common = {
& #39;X-Requested-With': 'XMLHttpRequest'
};
|
登入後複製
第5步:预渲染应用程序
我们现在需要在webpack配置中使用prerender spa插件来执行预渲染。确保它在HTML网页包插件之后。
1 2 3 4 5 6 7 8 | var PrerenderSpaPlugin = require(& #39;prerender-spa-plugin');
module.exports.plugins.push(
new PrerenderSpaPlugin(
Mix.output().path,
[ & #39;/' ]
)
);
|
登入後複製
现在我们可以做一个生产构建:
如果您选中build文件夹,dist/index.html现在应该如下所示,并使用预渲染HTML完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <!DOCTYPE html>
< html >
< head >
< meta charset = "utf-8" >
< title >Laravel</ title >
< link rel = "stylesheet" href = "/css/app.css" >
</ head >
< body >
< div id = "app" >
< div >
< div >
< div class = "col-md-8 col-md-offset-2" >
< div class = "panel panel-default" >
< div >Example Component</ div >
< div >
I'm an example component!
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
< script src = "/js/app.js" ></ script >
</ body >
</ html >
|
登入後複製
相关推荐:
2020年前端vue面试题大汇总(附答案)
vue教程推荐:2020最新的5个vue.js视频教程精选
更多编程相关知识,请访问:编程入门!!
以上是node和laravel專案中預渲染vue.js應用程式的詳細內容。更多資訊請關注PHP中文網其他相關文章!
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
-
2023-04-26 17:59:18
-
2023-04-26 17:47:48
-
2023-04-26 17:41:42
-
2023-04-26 17:37:05
-
2023-04-26 17:31:25
-
2023-04-26 17:27:32
-
2023-04-25 19:57:58
-
2023-04-25 19:53:11
-
2023-04-25 19:49:11
-
2023-04-25 19:41:54
| 僅客戶端渲染 | 服務端渲染 | 預先渲染 |
---|
#生產伺服器 | Any/none | Node.js only | Any/none |
| | | |
| | | |