วันพฤหัสบดีที่ 31 มกราคม 2019
เฟรมเวิร์กฟรอนท์เอนด์จำนวนมากต้องพึ่งพา JavaScript ในการแสดงเนื้อหา ซึ่งหมายความว่า Google อาจต้องใช้เวลาสักครู่หนึ่งในการจัดทำดัชนีเนื้อหาของคุณหรืออัปเดตเนื้อหาที่จัดทำดัชนีแล้ว
วิธีแก้ปัญหาเบื้องต้นที่เราพูดคุยกันที่งาน Google I/O ในปีนี้คือการแสดงผลแบบไดนามิก ซึ่งสามารถทำได้หลายวิธี บล็อกโพสต์นี้แสดงตัวอย่างวิธีแสดงผลแบบไดนามิกโดยใช้ Rendertron ซึ่งเป็นโซลูชันโอเพนซอร์สที่ใช้ Chromium แบบ Headless เป็นหลัก
เว็บไซต์แบบใดบ้างที่ควรพิจารณาใช้การแสดงผลแบบไดนามิก
ในบรรดาเครื่องมือค้นหาหรือบ็อตโซเชียลมีเดียทั้งหมดที่ไปยังเว็บไซต์ของคุณ จะมีเฉพาะบางรายการเท่านั้นที่เรียกใช้ JavaScript ได้ Googlebot อาจต้องใช้เวลาสักครู่หนึ่งในการเรียกใช้ JavaScript ของคุณและยังมีข้อจํากัดบางประการด้วย
การแสดงผลแบบไดนามิกมีประโยชน์สำหรับเนื้อหาที่เปลี่ยนแปลงบ่อยและต้องใช้ JavaScript ในการแสดง การพิจารณาใช้การแสดงผลแบบผสมผสาน (เช่น Angular Universal) อาจช่วยให้ประสบการณ์การใช้งานเว็บไซต์ดีขึ้น (โดยเฉพาะอย่างยิ่ง เวลาที่ใช้ใน First Meaningful Paint)
การแสดงผลแบบไดนามิกทำงานอย่างไร
การแสดงผลแบบไดนามิกหมายถึงการสลับไปมาระหว่างเนื้อหาที่แสดงผลฝั่งไคลเอ็นต์และเนื้อหาที่แสดงผลล่วงหน้าสำหรับ User Agent ที่เจาะจง
คุณจะต้องใช้ตัวแสดงผล (Renderer) เพื่อเรียกใช้ JavaScript และสร้าง HTML แบบคงที่ Rendertron เป็นโปรเจ็กต์โอเพนซอร์สที่ใช้ Chromium แบบ Headless เพื่อแสดงผล แอปต่างๆ ที่มีหน้าเดียวมักจะโหลดข้อมูลในเบื้องหลังหรือเลื่อนเวลาการแสดงผลเนื้อหา Rendertron มีกลไกในการระบุว่าเว็บไซต์หนึ่งๆ แสดงผลเสร็จเมื่อใด และรอจนกว่าคำขอทั้งหมดของเครือข่ายจะเสร็จสิ้นและไม่มีงานค้าง
โพสต์นี้ครอบคลุมเรื่องต่อไปนี้
- ดูตัวอย่างเว็บแอป
- ตั้งค่าเซิร์ฟเวอร์
express.js
ขนาดเล็กเพื่อแสดงเว็บแอป - ติดตั้งและกำหนดค่า Rendertron เป็นมิดเดิลแวร์สำหรับการแสดงผลแบบไดนามิก
ตัวอย่างเว็บแอป
เว็บแอป "Kitten Corner" ใช้ JavaScript เพื่อโหลดรูปภาพแมวแบบต่างๆ จาก API และแสดงรูปในตารางกริด
ต่อไปนี้คือ JavaScript ที่ใช้
const apiUrl = 'https://api.thecatapi.com/v1/images/search?limit=50'; const tpl = document.querySelector('template').content; const container = document.querySelector('ul'); function init () { fetch(apiUrl) .then(response => response.json()) .then(cats => { container.innerHTML = ''; cats .map(cat => { const li = document.importNode(tpl, true); li.querySelector('img').src = cat.url; return li; }).forEach(li => container.appendChild(li)); }) } init(); document.querySelector('button').addEventListener('click', init);
เว็บแอปดังกล่าวใช้ JavaScript สมัยใหม่ (ES6) ซึ่ง Googlebot ยังไม่รองรับ เราใช้การทดสอบความเหมาะกับอุปกรณ์เคลื่อนที่เพื่อตรวจสอบได้ว่า Googlebot เห็นเนื้อหานั้นหรือไม่ ผลการทดสอบมีดังนี้
แม้ว่าปัญหานี้จะแก้ไขง่าย แต่ก็เป็นแบบฝึกหัดที่ดีสำหรับเรียนรู้วิธีตั้งค่าการแสดงผลแบบไดนามิก การแสดงผลแบบไดนามิกจะช่วยให้ Googlebot เห็นภาพแมวได้โดยไม่ต้องเปลี่ยนโค้ดของเว็บแอป
ตั้งค่าเซิร์ฟเวอร์
ในการให้บริการเว็บแอปพลิเคชัน เราจะใช้ express
ซึ่งเป็นไลบรารี node.js
ในการสร้างเว็บเซิร์ฟเวอร์
โค้ดของเซิร์ฟเวอร์จะมีลักษณะดังนี้ (ดูซอร์สโค้ดของโปรเจ็กต์ทั้งหมดได้ที่นี่)
const express = require('express'); const app = express(); const DIST_FOLDER = process.cwd() + '/docs'; const PORT = process.env.PORT || 8080; // Serve static assets (images, css, etc.) app.get('*.*', express.static(DIST_FOLDER)); // Point all other URLs to index.html for our single page app app.get('*', (req, res) => { res.sendFile(DIST_FOLDER + '/index.html'); }); // Start Express Server app.listen(PORT, () => { console.log(`Node Express server listening on https://localhost:${PORT} from ${DIST_FOLDER}`); });
ลองดูตัวอย่างแบบสดได้ที่นี่ คุณจะเห็นภาพแมวมากมาย หากใช้เบราว์เซอร์ที่ทันสมัย หากต้องการเรียกโครงการจากคอมพิวเตอร์ให้ทำงาน คุณต้องใช้ node.js
เพื่อเรียกใช้คําสั่งต่อไปนี้
npm install --save express rendertron-middleware node server.js
จากนั้นชี้เบราว์เซอร์ไปที่ https://localhost:8080
จากนั้นก็ตั้งค่าการแสดงผลแบบไดนามิกได้
ทำให้อินสแตนซ์ Rendertron ใช้งานได้
Rendertron เริ่มการทำงานของเซิร์ฟเวอร์ที่นำ URL หนึ่งมา แล้วส่ง HTML แบบคงที่ของ URL นั้นกลับไปโดยใช้ Chromium แบบ Headless เราจะทําตามคําแนะนําจากโปรเจ็กต์ Rendertron และใช้ Google Cloud Platform
โปรดทราบว่าคุณสามารถเริ่มต้นใช้งานด้วย Usage Tier ได้โดยไม่มีค่าใช้จ่าย การใช้การตั้งค่านี้ในเวอร์ชันที่ใช้งานจริงอาจมีค่าใช้จ่ายตามราคาที่กำหนดไว้ของ Google Cloud Platform
- สร้างโปรเจ็กต์ใหม่ในคอนโซล Google Cloud จด "รหัสโปรเจ็กต์" ด้านล่างช่องป้อนข้อมูลเอาไว้
- ติดตั้ง Google Cloud SDK ตามที่อธิบายไว้ในเอกสารประกอบและลงชื่อเข้าสู่ระบบ
-
โคลนที่เก็บ Rendertron จาก GitHub ดัวยคำสั่งนี้
git clone https://github.com/GoogleChrome/rendertron.git cd rendertron
-
เรียกใช้คำสั่งต่อไปนี้เพื่อติดตั้งส่วนที่ใช้อ้างอิงและสร้าง Rendertron ในคอมพิวเตอร์
npm install && npm run build
-
เปิดใช้แคชของ Rendertron ด้วยการสร้างไฟล์ใหม่ชื่อ
config.json
ในไดเรกทอรี Rendertron โดยมีเนื้อหาดังนี้{ "datastoreCache": true }
-
เรียกใช้คำสั่งต่อไปนี้จากไดเรกทอรี Rendertron แทนที่
YOUR_PROJECT_ID
ด้วยรหัสโปรเจ็กต์ที่จดไว้จากขั้นตอนที่ 1gcloud app deploy app.yaml --project YOUR_PROJECT_ID
- เลือกภูมิภาคที่ต้องการและยืนยันการทำให้ใช้งานได้ รอจนกระทั่งเสร็จสิ้น
- ป้อน
YOUR_PROJECT_ID.appspot.com
ของ URL คุณควรจะเห็นอินเทอร์เฟซของ Rendertron ซึ่งมีช่องป้อนข้อมูล 1 ช่อง และปุ่มอีก 2-3 ปุ่ม
ถ้าเห็นอินเทอร์เฟซบนเว็บของ Rendertron แสดงว่าคุณทำให้อินสแตนซ์ Rendertron ใช้งานได้สำเร็จ จด URL ของโปรเจ็กต์ (YOUR_PROJECT_ID.appspot.com
) ไว้เพราะคุณจะต้องใช้ในส่วนถัดไปของกระบวนการ
เพิ่ม Rendertron ไปยังเซิร์ฟเวอร์
เว็บเซิร์ฟเวอร์ใช้ express.js
และ Rendertron มีมิดเดิลแวร์ express.js
เรียกใช้คําสั่งต่อไปนี้ในไดเรกทอรีของไฟล์ server.js
npm install --save rendertron-middleware
คำสั่งนี้ติดตั้ง rendertron-middleware จาก NPM เราจึงเพิ่มรายการดังกล่าวไปยังเซิร์ฟเวอร์ได้โดยทำดังนี้
const express = require('express'); const app = express(); const rendertron = require('rendertron-middleware');
กำหนดค่ารายการบ็อต
Rendertron ใช้ส่วนหัว HTTP ของ user-agent
เพื่อระบุว่าคําขอมาจากบ็อตหรือจากเบราว์เซอร์ของผู้ใช้ ส่วนหัวนี้มีรายการ User Agent ของบ็อตที่มีการดูแลรักษาเป็นอย่างดีเพื่อใช้เปรียบเทียบ โดยค่าเริ่มต้น รายการนี้ไม่รวม Googlebot เนื่องจาก Googlebot เรียกใช้ JavaScript ได้ หากต้องการให้ Rendertron แสดงผลคำขอของ Googlebot ด้วย ให้เพิ่ม Googlebot ลงในรายการ User Agent ดังนี้
const BOTS = rendertron.botUserAgents.concat('googlebot'); const BOT_UA_PATTERN = new RegExp(BOTS.join('|'), 'i');
Rendertron จะเปรียบเทียบส่วนหัวของ user-agent
กับนิพจน์ทั่วไปนี้ในภายหลัง
เพิ่มมิดเดิลแวร์
ในการส่งคำขอของบ็อตไปยังอินสแตนซ์ Rendertron เราจำเป็นต้องเพิ่มมิดเดิลแวร์ไปยังเซิร์ฟเวอร์ express.js
มิดเดิลแวร์จะตรวจสอบ User Agent ที่ส่งคำขอและส่งต่อคำขอจากบ็อตที่รู้จักไปยังอินสแตนซ์ Rendertron ให้เพิ่มโค้ดต่อไปนี้ลงใน Server.js และอย่าลืมแทนที่ YOUR_PROJECT_ID
ด้วยรหัสโครงการ Google Cloud Platform ดังนี้
app.use(rendertron.makeMiddleware({ proxyUrl: 'https://YOUR_PROJECT_ID.appspot.com/render', userAgentPattern: BOT_UA_PATTERN }));
บ็อตที่ขอเว็บไซต์ที่เป็นตัวอย่างได้รับ HTML แบบคงที่จาก Rendertron ดังนั้นบ็อตจะไม่จำเป็นต้องเรียกใช้ JavaScript เพื่อแสดงเนื้อหา
การทดสอบการตั้งค่าของเรา
หากต้องการทดสอบว่าการตั้งค่า Rendertron ถูกต้องดีหรือไม่ ให้เรียกใช้การทดสอบความเหมาะกับอุปกรณ์เคลื่อนที่อีกครั้ง
คราวนี้ภาพแมวจะแสดงขึ้นมา ซึ่งต่างกับการทดสอบครั้งแรก ในแท็บ HTML เราจะเห็น HTML ทั้งหมดที่โค้ด JavaScript สร้างขึ้น และด้วยการตั้งค่า Rendertron จึงไม่ต้องใช้ JavaScript แสดงเนื้อหาอีกต่อไป
บทสรุป
คุณสร้างการตั้งค่าการแสดงผลแบบไดนามิกได้โดยไม่ต้องทำการเปลี่ยนแปลงใดๆ กับเว็บแอป การเปลี่ยนแปลงเหล่านี้จะช่วยให้คุณให้บริการเว็บแอปในเวอร์ชัน HTML แบบคงที่แก่ Crawler ได้