秒开率对于用户的留存率有直接的影响,数据表明, 网页加载时间过长会直接导致用户流失.转转集团作为一家电商公司, 对于H5页面的秒开率有着更加严格的需求, 在主要的卖场侧页面(手机频道页、3c频道页、活动页)等重要流量入口我们都采用了SSR(服务端渲染)技术来构建页面,今天就带大家了解一下我们摸索出来的一些最佳实践.
在早期的web应用中,实际上我们都是用的服务端渲染技术, 像jsp、asp、php等各种后台模板生成的页面,前端都是拿到整张页面,不用自己去拼接DOM.后来随着前后端分离开发模式,衍生出了最主要的两种渲染方式CSR以及SSR.
CSR : 客户端渲染,整个渲染流程是: 浏览器请求url --> 服务器返回index.html(空body、白屏) --> 再次请求bundle.js、路由分析 --> 浏览器渲染bundle.js体积越大, 就会导致白屏的时间越长,给用户的体验就越差(当然,这可以借助打包构建工具来优化这部分)
交互流程图如下
图1-1客户端渲染流程图
我们来看看整个交互流程图 :
图 1-2 服务端渲染交互流程图
理解了两种渲染模式的异同,我们来看看SSR整个构建逻辑(主要以Vue-SSR为例)
我们以官网的图片为例:
图 2-1 SSR构建逻辑
从图中我们可以知道 :
在整个构建过程中, 我们有两个入口, 一个是server-entry.js, 执行server端的逻辑, 一个是client.js, 执行client端的逻辑, 然后通过会将webpack打包分成两个Bundle: 服务端bundle; 客户端bundle. Node.js会处理服务端bundle用于SSR, 客户端bundle会在用户请求时和已经由SSR渲染出的页面一起返回给用户, 然后在浏览器执行”注水”(hydrate
), 接管Vue接下来的业务逻辑.
理解了整个构建逻辑,接下来我们来看看我们是怎么运用SSR来服务我们的项目的.
卖场侧业务首页组成大同小异: 主要分首屏和第二屏, 首屏有多个模块组成, 第二屏是商品Feed流,便于读者理解, 我们抽象出了页面结构图:
图 2-2 页面结构图
而且这些页面都有一个共同的特点:
由于对于秒开率有着极高的要求,又承载了主要流量入口,结合以上页面特点,所以我们使用了SSR来提升用户体验.
经过一系列的探索和探究, 我们最终使用Nuxt.js来作为我们的技术选型.
这里提下为啥使用Nuxt.js作为我们的技术选型, 主要原因有以下几点:
目前我们使用SSR实现的主要能力有:
接下来就和大家探索其中几种能力的主要思路:
这种实现方式主要是结合asyncData在服务端异步获取数据,使用vue动态组件component的特性,来调整模块的渲染顺序; mounted生命钩子只会在客户端执行, 使用仅在客户端渲染组件的特性来实现的.
示例代码:
<template>
<!--服务端渲染,动态获取首屏模块并且加载对应模块的数据, 使用error-boundary来拦截错误-->
<template v-for="(e, i) in structureOrder">
<error-boundary>
<component :info="activityState.structure[e]"
:is="Mutations.name2Component(e)"
class="anchor"
:id="e"
:key="i" :name="e" v-if="activityState.structure[e] || e === 'bar' "/>
</error-boundary>
</template>
<!--客户端渲染-->
<client-only>
<!--滑动到可见范围加载对应的数据-->
<div :is="listComponent" :tab="labelFilter"/>
</client-only>
</template>
获取数据:
//服务端渲染数据
async asyncData({app, route, req}) {
const initData = await app.$axios.$get(host, {
params: {
name: key, from, smark, keys: `structure,base,labelFilter,navigate,redPack,${elements}`
}, headers
})
const {structureInfo, structureOrder, restStructure, anchors} = Mutations.initStructure(initData)
return {
structureInfo,
restStructure,
structureOrder, //动态返回对应模块的名称
useVideo: Mutations.checkUseVideo(req),
theme,
pageFrom: route.query.from,
isPOP,
anchors,
...formInfo
}
},
async mounted() {
//获取客户端渲染的数据
const res = await this.initData()
},
关于ErrorBoundary这个捕获错误的组件,这个组件的主要功能是使得组件级的错误不会蔓延到页面级,不会造成整个页面的白屏,考虑到服务端渲染可能会发生偶发性错误,状态容易变的不可控, 所以使用这个能力还是很有必要的, 这个组件主要使用vue提供的 errorCaptured 来捕获组件级的错误, 想详细了解这个api的作用可以去看官方文档,具体的实现如下:
const errorBoundary = Vue => {
Vue.component('ErrorBoundary', {
data: () => ({ error: null }),
errorCaptured(err, vm, info) {
this.error = `${err.stack}\n\nfound in ${info} of component`
SentryCapture(err, 1) //异常上报到sentry
return false
},
render() {
return (this.$slots.default || [null])[0] || null
}
})
}
// 全局注册errorBoundary
Vue.use(errorBoundary)
这个功能的主要作用是 : 可以根据配置json文件定制化活动页面的样式, 做到"千人千面" (一个会场的key可以配置一种样式, 但是底层代码是一套),使得元素多样化,在视觉上给用户体验带来很大提升.
我们先来看看效果示意图:
以上就是展示效果, 借住CSS注入, 我们可以根据不同的json文件来定制化页面的样式, 只需要维护一套代码, 简单高效.
实现逻辑也很简单,主要是运用了Nuxt.js框架提供的head方法:
head() {
//this.baseInfo.additionStyle是从json文件拿到的样式
//通过css权重, 可以实现样式覆盖
return {
style: [
{cssText: this.baseInfo?.additionStyle || '', type: 'text/css'}
],
__dangerouslyDisableSanitizers: ['style'] // 防止对一些选择器的特殊字符进行转义
}
},
不仅如此, 还可以实现js注入, 感兴趣的小伙伴可以自己去了解,底层原理可以了解下 vue-meta 这个库
但是, 随着业务的不断迭代, 这种注入方式还是存在很多可优化的点:
目前, 集团内部正在使用 魔方 一步一步去替代这种方式, 魔方 只需要运营同学拖拖拽拽, 就能生成一个活动页, 简单高效
其实这种优化页面的方法并不是说只适用于SSR, 其他非SSR页面也可以使用这种方式来优化;
看看我们的实现方式 :
function asyncComponent({componentFactory, loading = 'div', loadingData = 'loading', errorComponent, rootMargin = '0px',retry= 2}) {
let resolveComponent;
return () => ({
component: new Promise(resolve => resolveComponent = resolve),
loading: {
mounted() {
const observer = new IntersectionObserver(([entries]) => {
if (!entries.isIntersecting) return;
observer.unobserve(this.$el);
let p = Promise.reject();
for (let i = 0; i < retry; i++) {
p = p.catch(componentFactory);
}
p.then(resolveComponent).catch(e => console.error(e));
}, {
root: null,
rootMargin,
threshold: [0]
});
observer.observe(this.$el);
},
render(h) {
return h(loading, loadingData);
},
},
error: errorComponent,
delay: 200
});
}
export default {
install: (Vue, option) => {
Vue.prototype.$loadComponent = componentFactory => {
return asyncComponent(Object.assign(option, {
componentFactory
}))
}
}
}
实现原理主要是使用vue高阶组件, 元素到达可见范围内, 延迟加载组件;
看看效果图:
我们可以看到,只有到底部商品Feed流出现在可视范围,才去请求对应的接口
所谓大促场景,是指像 6.18, 双11,这种场景下, 面对大流量, 如何保证页面稳定? SSR是CPU密集型任务, 意味着很耗费服务器资源,集团目前主要采取的策略是:
请大家移步集团一位前端大佬写的公众号文章: [Nuxt实现的SSR页面性能优化的进一步探索与实践]
最终,看看我们最终的实现效果:
可以看到, 首屏渲染时间在594ms, 秒开率在百分之87左右;
ssr的使用过程并不是一帆风顺的, 在使用的过程中, 也总结几点不足之处:
至于如何取舍, 看各位同学的项目需求,以及运用场景;
SSR的使用有利有弊, 我们应该结合自己的业务特性去制定合适的方案, 它的优点就是快, 有利于SEO, 缺点也很明显, 比较耗费服务器资源, 对于亿级流量的超巨app来说, 理论上是不太合适的, 集团内部也有自己的一套方案来优化客户端渲染, 使得用户体验尽量向SSR靠齐.每一种技术的运用只有实践了才知道利弊,才能产生碰撞. 本文只是简单的带大家了解一条业务线上对SSR的运用, 所阐述的方面也只是冰山一角, 希望给广大开发者带来一定的启发, 前人栽树, 后人乘凉, 感谢转转FE前辈们留下的宝贵财富.
参考资料
nuxt官网: https://www.baidu.com/link?url=xy0d8KPUgTmiVoGge6g-FgdeqjJSTjxdpT0tpxZzBG_&wd=&eqid=db50cacf00052e5e000000066081587d
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/JO5SWE9wd93ICM5ccZ71FQ
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。