前端 SSR:别让你的网站变成 SEO 黑洞

前端 SSR:别让你的网站变成 SEO 黑洞

毒舌时刻

这网站做得跟黑洞似的,搜索引擎根本爬不进去。

各位前端同行,咱们今天聊聊前端 SSR(服务端渲染)。别告诉我你还在使用纯客户端渲染,那感觉就像在没有窗户的房间里生活——能住,但看不见外面的世界。

为什么你需要 SSR

最近看到一个项目,纯客户端渲染,SEO 排名倒数,用户体验差。我就想问:你是在做网站还是在做内部工具?

反面教材

// 反面教材:纯客户端渲染 // App.jsx import React, { useState, useEffect } from 'react'; function App() { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { async function fetchData() { setLoading(true); try { const response = await fetch('/api/data'); const result = await response.json(); setData(result); } catch (error) { console.error('Error fetching data:', error); } finally { setLoading(false); } } fetchData(); }, []); return ( <div> <h1>我的网站</h1> {loading ? <div>加载中...</div> : ( <div> {data.map(item => ( <div key={item.id}> <h2>{item.title}</h2> <p>{item.content}</p> </div> ))} </div> )} </div> ); } export default App; 

毒舌点评:这代码,就像在黑暗中摸索,搜索引擎根本找不到你的内容。

正确姿势

1. Next.js SSR

// 正确姿势:Next.js SSR // 1. 安装依赖 // npx create-next-app@latest // 2. 页面组件 // pages/index.js import React from 'react'; export async function getServerSideProps() { // 服务端获取数据 const res = await fetch('https://api.example.com/data'); const data = await res.json(); return { props: { data } }; } export default function Home({ data }) { return ( <div> <h1>我的网站</h1> <div> {data.map(item => ( <div key={item.id}> <h2>{item.title}</h2> <p>{item.content}</p> </div> ))} </div> </div> ); } 

2. Nuxt.js SSR

// 正确姿势:Nuxt.js SSR // 1. 安装依赖 // npx create-nuxt-app@latest // 2. 页面组件 // pages/index.vue <template> <div> <h1>我的网站</h1> <div> <div v-for="item in data" :key="item.id"> <h2>{{ item.title }}</h2> <p>{{ item.content }}</p> </div> </div> </div> </template> <script> export default { async asyncData({ $axios }) { // 服务端获取数据 const { data } = await $axios.get('https://api.example.com/data'); return { data }; } }; </script> 

3. Remix SSR

// 正确姿势:Remix SSR // 1. 安装依赖 // npx create-remix@latest // 2. 路由组件 // app/routes/index.jsx import { json } from '@remix-run/node'; export async function loader() { // 服务端获取数据 const response = await fetch('https://api.example.com/data'); const data = await response.json(); return json({ data }); } export default function Home() { const { data } = useLoaderData(); return ( <div> <h1>我的网站</h1> <div> {data.map(item => ( <div key={item.id}> <h2>{item.title}</h2> <p>{item.content}</p> </div> ))} </div> </div> ); } 

4. React 18 SSR

// 正确姿势:React 18 SSR // 1. 安装依赖 // npm install react react-dom express // 2. 服务端代码 // server.js import express from 'express'; import React from 'react'; import { renderToString } from 'react-dom/server'; import App from './App'; const app = express(); app.get('*', async (req, res) => { // 服务端获取数据 const response = await fetch('https://api.example.com/data'); const data = await response.json(); const html = renderToString(<App data={data} />); res.send(` <!DOCTYPE html> <html> <head> <title>我的网站</title> </head> <body> <div>${html}</div> <script> window.__INITIAL_DATA__ = ${JSON.stringify(data)}; </script> <script src="/bundle.js"></script> </body> </html> `); }); app.listen(3000, () => { console.log('Server is running on port 3000'); }); // 3. 客户端代码 // App.jsx import React from 'react'; function App({ data }) { return ( <div> <h1>我的网站</h1> <div> {data.map(item => ( <div key={item.id}> <h2>{item.title}</h2> <p>{item.content}</p> </div> ))} </div> </div> ); } export default App; // 4. 客户端入口 // client.js import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App data={window.__INITIAL_DATA__} /> </React.StrictMode> ); 

