175 6191 5976

添加官方微信

领创时代关于网站建设、青岛画册设计、青岛网站设计的观点和相关新闻 将我们的想法与焦点与你共享

如何通过JavaScript代码拆分获得更高的网站性能

2019-06-05 来源:小领

现代网站建设通常将所有JavaScript组合成一个大型的类似main.js这样的脚本文件。这通常包含所有页面或路由的脚本,即使用户只需要一小部分用于他们正在访问的网站页面。 不过以这种方式在网站中使用JavaScript时,网站页面的加载性能会受到影响,特别是在移动设备上进行响应式网页设计时。所以让我们可以通过JavaScript代码拆分来解决它。

如何编写更快,更轻的JavaScript代码。 代码拆分解决了什么问题?当Web浏览器看到<script>时,它需要花时间下载和处理您引用的JavaScript。这在高端设备上会感觉很快,但是加载,解析和执行未使用的JavaScript代码可能需要一段时间,而网络速度较慢且CPU速度较慢的移动设备。如果您曾经登录过咖啡店或酒店的WiFi,您会发现每个人都可能遇到网络体验缓慢的问题。花费在等待JavaScript完成启动的每一秒都可以延迟用户与您的体验交互的速度。如果您的UX依赖于JS来获取关键组件,甚至只是为简单的UI片段附加事件处理程序,情况尤其如此。

绝对值得问问自己是否需要进行代码拆分。如果您的网站需要JavaScript用于交互式内容(用于菜单抽屉和轮播等功能),或者是依赖JavaScript框架来呈现UI的单页应用程序,答案可能是“是”。代码拆分对您的网站是否值得,这是一个您需要自己回答的问题。您了解您的架构以及您的网站加载方式。值得庆幸的是,有一些工具可以帮助您。

对于那些刚接触JavaScript代码拆分的人来说,Lighthouse(Chrome开发者工具中)可以帮助您了解这是否是您网站的问题。您要查找的审核是缩短JavaScript执行时间(此处记录)。此审核会突出显示页面上可能会延迟用户与其进行交互的所有脚本。

如果你看起来有更昂贵的脚本可以更好地拆分,那么下一个要查看的工具是Chrome开发者工具中的代码覆盖功能(DevTools>右上菜单>更多工具>覆盖范围)。这可以衡量页面中未使用的JavaScript(和CSS)的数量。对于汇总的每个脚本,DevTools将显示“未使用的字节”。这是您可以考虑在用户需要时拆分和延迟加载的代码。在代码拆分JavaScript时,您可以采用几种不同的方法。这些适用于您的网站的程度往往会有所不同,具体取决于您是希望拆分页面/应用程序“逻辑”还是将库/框架与其他“供应商”分开。

动态代码拆分:我们中的许多人“静态地”导入JavaScript模块和依赖关系,以便在构建时将它们捆绑在一起。“动态”代码拆分增加了在JavaScript中定义要根据需要拆分和延迟加载的点的功能。现代JavaScript使用动态import()语句来实现这一点。我们将很快介绍这一点。入口点代码拆分:条目是您的站点或应用程序中的起点,Webpack等工具可以查看它以构建您的依赖关系树。按条目拆分对于未使用客户端路由或依赖服务器端和客户端呈现组合的页面非常有用。

对于本文中的目的,我们将专注于动态代码拆分。开始使用代码拆分,让我们优化一个简单应用程序的JavaScript性能,该应用程序通过代码拆分对三个数字进行排序 - 这是我的同事Houssein Djirdeh的应用程序。我们将用于快速加载JavaScript的工作流程是衡量,优化和监控。从这里开始。

在尝试添加任何优化之前,我们首先要测量JavaScript的性能。由于神奇的分拣机应用程序托管在Glitch上,我们将使用其编码环境。以下是如何解决这个问题:

这个简单的应用程序似乎只使用71.2 KB的JavaScript来排序几个数字。这当然不对。在我们的源src / index.js中,导入了Lodash实用程序库,我们使用sortBy(它的一个排序实用程序)来排序我们的数字。Lodash提供了一些有用的功能,但应用程序只使用了一种方法。安装和导入所有第三方依赖项是一个常见的错误,实际上你只需要使用它的一小部分。


编写自定义排序方法,而不是依赖第三方库。使用内置于浏览器中的Array.prototype.sort()。只从Lodash 导入sortBy方法而不是整个库。仅在用户需要时(当他们单击按钮时)下载用于排序的代码。选项1和2适合减少我们的包大小 - 这些可能对实际应用程序有意义。出于教学目的,我们将尝试不同的东西。选项3和4有助于提高应用程序的性能。我们将修改一些文件,只从Lodash 导入我们需要的单个sortBy方法。让我们从package.json中替换我们的lodash依赖开始:

js
import "./style.css";
import _ from "lodash";
import sortBy from "lodash.sortby";
接下来,我们将更新值的排序方式:

