1. 使用骨架屏,初始化页面加loding图
什么是骨架屏呢?骨架屏(Skeleton Screen)是指在页面数据加载完成前,先给用户展示出页面的大致结构(灰色占位图),在拿到接口数据后渲染出实际页面内容然后替换掉。Skeleton Screen 是近两年开始流行的加载控件,本质上是界面加载过程中的过渡效果。 假如能在加载前把网页的大概轮廓预先显示,接着再逐渐加载真正内容,这样既降低了用户的焦灼情绪,又能使界面加载过程变得自然通畅,不会造成网页长时间白屏或者闪烁。这就是Skeleton Screen!
Skeleton Screen 能给人一种页面内容“已经渲染出一部分”的感觉,相较于传统的 loading 效果,在一定程度上可提升用户体验。
目前生成骨架屏的技术方案大概有三种:
- 使用图片、svg 或者手动编写骨架屏代码:使用 HTML + CSS 的方式,我们可以很快的完成骨架屏效果,但是面对视觉设计的改版以及需求的更迭,我们对骨架屏的跟进修改会非常被动,这种机械化重复劳作的方式此时未免显得有些机动性不足;
- 通过预渲染手动书写的代码生成相应的骨架屏:该方案做的比较成熟的是 vue-skeleton-webpack-plugin,通过 vueSSR 结合 webpack 在构建时渲染写好的 vue 骨架屏组件,将预渲染生成的 DOM 节点和相关样式插入到最终输出的 html 中。
// webpack.conf.js
const SkeletonWebpackPlugin = require('vue-skeleton-webpack-plugin');
plugins: [
//...
new SkeletonWebpackPlugin({
webpackConfig: {
entry: {
app: resolve('./src/entry-skeleton.js')
}
}
})
]
该方案的前提同样是编写相应页面的骨架屏组件,然后预渲染生成骨架屏所需的 DOM 节点,但由于该方案与 vue 相关技术直接关联,在当今前端框架三分天下的大环境下,我们可能需要一个更加灵活、可控的方案;
3 . 饿了么内部的生成骨架页面的工具:该方案通过一个 webpack 插件 page-skeleton-webpack-plugin 的方式与项目开发无缝集成,属于在自动生成骨架屏方面做的非常强大的了,并且可以启动 UI 界面专门调整骨架屏,但是在面对复杂的页面也会有不尽如人意的地方,而且生成的骨架屏节点是基于页面本身的结构和 CSS,存在嵌套比较深的情况,体积不会太小,并且只支持 history 模式。
// webpack.conf.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { SkeletonPlugin } = require('page-skeleton-webpack-plugin')
const path = require('path')
plugins: [
//...
new HtmlWebpackPlugin({
// Your HtmlWebpackPlugin config
}),
new SkeletonPlugin({
pathname: path.resolve(__dirname, `${customPath}`), // 用来存储 shell 文件的地址
staticDir: path.resolve(__dirname, './dist'), // 最好和 `output.path` 相同
routes: ['/', '/search'], // 将需要生成骨架屏的路由添加到数组中
})
]
2. 减少http请求和冗余数据,轻量化接口数据
前端在初始化编辑窗口时分别通过了4个接口请求了不同资源。通过和后端协商将4个接口改为一个接口,同时对返回的数据进行删减,只返回前端使用到的数据。
3.1 组件,路由懒加载
拆分页面。分担加载压力 具体实现:juejin.cn/post/698572…
3.2 组件渲染
拿react举例,组件分割方面不要太深。需要控制组件的渲染,尤其是深层组件的render。 老生常谈的话题,我们可以一些方式来优化组件渲染
- 声明周期控制 - 比如react的shouldComponentUpdate来控制组件渲染。
- 官网提供的api- PureComponent
- 控制注入组件的参数
- 分配组件唯一key
4. 配置nginx优化
-
压缩文件
开启gzip可以在vue-cli2脚手架中把config/index.js中的productionGzip设置为truelocation { gzip on; //开启压缩 gzip_typestext/htmltext/plaintext/css; //指定需要压缩的文件类型,默认为text/html gzip_min_length 512; //需要进行压缩的最小文件大小(单位字节) } 复制代码 -
优化缓存分配
nginx使用缓存存储请求和返回数据,优化缓存分配可以节约内存空间以及减少cpu的使用。可以将常用的js,CSS和和图片设置在浏览器本地长时间缓存,这样用户第一次打开页面后,会在本地缓存上述内容,提高了以后打开的页面加载速度,节省服务端大量带宽。 -
配置白名单
5. 优化wepack打包机制
使用插件件webpack-bundle-analyzer查看项目所有包及体积大小
- 精简打包代码,压缩代码
purifyCS打包优化去重去无效代码
UglifyJsPlugin对js文件进行压缩,从而减小js文件的大小,加速load速度。 注意此插件会拖慢webpack的编译速度,建议在开发阶段将其关闭,部署的时候再开启。
Tree Shaking删除没用到的代码。这样的功能对于构建大型应用时是非常好的 - 依赖按需引入 去除冗余依赖
如:iview ui采用按需引入 - 代码分包
- 去除非必要文件
6.使用CDN
CDN主要功能是在不同的地点缓存内容,通过负载均衡技术,将用户的请求定向到最合适的缓存服务器上去获取内容
7.1图片转base64
wepack中的url-loader对未设置或者小于limi设置的图片进行转换,以base64的格式被img的src所使用;而对于大于limit byte的图片用file-loader进行解析。
7.2 图片压缩
图床工具是自带压缩功能的,压缩后直接上传到CDN上。 如果公司没有图床工具,我们该如何压缩图片呢?我推荐几种我常用的方式
8.后台分布式部署,负载均衡
9、页面数据懒加载
减少每次请求数据的数量,通过下拉加载更多的方式加载更多数据
10、接口调用同步改异步(非有必要不要使用同步);
11、减少首屏调用的接口数量;
12、模块或者图片懒加载
分批加载,默认显示5个图片, 点击加载更多查询其他图片
13、去掉没用的打印
14、谨慎使用”文本截断“智能截断,使用字符数截断。
文本截断动态计算需要耗费一定的性能
15、等比例修改图片尺寸大小
const zipImgUrl = (str) => {
const url = replaceToHttps(str);
if (url.indexOf('.gif') > -1) {
return url;
}
return ${url.replace('405x552', '60x87').replace('220x293', '90x120')};
};
使用方式:
const url = zipImgUrl(originUrl)
注: 需要服务端支持
16、图片预加载
图片预加载:预先请求图,然后可缓存在浏览器本地
const img = new Image();
img.src = element;
充分利用浏览器中任务队列的空闲时期,有空闲即预加载图片 window.requestIdleCallback()
17、优化入口文件的体积大小,减少首屏渲染时间。
webpack打包优化,或者使用vite
18、系统内使用tab 批量打开详情页面。
升级HTTP1.1 → HTTP 2.0
19 node middleware
中文(node 中间件)
中间件主要是指封装所有Http请求细节处理的方法。一次Http请求通常包含很多工作,如记录日志、ip过滤、查询字符串、请求体解析、Cookie处理、权限验证、参数验证、异常处理等,但对于Web应用而言,并不希望接触到这么多细节性的处理,因此引入中间件来简化和隔离这些基础设施与业务逻辑之间的细节,让我们能够关注在业务的开发上,以达到提升开发效率的目的。
使用node middleware合并请求。减少请求次数。这种方式也是非常实用的。
20 web worker
Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。
合理实用web worker可以优化复杂计算任务。这里直接抛阮一峰的入门文章:传送门
21 缓存
缓存的原理就是更快读写的存储介质+减少IO+减少CPU计算=性能优化。而性能优化的第一定律就是:优先考虑使用缓存。
缓存的主要手段有:浏览器缓存、CDN、反向代理、本地缓存、分布式缓存、数据库缓存。
22.预渲染
预渲染相对于SSR比较简单,预渲染可以极大的提高网页访问速度。无需服务器实时动态编译,采用预渲染,在构建时针对特定路由简单的生成静态HTML文件
使用prerender-spa-plugin 插件
23.ssr
客户端渲染:
又称为前端渲染,起源于js的兴起,ajax让前端渲染更加成熟,前端专注于ui,后端专注于逻辑,真正意义上实现了前后端的分离,通过约定好的API来交互,后端提供数据,前端根据数据生成DOM插入HTML页面。初次渲染大都是将原html中的数据标记{{}}替换,鼠标右击查看源码,页面代码不可以在源代码中看到,性能消耗在客户端
优点:减少服务器压力,可以实现局部刷新,无需每次都请求完整的页面,体验更好 缺点:前端耗时较多,首屏渲染慢,渲染前要下载一堆js和css文件,不利于SEO,爬虫看不到完整的代码
服务端渲染:
又称为后端渲染,服务器端在返回html之前,在html特定的区域特定的符号里用数据填充,再给客户端,客户端只负责解析HTML。鼠标右击点击查看源码时,页面代码可以在源代码中看到。性能消耗在服务器端,用户达到一定程度的时候,后端会考虑缓存部分数据,避免消耗过多的资源重复渲染。
优点:前端耗时少,首次渲染快,更快的内容到达时间,利于SEO
缺点:网络传输数据量大,占用部分服务器运算资源,用户体验差,不容易维护,前端修改部分html/css后端也要改
附:前端性能分析工具
1、chrome NetWork和performance
2、webpack-bundle-analyzer: 项目构建后生成的bundle包是压缩后的。webpack-bundle-analyzer是一款包分析工具。
3、PerformanceNavigationTiming:获取各个阶段的响应时间,我们所要用到的接口是PerformanceNavigationTiming接口。
PerformanceNavigationTiming 提供了用于存储和检索有关浏览器文档事件的指标的方法和属性。 例如,此接口可用于确定加载或卸载文档需要多少时间。
性能测试工具
1 Pingdom
2 Load Impact
3 WebPage Test
4 Octa Gate Site Timer
5 Free Speed Test