技术标签: html5 react 前端面试 javascript
初始阶段 -> 加载优化
运行阶段 -> 渲染优化
#####问题分析
结论:所有加载慢的问题最终都可以归纳成两个问题 多 和 大。Tips:还有网速不好和电脑太渣
#####问题讲解
模拟面试对话
Q: 面试官爸爸 A: 你
Q:那既然你已经知道了首页加载慢的几个原因,那我先问你首页加载图片过多怎么处理?
A:减少图片不就完了吗
Q:那我们的首页就是有这么多图片怎么办?
如何分析:看看淘宝怎么解决
A: 可以通过懒加载的方式来减少首屏图片的加载量
Q: 懒加载是什么原理?
如何分析:看看懒加载的库
<img alt="A lazy image" data-src="lazy.jpg">
<------ 滚动到特定位置的时候 ------>
<img alt="A lazy image" src="lazy.jpg" data-src="lazy.jpg">
A: 懒加载原理就是监听滚动条事件,如果(滚动条距离浏览器顶部的高度 === 图片距离顶部的高度),那么就将 data-src 的值赋值到 src 上。
Q: 那假设首页的小图片就是很多,比如有很多个小 ICON 怎么办?
如何分析:还是看看淘宝怎么解决
A: 可以分别使用 iconfont 和雪碧图来处理小图标和小图片
总结:
首页加载图片过多的问题,可以通过以下几种方法解决:
- 通过懒加载的方式处理非首屏的图片
- 对于小图标可以采用 iconfont 的方式解决
- 对于小图片可以采用雪碧图的方式解决
Q: 首页的请求量过多怎么解决?
如何分析:
先通过工具来确定是哪些类型的资源请求过多
通过浏览器的 Network 可以确定首页加载的资源和请求量
requests:请求数量
resources:前端资源总大小
DOMContentLoaded: 浏览器已经完全加载了 HTML, 其他静态资源( JS, CSS, 图片等)并没有下载完毕(能看,不能用)
Load:浏览器已经加载了所有的静态资源(能用了)
通过 converge 来查看代码的使用状况
A: 可以通过减少资源的请求量
Q: 只有通过合并静态资源的方式才能减少资源请求量吗?
如何分析:
除了从资源层面来解决问题,还可以从我们自己写的代码本身来考虑。
对于引入的一些比较大型的第三方库,比如 组件库(antd,element-ui),函数库(lodash)等,务必设定按需加载。Tips: 一般都是用 Babel 插件来实现的
可以通过前端路由懒加载的方式(只限于 SPA 应用)
A: 当然不是,还可以从代码层面的优化,比如说:
1. 如果在项目中引入了比较大型的第三方库,那就可以通过特定的 Babel 插件来进行按需加载
2. 在路由层面也可以使用 React lazy 进行动态路由的加载,从而可以减少首页的 JS 和 CSS 的大小
Q:那我问你为什么 React lazy 可以进行动态路由的加载?
如何分析:先看看使用方式
// 1. 引入 react lazy, 并且使用 import 动态导入组件
import { lazy } from 'react'; // 静态导入
lazy(() => import('./Home')); // 动态导入
// 2. 引入 Suspense 组件,并使用 Suspense 将根组件包裹起来,并使用 fallback props 传入 loading 组件
import { Suspense } from 'react';
// 注意:使用 lazy 加载的组件,必须是 Suspense 子组件,或者孙组件
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
动态导入(dynamic import):当代码运行 import 的时候,再导入组件
import("./math").then(math => {
console.log(math.add(16, 26));
});
// 类似于 fetch,都是返回一个 Promise
fetch("./math").then(math => {
console.log(math.add(16, 26));
});
演示 Webpack 的代码分割
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ghvtVgx5-1622953813865)(./assets/1.png)]
结论:
import(‘xxx’) 返回的是一个 Promise
Webpack 只要遇到了 import(‘xxx’),就会把括号里引入的内容单独打一个包
A: 首先 React lazy 是使用了 dynamic import 的标准,webpack 只要遇到了 dynamic import, 就会把里面引入的内容单独打一个包。
由于 dynamic import 返回的是一个 Promise,所以可以使用 Promise 的状态来做渲染的流程控制。
如果当前 Promise 是 pending 状态,那么就渲染 Loading 组件,如果 Promise 是 resolve 状态那么就渲染动态导入的组件。
总结:
首页的请求量过多,可以通过一些手段来减少资源的请求量,比如:
- 通过 nginx 服务器来做资源文件的合并或者通过 Webpack 等打包工具进行物理打包
- 在代码层面,对于需要引入一些大型第三方库的时候,可以通过特定的 Babel 插件来进行按需加载
- 还有可以使用 React lazy 或其他动态导入方案来进行前端路由层面的动态加载,从而可以减少首页的 JS 和 CSS 的大小
Q: 首页请求的资源(CSS、JS、图片…)过大怎么解决?
A: 把资源变小不就完了吗?
Q: 怎么变小?
A:
/usr/local/etc/nginx
)#####答题思路
对于首页加载慢的问题,一般是由于首页加载资源过多,并且资源过大导致。所以应对的策略就减少资源的数量以及减小资源的大小。
- 对于图片可以懒加载,减小首屏图片加载量。以及对于小图标和小图片和分别使用 iconfont 和 雪碧图来解决,最大程度减少首屏图片数量,从而提升首页渲染性能。
- 对于其他资源可以通过打包(nginx combo 或者 Webpack 打包)来合并资源,并可以通过懒加载路由的方式来减小首页 JS 的加载量
- 减小资源的方式可以通过压缩和混淆加密来减小文件体积,图片则可以使用工具来压缩或者使用 webp 格式。
- 同时可在服务器端开始 gzip 压缩来最大化减少所有文件体积。
前端中最常见资源:HTML、CSS、JS、图片
####2. 优化图片的做法
Q: 好,那你刚刚说可以使用自动化工具对图片进行压缩,你是使用什么工具?
A: 用 熊猫站 不就完了吗?
如何分析
熊猫站:智能压缩 PNG 和 JPG 的一个网站
Q: 那你认为为什么这个工具可以同比例无损压缩?
如何分析
看看熊猫站的描述
通过相似颜色“量化”的技术来减少颜色数量,并且可以将 24 位的 PNG 文件转化成 8位的彩色图片。同时可以将不必要的元数据进行剥离。
–> 翻译成人话
通过减少颜色的数量以及不必要的数据来实现文件压缩
A:通过减少颜色的数量以及不必要的数据来实现文件压缩
Q: 非常 nice,但是这是方式不是有一个问题?难道每当我需要处理图片的时候,就要进入这个网站去上传一下吗?这样不仅仅效率低,还不安全。
A: 熊猫站很佛系的,他们把图片压缩工具 开放 出来了。可以使用 npm 安装开源包,就可以在我们本地进行图片压缩啦。
Q: 那除了这个方式还有什么其他的方式来优化图片吗?
如何分析
对图片进行转码 -> base64 格式
A: 可以使用 Webpack 的 url-loader 进行图片策略配置,将小图转换成 base64 格式,因为 base64 格式的图片的作用是减少资源的数量,但是 base64 格式的图片会增大原有图片的体积
A: 还有一种方式就是使用 webp 格式的图片
如何分析
图片格式有很多种,PNG、JPG、GIF,还有新的 WebP 格式
WebP 的优势:
根据 Google 的测试,同等条件等比例无损压缩后的 WebP 比 PNG 文件少了 26% 的体积。并且图片越多,压缩后的体积优势越明显。
压缩率比较,JPG vs WebP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fv0IZczI-1622953813867)(./assets/2.jpg)]
加载时间比较,JPG vs WebP
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2bcji073-1622953813868)(./assets/3.jpg)]
#####答题思路
图片的优化,也是从两个方面来考虑:太多 和 太大。
可以通过懒加载减少图片的请求,或者通过雪碧图来合并图片,以及将小图转化成 base64 的格式,来解决多的问题。
图片大的问题,可以通过自动化压缩工具来压缩图片,或者使用 WebP 格式的图片。
#####问题分析
#####问题讲解
Q: 我问你,怎么使用 Webpack 进行打包优化?
A: 少 和 小
Q: 怎么样少,怎么样小
如何分析
少 -> 使用 Webpack 进行物理打包。
小 -> 使用 Webpack 进行混淆和压缩,所有与 Webpack 优化相关的配置都是在 optimization 这个配置项里管理。
从 webpack 4 开始,会根据你选择的 mode 来执行不同的优化,不过所有的优化还是可以手动配置和重写。
development:不混淆,不压缩,不优化
production:混淆 + 压缩,自动内置优化
结论:只需要将 mode 改成 production 即可
A: 使用 Webpack 对代码进行混淆和压缩,并且可以使用 React lazy 进行拆包,结合路由进行按需加载。
Q: 那这里是不是有个问题?既然你对文件进行拆包处理,那么肯定会造成文件变多,是不是有矛盾?
如何分析
其实不冲突,因为拆包后的文件,不可能同时加载的,所以就不会造成同一时间资源请求过多的请求。
但是要注意打包策略
我们通常会把包,分为两类
第三方包(node_modules 里面的)
自己实现的代码(src 目录里面的)
- 公共的
- 非公共的
所以我们可以把第三方包打一个包,公共的代码打一个包,非公共的代码打一个包。
第三方包:改动频率 – 小
公共代码包:改动频率 – 中
非公共代码包:改动频率 – 高
所以可以将 打包策略 结合 网络缓存 来做优化
对于不需要经常变动的资源(第三方包),可以使用 Cache-Control: max-age=31536000
(缓存一年) 并配合协商缓存 ETag
使用(一旦文件名变动才会下载新的文件)
对于需要频繁变动的资源(代码包),可以使用 Cache-Control: no-cache
并配合 ETag
使用,表示该资源已被缓存,但是每次都会发送请求询问资源是否更新。
A: 其实不冲突,因为拆包后的文件,不可能同时加载的,所以就不会造成同一时间资源请求过多的请求。但是可以使用 Webpack 的 optimization.splitChunks 进行打包策略的优化。将 node_modules 单独打包,以及将自己实现的代码也可以分为公共包和非公共包,并且分开打包。
最后还可以结合网络缓存来做加载性能优化。
#####答题思路
Webpack 打包优化,也是从两个方面来考虑:太多 和 太大。
- 可以通过设置 mode = production 来默认实现 Webpack 对代码的混淆和压缩,从而最大程度的减少代码体积
- 使用 Webpack + dynamic import 并结合路由的入口文件做拆包处理。
- 并且可以设定一些打包策略,并配合网络缓存做最终的加载性能优化。
####4. 实现 CDN 加速
为什么 CDN( 解决方案 -> nginx ) 可以实现加速
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2BRya1u4-1622953813869)(./assets/4.jpeg)]
游戏分区:北京一区,上海一区,广东一区…
Tips:CDN 服务器就是在你家门口放一台服务器,把所有的静态资源都同步到你家门口这台服务器上,以后只要你访问这个网站,都直接从这台服务器上下载静态资源。
Http1.1 请求:对于同一个协议、域名、端口,浏览器允许同时打开最多 6个 TCP 连接(最多同时发送 6个请求)
主站 Request URL: https://www.taobao.com/
JS&CSS Request URL: https://g.alicdn.com/??kg/home-2017/1.4.17/lib/style/lazy.css
图片 Request URL: https://img.alicdn.com/tfs/TB1_uT8a5ERMeJjSspiXXbZLFXa-143-59.png
字体 Request URL: https://at.alicdn.com/t/font_403341_n8tj33yn5peng66r.woff
扩展:Http2.0: 引入了多路复用的机制,可以最大化发送请求数量。
CDN 服务器主要是用来放静态资源的服务器,可以用来加速静态资源的下载
CDN 之所以能够加速,是因为会在很多地方都部署 CDN 服务器,如果用户需要下载静态资源,会自动选择最近的节点下载
同时由于 CDN 服务器的地址一般都跟主服务器的地址不同,所以可以破除浏览器对同一个域名发送请求的限制
####1. 渲染十万条数据如何不造成卡顿
为什么渲染很多条数据会造成浏览器卡顿
为什么渲染很多条数据会造成浏览器卡顿
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-olQwyv6s-1622953813871)(./assets/5.jpg)]
结论:
- 无论是浏览器中的 DOM 和 BOM,还是 NodeJS,它们都是基于 JavaScript 引擎之上开发出来的
- DOM 和 BOM 的处理最终都是要被转换成 JavaScript 引擎能够处理的数据
- 这个转换的过程很耗时
- 所以在浏览器中最消耗性能的就是操作 DOM
指导原则:尽可能的减少 DOM 的操作
eg:假如有一个需求,我们要在一个页面中 ul 标签里渲染 十万 个 li 标签。
// 插入十万条数据
const total = 100000;
let ul = document.querySelector('ul'); // 拿到 ul
// 懒加载的思路 -- 分段渲染
// 1. 一次渲染一屏的量
const once = 20;
// 2. 全部渲染完需要多少次,循环的时候要用
const loopCount = total / once;
// 3. 已经渲染了多少次
let countHasRender = 0;
function add() {
// 创建虚拟节点,(使用 createDocumentFragment 不会触发渲染)
const fragment = document.createDocumentFragment();
// 循环 20 次
for (let i = 0; i < once; i++) {
const li = document.createElement('li');
li.innerText = Math.floor(Math.random() * total);
fragment.appendChild(li);
}
// 最后把虚拟节点 append 到 ul 上
ul.appendChild(fragment);
// 4. 已渲染的次数 + 1
countHasRender += 1;
loop();
}
// 最重要的部分来了
function loop() {
// 5. 如果还没渲染完,那么就使用 requestAnimationFrame 来继续渲染
if (countHasRender < loopCount) {
// requestAnimationFrame 叫做逐帧渲染
// 类似于 setTimeout(add, 16);
// 帧:一秒钟播放多少张图片,一秒钟播放的图片越多,动画就约流畅
// 1000/60 = 16
window.requestAnimationFrame(add);
}
}
loop();
结论:
- 可以使用 document.createDocumentFragment 创建虚拟节点,从而避免引起没有必要的渲染
- 当所有的 li 都创建完毕后,一次性把虚拟节点里的 li 标签全部渲染出来
- 可以采取分段渲染的方式,比如一次只渲染一屏的数据
- 最后使用 window.requestAnimationFrame 来逐帧渲染
导致浏览器卡顿的原因一般都是操作 DOM 的次数太频繁。
如果想要渲染很多条数据不造成卡顿,那么就一定要尽可能的减少操作 DOM 的次数。
比方说 React 的虚拟 DOM,本质上就是用 JS 数据来模拟真实 DOM树,从而大大减少了操作真是 DOM 的次数。
还有在渲染的时候,可以使用 document.createDocumentFragment 创建虚拟节点,从而避免引起没有必要的渲染
也可以采取分段渲染的方式,最后使用 window.requestAnimationFrame 来逐帧渲染
记住:
在前端中性能优化的点主要分为两个阶段:
初始阶段,主要就是加载方面优化的问题。所有问题的指导原则就两点:
- 尽可能的减少前端资源的数量
- 尽可能的减小前端资源的大小
运行阶段,主要就是渲染方面优化的问题。只要是在浏览器中,所有的问题的指导原则就是:
- 尽可能的减少操作 DOM
文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大
文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码
文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版
文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗
文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程
文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0
文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader
文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型
文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写
文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录
文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点
文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文