2

我正在开发一个可通过模块扩展的大型项目。每个模块都可以拥有自己的 javascript 文件,该文件可能只需要在一个页面、使用此模块的多个页面,甚至所有页面(如果它是全局扩展名)上需要。

现在,每当更新或安装新模块时,我都会将所有 .js 文件合并到一个文件中。客户端只需加载一个“大” .js 文件,但要为每一页解析它。假设有人安装了很多模块并且 .js 文件增长到 1MB-2MB。继续这条路线是否有意义,或者我应该在需要时包含每个 .js。

这可能会导致每个页面多出 10-15 个 http 请求。同时,.js 文件的解析时间会减少,因为我只需要为每个页面加载一小部分。同时,浏览器不会尝试执行当前页面甚至不需要甚至可能执行的 js 代码。

比较这两种情况对我来说相当困难,因为我必须重写很多代码。在我继续之前,我想知道是否有人遇到过类似的问题以及他/她是如何解决的。我最担心的是js文件的解析时间增长太多。通常网络延迟是最大的问题,但我从来不需要处理这么多可能的模块/扩展 -> js 文件。

4

2 回答 2

1

如果这两个条件为真,那么只要您执行要求(如下),您走哪条路并不重要。

条件 1:javascript 文件在标准浏览器中运行,这意味着它们不会在苹果 ios uiWebView 应用程序(html5 iphone/ipad 应用程序)中运行

条件2:初始页面加载时间无关紧要。换句话说,这更像是一个 Web 应用程序,而不是一个网页。所以用户每天登录,长时间保持登录,做很多事情......注销......第二天回来......

要求:

将 javascript 文件、css 文件和所有图像放在 Web 服务器上的 /cache 目录下。告诉 Web 服务器在标头中发送 1 年的 max-age(仅针对此目录和子目录)。然后,一旦浏览器下载了文件,它就不会再浪费一次往返于 Web 服务器询问它是否有最新版本。

然后您将需要实现 javascript 版本控制,通常通过在 js 包含行中添加“?jsver=1”来完成。然后随着每次更改增加版本。

使用 chrome 检查器并确保设置正确。在第一次请求之后,浏览器在 1 年内不再发送 Etag 或再次向 Web 服务器请求文件。(硬重新加载将再次下载文件...因此使用链接和用户通常采用的标准导航路径进行测试。还要查看 Web 服务器日志以查看哪些请求被切断。

好的浏览器会将 javascript 编译为机器码,编译后的代码将位于浏览器的缓存中等待执行。这就是条件 #1 很重要的原因。今天,唯一不会 JIT 编译 js 代码的浏览器是 uiWebView 内的 Apple Safari,只有在苹果应用程序中运行 html/js 时才会发生这种情况(并且该应用程序是从应用商店下载的)。

希望这是有道理的。我已经完成了这些事情,并且大大减少了网络往返次数。阅读 Etags 以及浏览器如何进行往返以确定是否使用当前版本的 js/css/images。

另一方面,如果您正在构建一个网站并且您想针对第一次访问者进行优化,那么越少越好。只让浏览器下载第一个页面视图绝对需要的内容。

于 2013-08-05T01:29:39.317 回答
0

你真的应该使用按需 JavaScript。只加载 90% 的用户会使用的内容。对于大多数人不会使用的东西,请将它们分开并按需加载。此外,如果压缩后的 JavaScript 超过 2 兆字节,你应该认真重新考虑你在做什么。

function ondemand(url,f,exe)
{
 if (eval('typeof ' + f)=='function') {eval(f+'();');}
 else
 {
  var h = document.getElementsByTagName('head')[0];
  var js = document.createElement('script');
  js.setAttribute('defer','defer');
  js.setAttribute('src','scripts/'+url+'.js');
  js.setAttribute('type',document.getElementsByTagName('script')[0].getAttribute('type'));
  h.appendChild(js);
  ondemand_poll(f,0,exe);
  h.appendChild(document.createTextNode('\n'));
 }
}


function ondemand_poll(f,i,exe)
{
 if (i<200) {setTimeout(function() {if (eval('typeof ' + f)=='function') {if (exe==1) {eval(f+'();');}} else {i++; ondemand_poll(f,i,exe);}},50);}
 else {alert('Error: could not load \''+f+'\', certain features on this page may not work as intended.\n\nReloading the page may correct the problem, if it does not check your internet connection.');}
}

示例用法:加载example.js(第一个参数),轮询函数example_init1()(第二个参数)和1(第三个参数)意味着一旦轮询找到它就执行该函数......

function example() {ondemand('example','example_init1',1);}
于 2013-08-04T18:47:34.960 回答