pppr - 解決 JavaScript
無法被搜尋引擎正確索引的問題
Kewang
● 王慕羣 Kewang
● Java / JavaScript
● HBase / PostgreSQL / MongoDB / ElasticSearch
● Git / DevOps
●
熱愛開源
LinkedinLinkedin kewangtwkewangtw
SlideShareSlideShare kewangkewang
GmailGmail cpckewangcpckewang
FacebookFacebook Kewang 的資訊進化論Kewang 的資訊進化論
devopsday taipeidevopsday taipei '17'17
hadoopconhadoopcon '14 '15'14 '15
mopconmopcon '14'14
jcconfjcconf '16 '17 '18'16 '17 '18
modernwebmodernweb '18 '19'18 '19
GitHubGitHub kewangkewang
FunlidayFunliday kewangkewang
coscupcoscup '20'20
5
Agenda
● CSR & SSR
● Why SSR?
● How SSR?
● What is prerender?
● pppr - enhanced prerender
6
CSR & SSR
7
Rendered page
8
Rendered page
9
CSR - client side rendering
10
CSR - client side rendering
總行數就是 12 行
11
SSR - server side rendering
12
SSR - server side rendering
總行數超過 500 行
13
14
15
16
17
18
19
20
21
22
23
Why SSR?
24
Social media
25
Social media
26
Social media
27
Meta tags
28
Meta tags
29
Meta tags
30
Meta tags
31
SEO
32
SEO
33
SERP - Search Engine Results Page
34
SERP - Search Engine Results Page
35
How SSR?
36
JavaScript framework SSR solutions
● Vue.js
– Nuxt.js
● Angular
– Angular Universal
● React
– Next.js
37
Next.js SSR example
38
Common SSR steps
1. Write server code at client page
2. Modify webpack build flow
39
vue-hackernews-2.0
40
vue-hackernews-2.0
41
vue-hackernews-2.0
42
Common SSR steps - server.js
43
Common SSR steps - server.js
比對出合適的路由
44
Common SSR steps - server.js
比對出合適的路由
對應正確的路徑參數
45
Common SSR steps - server.js
比對出合適的路由
對應正確的路徑參數
取得對應的 metadata
46
Common SSR steps - server.js
比對出合適的路由
對應正確的路徑參數
回傳結果
取得對應的 metadata
47
Common SSR steps - metadata.js
48
Common SSR steps - metadata.js
不想被搜尋引擎 index
49
Common SSR steps - webpack.js
50
SSR cons
51
SSR cons
● Code complexity increases
52
SSR cons
● Code complexity increases
● Can't separate server and client code
53
SSR cons
● Code complexity increases
● Can't separate server and client code
● Every route need an extra API to generate data
54
SSR cons
● Code complexity increases
● Can't separate server and client code
● Every route need an extra API to generate data
● Avoid to run `window` or other DOM objects at server code
55
SSR cons
● Code complexity increases
● Can't separate server and client code
● Every route need an extra API to generate data
● Avoid to run `window` or other DOM objects at server code
● You need a full-stack engineer
56
What is prerender?
57
Introduction
58
System diagram
client
CDN
puppeteerNginx
Web server
59
System diagram
client
CDN
puppeteersend request Nginx
Web server
60
System diagram
client
CDN
puppeteersend request Nginx
Web server
non-crawler
61
System diagram
client
CDN
puppeteersend request Nginx
Web server
crawler
non-crawler
62
System diagram
client
CDN
puppeteersend request Nginx
Web server
crawler
non-crawler
if no cache
63
System diagram
client
CDN
puppeteersend request Nginx
Web server
crawler
non-crawler
if no cache
request
64
Reverse Proxy - Nginx
65
Reverse Proxy - Nginx
crawler
66
Reverse Proxy - Nginx
crawler
forward to prerender
67
Reverse Proxy - Nginx
crawler
forward to prerender
direct to origin
68
Pyramid of Puppeteer
69
Pyramid of Puppeteer
70
Pyramid of Puppeteer
71
Pyramid of Puppeteer
72
Pyramid of Puppeteer
73
pppr - enhanced prerender
74
pppr - enhanced prerender
https://github.com/funliday/pppr
75
DEMO
76
Zero configuration
77
LRU cache
78
Retry times
79
Endpoint
80
Callback
81
If you want to build a prerender service
82
Without cache
expressjs
clientclientclientclientclient
83
Without cache
expressjs
clientclientclientclientclient
84
Without cache
expressjs
puppeteer
clientclientclientclientclient
85
With cache
expressjs
clientclientclientclientclient
86
With cache
expressjs
clientclientclientclientclient
87
With cache
expressjs
has cache
clientclientclientclientclient
88
With cache
expressjs
has cache
N
clientclientclientclientclient
89
With cache
expressjs
puppeteer
has cache
N
clientclientclientclientclient
90
With cache
expressjs
puppeteer
has cache
N Y
clientclientclientclientclient
91
With cache
expressjs
puppeteer
has cache
N
return
cache
Y
clientclientclientclientclient
92
Without open new page per request
client
93
Without open new page per request
client
A page
94
Without open new page per request
client
A page
B page
95
Without open new page per request
client
A page
B rendered
B page
96
Without open new page per request
client
A page
B rendered
B page
A unexpected error
97
With open new page per request
client
98
With open new page per request
client
A page
99
With open new page per request
client
A page
B page
100
With open new page per request
client
A page
B rendered
B page
101
With open new page per request
client
A page
B rendered
B page
A rendered
102
Modify user agent
103
Modify user agent
HeadlessChrome
104
Modify user agent
HeadlessChrome
105
Modify user agent
Chrome
106
Without handle redirection
expressjs
puppeteer
HTTP client
107
Without handle redirection
expressjs
puppeteer
HTTP client
108
Without handle redirection
expressjs
puppeteer
HTTP client
status 30x
109
Without handle redirection
expressjs
puppeteer
HTTP client
status 30x
N
110
Without handle redirection
expressjs
puppeteer
HTTP client
renderer
status 30x
N
111
Without handle redirection
expressjs
puppeteer
HTTP client
renderer
status 30x
Y
N
112
With handle redirection
expressjs
puppeteer
HTTP client
113
With handle redirection
expressjs
puppeteer
HTTP client
114
With handle redirection
expressjs
puppeteer
HTTP client
status 30x
115
With handle redirection
expressjs
puppeteer
HTTP client
status 30x
N
116
With handle redirection
expressjs
puppeteer
HTTP client
renderer
status 30x
N
117
With handle redirection
expressjs
puppeteer
HTTP client
renderer
status 30x
YN
118
With handle redirection
expressjs
puppeteer
HTTP client
renderer
status 30x
return 30x
YN
119
Handle query string
120
Handle query string
取得除了 url 外的其他參數
121
Handle query string
取得除了 url 外的其他參數
重組成完整的 URL
122
Conclusion
123
Conclusion
124
Conclusion
● Client solution: SSR or Framework solution
125
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
126
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
127
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
– Mix server & client code at one page
128
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
– Mix server & client code at one page
– Cache API
129
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
– Mix server & client code at one page
– Cache API
– Full-stack engineer
130
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
– Mix server & client code at one page
– Cache API
– Full-stack engineer
● Server solution: pppr
131
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
– Mix server & client code at one page
– Cache API
– Full-stack engineer
● Server solution: pppr
– Pure server code and configuration
132
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
– Mix server & client code at one page
– Cache API
– Full-stack engineer
● Server solution: pppr
– Pure server code and configuration
– Cache page and CDN
133
Conclusion
● Client solution: SSR or Framework solution
– Universal JavaScript
– Extra API
– Mix server & client code at one page
– Cache API
– Full-stack engineer
● Server solution: pppr
– Pure server code and configuration
– Cache page and CDN
– More and more user-agents
134
References
●
Rendering on the Web
●
Client-Side, Static, and Server-Side Rendering
●
React and Server Side Rendering (SSR)
●
vuejs/vue-hackernews-2.0
●
Implement dynamic rendering with Rendertron
●
Puppeteer Tutorial
●
Prerender in the Cloud
●
prerender 1粉絲頁文章
●
prerender 2粉絲頁文章
●
prerender 3粉絲頁文章
pppr - 解決 JavaScript 無法被搜尋引擎正確索引的問題

pppr - 解決 JavaScript 無法被搜尋引擎正確索引的問題