毒舌点评:这才叫前端 SSR,服务端渲染内容,搜索引擎友好,用户体验好,再也不用担心 SEO 问题了。

Read more

AI+playwright+robotframework实现AI大模型驱动的web UI自动化测试

文章目录 * 前言 * 一、playwright与selenium 对比 * 二、AI-playwright MCP * 三、Playwright封装设计建议 * robotframerwork-browser 介绍 前言 前些日子将团队内的UI自动化完成了重构,由之前使用的selenium的迁移到了新生的工具playwright。 在AI大模型的加持下,脚本质量稳定和编写效率上得到了明显提升。刚刚发了一个关于AI 编写自动化接口测试的博客,看起来反响不错,所以又写了这篇文章与大家分享。本文从playwright与selenium 对比出发,尽量用简单语言来描述,一篇文章不太可能教会你如何去写,更多的是思路与设计的分享 一、playwright与selenium 对比 关于对比,之前有博主总结的蛮好,直接引用了 Playwright 与Selenium对比。我稍微总结一下,便于理解,从原理上对比 * selenium 使用“代理”webdriver 协议来统一接口对接不同厂家的浏览器 * playwright直接和各个浏览器原生底层调试协议来通信,

前端打工人必看:Promise.then()链式调用3天吃透(含踩坑血泪史)

前端打工人必看:Promise.then()链式调用3天吃透(含踩坑血泪史)

@[toc]( 前端打工人必看:Promise.then()链式调用3天吃透(含踩坑血泪史)) 前端打工人必看:Promise.then()链式调用3天吃透(含踩坑血泪史) 说实话,Promise这玩意儿我到现在有时候还会写错。不是不懂原理,就是那种"脑子会了手不会"的感觉,你懂的。今天咱们不整那些虚的,就把我这些年踩过的坑、流过的泪、砸过的键盘,统统掏出来给你看。 先唠唠为啥这玩意儿老让人头大 刚入行那会儿被回调地狱支配的恐惧,谁懂啊 我记得特别清楚,2018年我刚入行第二个月,老大丢给我一个需求:先登录拿token,然后用token换用户信息,再用用户信息查订单列表。听起来很简单对吧?我当时是这么写的: // 警告:以下代码包含令人不适的内容,请谨慎观看login(username, password,function(token){getUserInfo(token,function(userInfo){getOrderList(userInfo.userId,

B/S 架构:现代 Web 应用的核心架构模式

前言 在当今高度互联的数字时代,Web 应用已成为企业运营、公共服务和日常生活的基础设施。无论是电商平台、在线办公系统,还是政府服务平台,其背后都依赖于一种核心的软件架构模式——B/S 架构(Browser/Server Architecture,浏览器/服务器架构)。 作为对传统 C/S 架构(Client/Server)的演进与优化,B/S 架构凭借其跨平台性、集中式维护、部署便捷性以及强大的可扩展能力,已成为现代 Web 应用开发的事实标准。 一、什么是 B/S 架构? B/S 架构(Browser/Server Architecture)是一种基于 Web 的多层客户端-服务器软件架构模型。其核心思想是: 将用户界面、业务逻辑与数据存储进行分层解耦,用户通过标准

Flutter 三方库 webdriver 的鸿蒙化适配指南 - 掌控全自动端向测试、浏览器自动化实战、鸿蒙级精密 QA 专家

Flutter 三方库 webdriver 的鸿蒙化适配指南 - 掌控全自动端向测试、浏览器自动化实战、鸿蒙级精密 QA 专家

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 webdriver 的鸿蒙化适配指南 - 掌控全自动端向测试、浏览器自动化实战、鸿蒙级精密 QA 专家 在鸿蒙跨平台应用执行复杂的 Web 自动化测试(如模拟用户在高并发下的登录流程、处理复杂的 DOM 树抓取或是实现一个具备全自动回测能力的 CI/CD 流水线)时,如果依赖手动测试或简单的 HTTP 拨测,极易在处理“动态元素渲染”、“多窗口会话指控”或“JavaScript 异步执行”时陷入回归测试漏洞。如果你追求的是一种完全对齐 W3C WebDriver 协议规范、支持多种驱动后端且具备极致工程掌控力的方案。今天我们要深度解析的 webdriver——一个专注于浏览器指控的顶级框架,正是帮你打造“鸿蒙超感 QA 中心”的核心重器。 前言