js
form.addEventListener("submit", e => {
  e.preventDefault();
  const values = [input1.valueAsNumber, input2.valueAsNumber, input3.valueAsNumber];
  const sortedValues = _.sortBy(values);
  const sortedValues = sortBy(values);
  results.innerHTML = `
    <h2>
      ${sortedValues}
    </h2>
  `
});
重新加载魔术数字应用程序,打开开发人员工具并再次查看“网络”面板。对于这个特定的应用程序,我们的捆绑包大小减少了四个小工作。但仍有很大的改进空间。

JavaScript代码拆分,Webpack是当今Web开发人员使用的最流行的JavaScript模块捆绑器之一。它将所有JavaScript模块和其他资产“捆绑”(组合)到Web浏览器可以读取的静态文件中。

此应用程序中的单个捆绑包可以拆分为两个单独的脚本:一个负责构成初始路线的代码。另一个包含我们的排序代码。使用动态导入(使用import()关键字),可以根据需要延迟加载第二个脚本。在我们的魔术数字应用程序中,当用户单击按钮时,可以根据需要加载构成脚本的代码。我们首先删除src / index.js中 sort方法的顶级导入:

import sortBy from "lodash.sortby";
在单击按钮时触发的事件侦听器中导入它:

form.addEventListener("submit", e => {
  e.preventDefault();
  import('lodash.sortby')
    .then(module => module.default)
    .then(sortInput())
    .catch(err => { alert(err) });
});
我们正在使用的这种动态import()功能是standardstrack建议的一部分,该建议包括以JavaScript语言标准动态导入模块的能力。Webpack已经支持这种语法。您可以在本文中阅读有关动态导入如何工作的更多信息。

它解析的语句返回的承诺。Webpack将此视为一个分裂点,它将分解为单独的脚本(或块)。返回模块后,module.default用于引用lodash提供的默认导出。Promise与另一个.then ()链接,调用sortInput方法对三个输入值进行排序。在Promise链的末尾,调用.catch()来处理由于错误而拒绝Promise的位置。在实际的生产应用程序中,您应该适当地处理动态导入错误。简单的警报消息(类似于此处使用的)是使用的,可能无法提供最佳的用户体验,让用户知道出了问题。

如果您看到像“解析错误:导入和导出可能只出现在顶层”这样的linting错误,请知道这是由于动态导入语法尚未最终确定。尽管Webpack支持它,但是Glitch使用的ESLint(一种JavaScript linting工具)的设置还没有更新到包含这种语法,但它仍然有效。我们需要做的最后一件事是在我们的文件末尾编写sortInput方法。这必须是一个函数,它返回一个从lodash.sortBy获取导入方法的函数。嵌套函数可以对三个输入值进行排序并更新DOM:

const sortInput = () => {
  return (sortBy) => {
    const values = [
      input1.valueAsNumber,
      input2.valueAsNumber,
      input3.valueAsNumber
    ];
    const sortedValues = sortBy(values);
    results.innerHTML = `
      <h2>
        ${sortedValues}
      </h2>
    `
  };
}
现在让我们最后一次重新加载应用程序,并密切关注网络面板。您应该注意在应用加载时如何只下载一个小的初始包。单击按钮以对输入数字进行排序后,将获取并执行包含排序代码的脚本/块。您是否看到数字仍然如我们所期望的那样排序?

JavaScript代码拆分和延迟加载对于修剪应用或网站的初始包大小非常有用。这可以直接导致用户更快的页面加载时间。虽然我们已经考虑将代码拆分添加到一个vanilla JavaScript应用程序,但您也可以将它应用于使用库或框架构建的应用程序。

使用JavaScript库或框架进行延迟加载,许多流行的框架支持使用动态导入和Webpack添加代码拆分和延迟加载。

以下是使用React(使用React.lazy()及其Suspense功能)延迟加载电影“描述”组件的方法,以便在组件被延迟加载时提供“加载...”回退(请参阅此处了解更多信息)细节):

import React, { Suspense } from 'react';
const Description = React.lazy(() => import('./Description'));
function App() {
  return (
    <div>
      <h1>My Movie</h1>
      <Suspense fallback="Loading...">
        <Description />
      </Suspense>
    </div>
  );
}
代码拆分有助于减少JavaScript对用户体验的影响。如果你有更大的JavaScript包,一定要考虑它,如果有疑问,不要忘记测量,优化和监控。 

版权声明:转载此文章须经 领创时代 同意,并请附上 领创时代 及本页链接http://www.leadnov.com/newsItem.aspx?id=160
创造品牌视觉体验 X 创新IT技术赋能企业
领创帮助您创新品牌战略,让品牌成为最具价值的资产。
中国·山东 青岛市市北区郑州路43号橡胶谷A栋
热线:175 6191 5976
微信:leadnov
Copyright © 2018-2020 leadnov.com 版权所有
鲁公网安备37020302372323
ICP证: 鲁ICP备18056479号

关注领创公众平台

添加官方微信

175 6191 5976