先看页面整体加载效果
Web 的性能优化有很多方法论可以来讨论,这里我先介绍一下飞天服务平台首页的业务背景,以及在业务过程中做的有针对性的优化方法。
最近在做飞天服务平台首页的过程中,遇到的页面打开性能有问题。由于飞天服务平台首页的业务特性:用户可以去配置业务模块到首页,每一个模块都可以去做二级的下钻、抽屉打开去做明细的分析,所以往往一个简单的业务指标呈现,背后带着很多业务数据的二次分析,需要二级页面或者抽屉来呈现这些业务洞察。同时用户可以在首页自定义页面的配置,如果用户配置了 10+ 卡片到首页之后,页面打开的时候同时去加载卡片,对于性能压力有很大的考验。
针对飞天服务平台的业务场景,以及之前性能优化的实践,首先我们会从尽可能缩小资源文件入手,让页面加载尽可能快。解决了资源文件文件问题之后,快速让页面可响应,让用户在体感上更加友好成了最重要的事情,所以启动了一系列关键链路优先、非关键链路渐进式加载的优化项,在做完这些优化之后,性能问题已经基本可以得到解决。
那有没有更进一步的优化呢,会在第三部分充分利用缓存-用空间换时间,讲述如何使用缓存把性能优化做到极致的过程。资源尽可能小,关键链路优先、非关键链路渐进式加载,充分利用缓存、用空间换时间三个方面也是一个渐进式的性能优化过程。
优化前的树形图
优化后的树形图 通过优化打包的方式,将静态的加载资源做到尽可能小,同时第三方库单独打包。图示为优化前 vendors 资源体积大小从 1.42 MB 优化到 384 KB。
资源加载优化的方法有很多,优化的思路也比较固定,这里就不再详细讲述,大致列举几种方式:
antd
主题和字体文件单独加载核心是在 package.json 内,对于 sideEffects 树形进行配置,如果没有副作用直接降 sideEffects 置为 false。
"sideEffects": [
"*.less" // 如果没有副作用,直接置为 false 即可
],
将依赖的包做了 treeshaking 之后,就可以做到每个页面、卡片独立打包,互不影响,在最大限度上减少了多余代码的打入,包体积也可以进一步减少。
由于业务的特殊性和抽屉交互形式的引入,飞天服务平台首页引入了很多业务实体的代码。抽屉组件很多代码引入就成了一个负担,一方面加大了资源的打包体积,一方面在页面打开的时候执行相关代码,导致页面可交互时间延长,经常需要等待页面渲染完成之后,页面才可以完全可交互。
这里的解决方法是:利用 Umi 的 dynamic 动态加载特性,分文件去加载第三方组件,同时添加一个加载的骨架屏。这样得到的效果是会在打开抽屉的时候,有一个短暂的骨架屏占位,之后渲染出内容。
/**
* @author linhuiw
* @description 异步加载组件 ProjectDetailCard
*/
import { dynamic } from 'umi';
import { Skeleton } from 'antd';
const ProjectDetailCard = dynamic({
loading: () => {
return (
<Skeleton
active={true}
paragraph={{
rows: 10,
}}
/>);
},
async loader() {
const { ProjectDetailCard } = await import(
/* webpackChunkName: "ProjectDetailCard" */ './index'
);
return ProjectDetailCard;
},
});
export { ProjectDetailCard };
<img src="image.png" loading="lazy" alt="…" width="200" height="200">
当给 img 标签设置了 loading="lazy"属性后,图片会延迟加载,直到资源与视口达到计算出的距离为止。目前浏览器本身就支持图片的异步加载,是一个性价比很高的优化点。
由于首页卡片内有很多需要交互触发的抽屉组件,导致了在页面打开的时候,会有短暂的页面渲染不可交互的时间。由于页面大量 Dom 渲染,会有 100ms 左右的不可响应时间,是一个非常不友好的体验。
这里充分利用 window.requestIdleCallback的特性,window.requestIdleCallback() 方法插入一个函数,这个函数将在浏览器空闲时期被调用。这使开发者能够在主事件循环上执行后台和低优先级工作,而不会影响延迟关键事件,如动画和输入响应。
这里主要做的优化是将弹窗的组件在浏览器空闲或者有触发的时候再去渲染,这样可以分阶段的去渲染主要展示内容。 附上分步渲染组件的示例:
import React, { useState, ReactNode, useEffect } from 'react';
// 判断是在浏览器环境还是在 Node 环境
import isNode from 'detect-node';
export const IdleUntilUrgent = ({ children, htmlElement }) => {
const [callbackId, setCallbackId] = useState(null);
const [renderChild, setRenderChild] = useState(false);
useEffect(() => {
if (!isNode) {
if (typeof window.requestIdleCallback !== 'undefined') {
// https://caniuse.com/#search=requestIdleCallback
setCallbackId(
window.requestIdleCallback(() => {
setRenderChild(true);
}),
);
} else {
setTimeout(() => {
setRenderChild(true);
});
}
}
}, []);
if (!isNode && !renderChild) {
return null;
}
// 取消这次渲染
if (!isNode && callbackId) {
window.cancelIdleCallback(callbackId);
}
return children;
};
同时页面埋点、性能检测相关的操作,也放到浏览器闲时的时候去触发。
备注:window.requestIdleCallback 需要加对应的 polyfill,推荐 requestidlecallback-polyfill 包去做 Safari 浏览器下的 polyfill。
由于飞天服务平台首页的业务特性,用户可以在首页配置非常多的卡片,如果同时去加载用户配置 10+ 个 卡片,肯定会触发性能问题。
性能表现上滚动到组件就立刻加载,肯定比 1.5 屏更好,但是 1.5 屏的渲染优化会让体验更加优秀,加载上有一个提前量,如果不是非常快速的滚动到对应卡片,体验上与直接默认加载卡片没有区别。
这里可以使用原生的 Intersection Observer API 去实现,浏览器本身提供了一种异步检测目标元素与祖先元素或 viewport 相交情况变化的方法。当然为了 API 更加友好,我使用了 react-intersection-observer这个组件库去做组件层面的懒加载。
骨架屏,尤其是精度更高的骨架屏,可以在一定程度上让用户感觉更快了。所以在骨架屏这个事情上,主要做了两个方面的骨架屏1. 卡片的加载骨架屏,卡片开始渲染初期,预渲染卡片的内容骨架 2. 表格的骨架屏(效果可以看文章开头的效果图)
简单科普下 SWR。swr 是 stale-while-revalidate 的简称,一种由 HTTP RFC 5861 (opens in a new tab) 推广的 HTTP 缓存失效策略。
最主要的能力是:我们在发起网络请求时,会优先返回之前缓存的数据,然后在背后发起新的网络请求,最终用新的请求结果重新触发组件渲染。使用 SWR,组件将会不断地、自动获得最新数据流。
UI 也会一直保持快速响应。SWR 特性在特定场景,对用户非常友好。目前我们将用户的数据存储在浏览器端数据库(IndexDB)内,配合一定的数据更新、缓存、清理机制,在页面加载过程中优先使用之前缓存的数据做一次渲染,等请求的数据返回之后,再做一次对比重新渲染。如果数据没有变化,则不需要重新渲染。
这么做的优势也很明显:
详细的技术方案,可以关注我,后续会出详细的技术文章来介绍。
基于 Service Worker 优化的原理,这里不再赘述,有很多同类型的文章。
图示为缓存优先,回退到网络的 Service Worker 策略:
目前看 Service Worker 缓存作为浏览器端和服务端代理, 拦截请求,处理响应,的确会有很好的性能提升。目前飞天服务平台首页还没有使用这个方案,后续的继续优化和性能提升,是一个可以发力的地方。
可以先看一下优化前后的数据,目前优化后页面总体在 1s 左右,做到页面的秒开。当然性能优化是没有尽头的,我这里主要是从上述三方面来讲述飞天服务平台实践过的性能优化。如果大家有更多想法也可以交流反馈。总体而言,在做到了资源尽可能小,关键链路优先、非关键链路渐进式加载之后,Web 应用的性能已经不会很差了,当做好常规的性能优化之后,相信 Web 的体验已经是非常优秀的。这个时候如果需要追求极致的性能优化,结合 SWR 和 Service Worker 的缓存,充分将资源和数据请求缓存起来,可以将 Web 的体验提升到类似原生应用的体验档次,当然性能优化也要考虑性价比,对于极致追求页面打开速度的场景,可以多做这种方案的尝试。后面这些性能优化的方案和策略,也同样会在飞天服务平台其他页面推广,相信伴随着这些策略的使用,飞天服务平台的页面初次打开体验可以提升一个档次。
本文由微信公众号阿里巴巴终端技术原创,哈喽比特收录。
文章来源:https://mp.weixin.qq.com/s/ZzOG4bU0hFof3che9nup9g
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为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 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。