@@ -833,6 +833,68 @@ frist_script是页面中一定存在的一个script标签,script是你创建
833
833
834
834
对很多应用来说,延迟加载的部分大部分情况下会比核心部分要大,因为我们关注的“行为”(比如拖放、XHR、动画)只在用户初始化之后才会发生。
835
835
836
+ ### 按需加载
837
+
838
+ 前面的模式会在页面加载后无条件加载其它的JavaScript,并假设这些代码很可能会被用到。但我们是否可以做得更好,分部分加载,在真正需要使用的时候才加载那一部分?
839
+
840
+ 假设你页面的侧边栏上有一些tabs。点击tab会发出一个XHR请求获取内容,然后更新tab的内容,然后有一个更新的动画。如果这是页面上唯一需要XHR和动画库的地方,而用户又不点击tab的话会怎样?
841
+
842
+ 下面介绍按需加载模式。你可以创建一个require()函数或者方法,它接受一个需要被加载的脚本文件的文件名,还有一个在脚本被加载完毕后执行的回调函数。
843
+
844
+ require()函数可以被这样使用:
845
+
846
+ require("extra.js", function () {
847
+ functionDefinedInExtraJS();
848
+ });
849
+
850
+ 我们来看一下如何实现这样一个函数。加载脚本很简单——你只需要按照动态\< script\> 元素模式做就可以了。获知脚本已经加载需要一点点技巧,因为浏览器之间有差异:
851
+
852
+ function require(file, callback) {
853
+
854
+ var script = document.getElementsByTagName('script')[0], newjs = document.createElement('script');
855
+
856
+ // IE
857
+ newjs.onreadystatechange = function () {
858
+ if (newjs.readyState === 'loaded' || newjs.readyState === 'complete') {
859
+ newjs.onreadystatechange = null;
860
+ callback();
861
+ }
862
+ };
863
+
864
+ // others
865
+ newjs.onload = function () {
866
+ callback();
867
+ };
868
+
869
+ newjs.src = file;
870
+ script.parentNode.insertBefore(newjs, script);
871
+ }
872
+
873
+ 这个实现的几点说明:
874
+
875
+ - 在IE中需要订阅readystatechange事件,然后判断状态是否为“loaded”或者“complete”。其它的浏览器会忽略这里。
876
+ - 在Firefox,Safari和Opera中,通过onload属性订阅load事件。
877
+ - 这个方法在Safari 2中无效。如果必须要处理这个浏览器,需要设一个定时器,周期性地去检查某个指定的变量(在脚本中定义的)是否有定义。当它变成已定义时,就意味着新的脚本已经被加载并执行。
878
+
879
+ 你可以通过建立一个人为延迟的脚本来测试这个实现(模拟网络延迟),比如ondemand.js.php,如:
880
+
881
+ <?php
882
+ header('Content-Type: application/javascript');
883
+ sleep(1);
884
+ ?>
885
+ function extraFunction(logthis) {
886
+ console.log('loaded and executed');
887
+ console.log(logthis);
888
+ }
889
+
890
+ 现在测试require()函数:
891
+
892
+ require('ondemand.js.php', function () {
893
+ extraFunction('loaded from the parent page');
894
+ document.body.appendChild(document.createTextNode('done!'));
895
+ });
896
+
897
+ 这段代码会在console中打印两条,然后页面中会显示“done!”,你可以在< http://jspatterns.com/book/7/ondemand.html > 看到示例。
836
898
837
899
838
900
0 commit comments