响应式和国际化的一些思考

306 阅读5分钟

333.gif 项目支持中英文静态切换, 并不刷新页面, 支持PC, iPad和移动端的响应式, 并且会根据用户的语言和屏幕信息, 返回预先渲染好的页面 访问链接(需翻墙): www.charlie-zoldyck.cn 备用链接,vercel国内可能不稳定okx-juster5.vercel.app/

目前只实现了首页和p2p交易页面, 点击头部导航栏所有菜单都会跳转到p2p页面, 点击logo跳转回首页

github链接为: github.com/Juster5/cha…

架构图:

okx项目流程图 (1).jpg

技术栈为Next.js, 通过vercel serverless部署, 接口数据来源OKX官网, 以下是一些实现方式, 欢迎指正:

国际化方案

Web端在区分国际化不同站点时, 一般有以下三种方案:

  1. 用不同的二级域名或者顶级域名区分, 例如sg.apple.com; www.applec.sg
  2. 域名相同, 路径不同, 例如www.apple.com/sg, www.apple.com/cn
  3. 域名相同, 路径也相同, 通过cookie来区分

方案选择: 第一种的坏处是每次切换页面时需要刷新页面, 并且顶级域名需要申请; 第二种如果路由是前端路由则页面不需要刷新, 后端路由则需要刷新; 第三种则不需要刷新页面, 只需要在cookie中设置切换的语言即可, 用户体验最好

本项目同时实现了第2,3种, 优先根据路由, 然后再根据cookie来区分

首先假设用户第一次访问时, 域名是不带语言路径的,也没有设置cookie, 当请求来Next.js服务端时, 工作流程如下:

获取cookie, 设置cookie

  1. 首先判断用户的请求头中是否有携带预先设置好的语言, 如果有则直接用
  2. 如果没有, 则取浏览器请求头中支持的语言,accept-language
  3. 在请求头的accept-language中和服务端支持的语言中做交集, 然后取优先级高的, 同时需要考虑语言相同地区不同时, 例如zh-CN和zh-TW, 在没有zh-TW, 应把zh-CN作为返回的语言

服务端根据cookie语言进行渲染

通过上面的步骤, 拿到了本次访问的语言, 然后初始化i18n实例, 因为该i18n实例是只用于服务端渲染, 只会渲染首页, 首页可以做得简单一点, 不用backend, localstore等插件; 然后通过next.js和i18n, 渲染html字符串返回给浏览器, 并把此次渲染的语言设置到到浏览器的cookie中

浏览器根据cookie语言进行渲染

服务端渲染后返回给浏览器的是html字符串, 并绑定没有dom事件, 所以浏览器需要再渲染一遍, 此时就需要保证服务端和浏览器渲染的页面一致的, 所以浏览器就需要根据上个步骤中服务端返回的cookie中语言来渲染页面, 才能保证两端的页面一致, 并且浏览器在切换语言时, 也需要将语言设置到cookie中; 另外浏览器的i18n实例, 需要http backend, localstorage等插件, 异步加载语言包, 同时要保证语言包返回之前不渲染, 不然渲染的页面会和服务端页面不一致从而导致报错, 所以页面需要包裹在Suspense组件中

响应式

本项目主要根据768, 1024, 1270来区分不同设备, 并以移动端优先的方式来开发

响应式之CSS

CSS媒体查询是响应式最常见的手段, 本项目以移动端优先的原则, 先实现小屏的样式, 再通过媒体查询的方式, 将大屏的样式放在后面往上覆盖, 并且多用vw,vh, 百分比的属性来设置宽度, 例如

img {
   width: 8vw;
}
img and @media min-width: 1024px{
  width: 10vw;
}
img and @media min-width: 1270px{
  width: 16vw;
}

响应式之JS

CSS响应式, 只能帮我们实现一些简单的基础功能, 但是有些功能却无法用CSS实现, 例如我们在小屏幕要隐藏一张图片, 即使设置了display:none, 图片还是会请求, 这时就需要通过JS来设置不同元素是否渲染来实现, 同时一些媒体资源也需要在不同尺寸的设备加载不同清晰度的资源, 这时也需要JS根据不同设备的宽度,来给资源的链接添加清晰度的后缀

同时在渲染完页面的时候, 将设备宽度提前设置在cookie中, 下次访问时服务端就可以根据cookie中的宽度来渲染不同的页面;

根据语言和屏幕信息预渲染页面

next.js根据预先定义好的不同语言和不同屏幕, 穷举, 然后进行预渲染, 例如中文和英文下的各3种宽度的, 6种页面如下:

Screen Shot 2023-01-08 at 8.41.41 PM.png

然后用户下次访问的时, 根据cookie中的语言和设备信息, 直接将预渲染的页面直接返回, 这样既可以提高访问速率, 又可以降低服务端压力

结尾

以上基本就是我对响应式和国际化项目的一些思考, 还有一个P2P页面是纯客户渲染的页面, 主要用于做单元测试, 鉴于篇幅原因就不做介绍了,感谢阅读