跳转至

前端性能面试题(山月)

prefetch 与 preload 的区别是什么

原文:https://q.shanyue.tech/fe/perf/286.html

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 286(opens new window)

Author

回答者: shfshanyue(opens new window)

<link rel="prefetch" href="style.css" as="style" />
<link rel="preload" href="main.js" as="script" /> 
  1. preload 加载当前路由必需资源,优先级高。一般对于 Bundle Spliting 资源与 Code Spliting 资源做 preload
  2. prefetch 优先级低,在浏览器 idle 状态时加载资源。一般用以加载其它路由资源,如当页面出现 Link,可 prefetch 当前 Link 的路由资源。(next.js 默认会对 link 做懒加载+prefetch,即当某条 Link 出现页面中,即自动 prefetch 该 Link 指向的路由资源

prefetch - Prefetch the page in the background. Defaults to true. Any that is in the viewport (initially or through scroll) will be preloaded.

更多信息可参考以下链接:

实现一个 once 函数,记忆返回结果只执行一次

原文:https://q.shanyue.tech/fe/perf/406.html

更多描述

类似于 lodash.once

const f = (x) => x;

const onceF = once(f);

//=> 3
onceF(3);

//=> 3
onceF(4); 

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 406(opens new window)

Author

回答者: shfshanyue(opens new window)

简单实现如下:

function once(f) {
  let result;
  let revoked = false;

  return (...args) => {
    if (revoked) return result;
    const r = f(...args);
    revoked = true;
    result = r;
    return r;
  };
} 

测试一下

> const f = () => {console.log('call'); return 3;}
< undefined

> once_f = once(f)
< (...args) => {
    if (revoked) return result
    const r = f(...args)
    revoked = true
    result = r
  }

// 第一次调用
> once_f()
< call
< 3

// 第二次调用,没有打印 call
> once_f()
< 3 

once(opens new window) 是社区使用最广泛的一个库,代码实现与上大同小异,然而每月下载量可达上亿,比 vue/react/angular 三者一个月的下载量加起来还要高一倍

如何压缩前端项目中 JS 的体积

原文:https://q.shanyue.tech/fe/perf/644.html

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 644(opens new window)

Author

回答者: shfshanyue(opens new window)

  1. terser(opens new window) 或者 uglify(opens new window),及流行的使用 Rust 编写的 swc 压缩混淆化 JS。
  2. gzip 或者 brotli 压缩,在网关处(nginx)开启
  3. 使用 webpack-bundle-analyzer 分析打包体积,替换占用较大体积的库,如 moment -> dayjs
  4. 使用支持 Tree-Shaking 的库,对无引用的库或函数进行删除,如 lodash -> lodash/es
  5. 对无法 Tree Shaking 的库,进行按需引入模块,如使用 import Button from 'antd/lib/Button',此处可手写 babel-plugin 自动完成,但不推荐
  6. 使用 babel (css 为 postcss) 时采用 browserlist,越先进的浏览器所需要的 polyfill 越少,体积更小
  7. code spliting,路由懒加载,只加载当前路由的包,按需加载其余的 chunk,首页 JS 体积变小 (PS: 次条不减小总体积,但减小首页体积)
  8. 使用 webpack 的 splitChunksPlugin,把运行时、被引用多次的库进行分包,在分包时要注意避免某一个库被多次引用多次打包。此时分为多个 chunk,虽不能把总体积变小,但可提高加载性能 (PS: 此条不减小总体积,但可提升加载性能)

Author

回答者: 1689851268(opens new window)

压缩的具体操作

  1. 去除多余字符,eg:空格,换行、注释
  2. 压缩变量名,函数名、属性名
  3. 使用更简单的表达,eg:合并声明、布尔值简化

如何优化 React 项目的性能

原文:https://q.shanyue.tech/fe/perf/645.html

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 645(opens new window)

Author

回答者: shfshanyue(opens new window)

  1. 避免不必要的渲染,shouldComponentUpdate、React.memo、React.useMemo、React.useCallback。
  2. 代码分割,React.lazy 动态加载组件
  3. 使用 react-query,对请求响应进行缓存、重发等,避免多次请求,减少网络 IO 消耗及优化渲染次数
  4. 使用 useDebounce,对值及事件处理函数进行防抖,避免状态频繁变动,优化渲染次数
  5. 使用 useImmer

如何提高首屏渲染时间?

原文:https://q.shanyue.tech/fe/perf/688.html

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 688(opens new window)

Author

回答者: shfshanyue(opens new window)

TODO

Author

回答者: illumi520(opens new window)

  1. 对于 pv 量比较高的页面,比如 b 站等流量图也比较大的,采用 ssr 采用 ssr 如何优化性能
    • 性能瓶颈在于 react-dom render/hydrate 和 server 端的 renderToString
    • 尽量减少 dom 结构, 采用流式渲染,jsonString 一个对象,而不是 literal 对象
    • server 去获取数据
    • 不同情况不同分析,减少主线程阻塞时间
    • 减少不必要的应用逻辑在服务端运行
  2. 减少依赖和包的体积
    • 利用 webpack 的 contenthash 缓存
    • 重复依赖包处理,可以采用 pnpm
    • 采用 code splitting,减少首次请求体积
    • 减少第三方依赖的体积
  3. FP (First Paint) 首次绘制 FCP (First Contentful Paint) 首次内容绘制 LCP (Largest Contentful Paint) 最大内容渲染 DCL (DomContentloaded) FMP(First Meaningful Paint) 首次有效绘制 L (onLoad) TTI (Time to Interactive) 可交互时间 TBT (Total Blocking Time) 页面阻塞总时长 FID (First Input Delay) 首次输入延迟 CLS (Cumulative Layout Shift) 累积布局偏移 SI (Speed Index) 一些性能指标可以监控性能

4.网络 prefetch cdn

网站性能优化中,如何对小图片进行优化

原文:https://q.shanyue.tech/fe/perf/705.html

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 705(opens new window)

Author

回答者: shfshanyue(opens new window)

TODO

Author

回答者: kv1991(opens new window)

通过整合小图片到一张精灵图,减少请求图片次数。

Author

回答者: illumi520(opens new window)

base64 或者搞成 svg



回到顶部