欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > JavaScript惰性加载优化实例

JavaScript惰性加载优化实例

2025/4/17 23:39:22 来源:https://blog.csdn.net/u014331598/article/details/147078658  浏览:    关键词:JavaScript惰性加载优化实例

这是之前的一位朋友的酒桌之谈,他之前负责的一个电商项目,刚刚开发万,首页加载时间特别长,体验很差,所以就开始排查,发现是在首页一次性加载所有js导致的问题,这个问题在自己学习的时候并不明显,往往被大家称为编程习惯,甚至有的公司大佬进行项目框架层级的硬性规定或者封装,可以起到很好的作用,但是今天还是拿出来和大家分享一下:

场景描述

网站在首页一次性加载了所有模块的JavaScript资源,包括:

  • 首屏轮播图

  • 商品推荐列表

  • 用户评论模块

  • 页脚帮助中心

  • 未可视区域的广告和营销组件

示例代码

// 问题代码示例 - 同步加载所有脚本
import Carousel from './components/Carousel';       // 首屏必要
import ProductList from './components/ProductList'; // 首屏必要 
import Reviews from './components/Reviews';         // 需要滚动到中部才显示
import Ads from './components/Ads';                // 页尾才显示
import HelpCenter from './components/HelpCenter';  // 页脚折叠区域
​
function HomePage() {return (<><Carousel /><ProductList /><Reviews /><Ads /><HelpCenter /></>);
}

问题

  1. 首屏加载时间过长

    • 用户需要等待所有JS下载并执行完才能看到首屏内容

    • Lighthouse评分中"First Contentful Paint"指标很差

  2. 带宽浪费

    • 加载了用户可能永远不会看到的资源(如未滚动的底部内容)

  3. 主线程阻塞

    • 大量JS同步执行导致主线程长时间忙碌

    • 用户交互(如点击搜索框)出现延迟

  4. 内存占用过高

    • 初始化了所有组件,包括那些不需要立即显示的

排查思路

这个排查的思路很通用,大部份性能问题都可以从这里着手,如果是前端的新朋友,那么建议从开头编写完代码之后,多依着下面的排查思路看看自己的代码执行步骤,然后思考,会有意想不到的收获。

一、初步性能评估

  1. 打开Chrome DevTools (F12)

    • 切换到 Network 面板

    • 勾选 Disable cache (模拟首次访问)

    • 选择 Fast 3G 网络限速(放大问题)

  2. 录制加载过程

    • 刷新页面开始录制

    • 观察所有资源的加载顺序和时间线

二、网络面板分析

  1. JS加载问题识别

    • 按类型筛选 JS 资源

    • 检查:

      • 是否首屏不需要的JS过早加载

      • 是否有大体积JS阻塞渲染(红色长条)

      • JS文件是否并行加载

  2. 关键指标查看

    markdown

    复制

    - Waterfall流中查找:* 蓝色竖线(DOMContentLoaded)* 红色竖线(Load)
    - 关注:* 首屏渲染完成时间* 主线程被JS执行阻塞的时间段

三、性能面板深度分析

  1. Performance面板录制

    • 点击 Record 后刷新页面

    • 停止后查看时间线

  2. 关键区域检查

    • Main 线程活动:

      • 长任务(超过50ms的黄色块)

      • JS编译与执行(紫色部分)

    • Network 网络请求:

      • JS加载与执行的关联关系

    • Timings 标记:

      • FP/FCP/FMP/LCP等关键时间点

  3. 典型问题模式识别

    javascript

    复制

    // 问题特征示例时间线:
    [JS下载1][JS执行1][JS下载2][JS执行2]...
    // 优化后应有:
    [首屏JS下载][首屏渲染][惰性加载其他资源]

四、内存面板检查

  1. Memory面板快照

    • Heap snapshot 比较:

      • 页面刚加载时

      • 滚动到底部后

  2. 内存问题识别

    • 检查是否过早初始化了不必要组件

    • 查看保留的DOM节点数量是否异常

五、Lighthouse自动化审计

  1. 生成报告

    • 切换到 Lighthouse 面板

    • 勾选 Performance 选项

    • 点击 Generate report

  2. 关键指标关注

    markdown

    复制

    - Opportunities中的建议:* "Defer offscreen images"* "Reduce unused JavaScript"
    - Diagnostics中的:* "Avoid enormous network payloads"* "JavaScript execution time"

六、具体问题定位步骤

  1. 确定关键渲染路径

    • Performance 录制中:

      • 找到 FCP (First Contentful Paint)

      • 分析之前的所有JS活动

  2. 识别非必要JS

    javascript

    复制

    // 在Console执行:
    performance.getEntriesByType('resource').filter(r => r.initiatorType === 'script').sort((a,b) => a.startTime - b.startTime).map(r => ({name: r.name.split('/').pop(),start: r.startTime,duration: r.duration}))
  3. 加载顺序可视化

    • 使用 Network 的时序图:

      • 拖动选择首屏时间段(0-FCP)

      • 右键 → "Save as HAR with content"

尝试解决

懒加载最直接的理解可以是按序加载,并不是一个很完整的操作,而是很多的细节拼凑或者是自己平常注意一种习惯吧。下面列出我自己习惯性的思路:

1. 动态导入 (Dynamic Import)
import { lazy, Suspense } from 'react';
​
const Reviews = lazy(() => import('./components/Reviews'));
const Ads = lazy(() => import('./components/Ads'));
const HelpCenter = lazy(() => import('./components/HelpCenter'));
​
function HomePage() {return (<><Carousel /><ProductList /><Suspense fallback={<Spinner />}>{/* 当元素进入视口时加载 */}<LazyLoadComponent><Reviews /></LazyLoadComponent><LazyLoadComponent><Ads /></LazyLoadComponent><LazyLoadComponent><HelpCenter /></LazyLoadComponent></Suspense></>);
}
2. Intersection Observer实现视口触发
// 自定义懒加载组件
const LazyLoadComponent = ({ children }) => {const ref = useRef();const [isVisible, setIsVisible] = useState(false);
​useEffect(() => {const observer = new IntersectionObserver(([entry]) => {if (entry.isIntersecting) {setIsVisible(true);observer.disconnect();}},{ threshold: 0.1 });observer.observe(ref.current);return () => observer.disconnect();}, []);
​return <div ref={ref}>{isVisible && children}</div>;
};

3. 图片/iframe懒加载

<!-- 使用原生loading属性 -->
<img src="product.jpg" loading="lazy" alt="Product">
​
<!-- 或使用Intersection Observer实现 -->
<div class="lazy-image" data-src="product.jpg"></div>

性能影响数据(模拟)

指标非惰性加载惰性加载优化后
首屏加载时间4.2s1.8s
总JS体积1.8MB650KB(首屏)
Lighthouse性能评分4882
首次输入延迟(FID)320ms110ms

这些细节往往很小,但是很多,欢迎各位小伙伴一起讨论。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词