javascript加载_JavaScript加载策略

news/2024/7/10 2:06:35 标签: python, java, javascript, js, vue
<a class=javascript加载" width="403px" height="256px" style="outline: none;" />

javascript加载

2010 update: Lo, the Web Performance Advent Calendar hath moved

2010年更新: Lo, Web Performance Advent Calendar已移动

Dec 15 This article is part of the 2009 performance advent calendar experiment. Today's article is a contribution from Ara Pehlivanian, author of two JavaScript books. Please welcome Ara and stay tuned for the articles to come.

12月15日本文是2009年效果降临日历实验的一部分。 今天的文章是两本JavaScript书的作者Ara Pehlivanian的贡献。 请欢迎ARA和住宿调整的文章来。

Ara PehlivanianAra Pehlivanian has been working on the Web since 1997. He's been a freelancer, a webmaster, and most recently, a Front End Engineer at Yahoo! Ara's experience comes from having worked on every aspect of web development throughout his career, but he's now following his passion for web standards-based front-end development. When he isn't speaking and writing about best practices or coding professionally, he's either tweeting as
@ara_p or maintaining his personal site at http://arapehlivanian.com/.
@ara_p发推 文或维护其个人网站 http://arapehlivanian.com/ 。

JavaScript has a dark side to it that not many people are aware of. It causes the browser to stop everything that it's doing until the script has been downloaded, parsed and executed. This is in sharp contrast to the other dependencies which get loaded in parallel--limited only by the number of connections the browser and server are able to create. So why is this a problem?

JavaScript的阴暗面是很少有人意识到。 这将导致浏览器停止其正在执行的所有操作,直到脚本被下载,解析和执行为止。 这与并行加载的其他依赖项形成鲜明对比-其他依赖项仅受浏览器和服务器能够创建的连接数限制。 那么为什么这是一个问题呢?

Good question! Before I can answer that, I need to explain how the browser goes about building a page. The first thing a it's does once it receives an HTML document from the server is to build the DOM--an object representation of the document in memory. As the browser goes about converting HTML into the DOM, it invariably encounters references to external dependencies such as CSS documents and images. Every time it does so, it fires off a request to the server for that dependency. It doesn't need to wait for one to be loaded before requesting another, it makes as many requests as it's capable of. This way, the page gets built one node at a time and as the dependencies come in, they're put in their correct placeholders. What gums up the works though, is when a JavaScript dependency is encountered. When this happens, the browser stops building the DOM and waits for that file to arrive. Once it receives the file, it parses and executes it. Only once all of that's done does the browser continue building the DOM. I suspect this has to do with wanting to provide as stable a DOM to the script as possible. If things were in flux while the script attempted to access or even modify a DOM node, things could get dicey. Either way, the time it takes before the browser can continue depends entirely on the size and complexity of the script file that's being loaded.

好问题! 在我能回答这个问题之前,我需要解释一下浏览器如何构建页面。 一旦从服务器接收到HTML文档,它要做的第一件事就是构建DOM(内存中文档的对象表示)。 当浏览器将HTML转换为DOM时,它总是会遇到对外部依赖项(例如CSS文档和图像)的引用。 每次这样做,它都会向服务器发出该依赖项的请求。 它不需要等待一个请求被加载就可以请求另一个请求,它可以发出尽可能多的请求。 这样,页面一次建立一个节点,并且随着依赖关系的引入,它们被放置在正确的占位符中。 但是,当遇到JavaScript依赖项时,使工作更麻烦的是。 发生这种情况时,浏览器将停止构建DOM,并等待该文件到达。 收到文件后,便会解析并执行该文件。 只有完成所有这些操作后,浏览器才能继续构建DOM。 我怀疑这与希望为脚本提供尽可能稳定的DOM有关。 如果在脚本尝试访问或什至修改DOM节点时事情不断变化,则事情可能会变得扑朔迷离。 无论哪种方式,浏览器继续运行所需的时间完全取决于所加载脚本文件的大小和复杂性。

Now imagine loading a 200k JavaScript file right in the <head> of a document. Say it's a JavaScript file that's not only heavy but also does some fairly complex computing that takes half a second to complete. Imagine now what would happen if that file took a second to transfer. Did you guess? Yup, the page would be blank until that transfer and the computation were complete. A second and a half of a blank page that the visitor has to endure. Given that most people don't spend more than a few seconds on the average web page, that's an eternity of staring at a blank page.

现在,想象一下在文档的<head>中加载一个200kJavaScript文件。 假设这是一个JavaScript文件,它不仅很沉重,而且还需要花费半秒钟才能完成一些相当复杂的计算。 现在想象一下,如果该文件花费一秒钟传输将会发生什么。 你猜对了吗是的,在传输和计算完成之前,页面将为空白。 访客必须忍受的空白页的一半和一半。 鉴于大多数人在普通网页上的花费不超过几秒钟,所以盯着空白页是永恒的。

减少 (Reduce)

So how can this problem be overcome? Well, the first thing that should be done, is to reduce as much as possible, the amount of data that's being sent over the pipe. The smaller the JavaScript file, the less waiting the visitor has to do. So what can be done to reduce file size? JavaScript files can be run through a minifier such as YUI Compressor (which removes unnecessary white space and formatting, as well as comments, and is proven to reduce file size by 40-60%). Also, if at all possible, servers should be set up to gzip files before they're sent. This can drastically reduce the number of bytes that get transferred since JavaScript is plain text, and plain text compresses really well.

那么如何解决这个问题呢? 好吧,应该做的第一件事是尽可能减少通过管道发送的数据量。 JavaScript文件越小,访问者等待的时间就越少。 那么如何减少文件大小呢? 可以通过诸如YUI Compressor之类的压缩程序运行JavaScript文件(该压缩程序可以删除不必要的空格和格式以及注释,并且可以将文件大小减少40-60%)。 另外,如果可能的话,应该在发送服务器之前将服务器设置为gzip文件。 由于JavaScript是纯文本,因此可以大大减少要传输的字节数,并且纯文本的压缩效果非常好。

延期 (Defer)

So, once you've made sure your file is as small as possible, what next? Well, the first thing is to make sure the visitor has something to look at while the script is loading. Instead of loading JavaScript files in the document's <head>, put your <script> tags immediately before your page's closing </body> tag. That way, the browser will have built the DOM and begun inserting images and applying CSS long before it encounters your script tags. This also means that your code will execute faster because it won't need to wait for the page's onload event--which only fires once all the page's dependencies are done loading.

因此,一旦确定文件越小越好,下一步呢? 好吧,首先要确保在脚本加载时访问者可以看一些东西。 无需将JavaScript文件加载到文档的<head> ,而是将<script>标记放在页面关闭</body>标记之前。 这样,浏览器将在遇到脚本标签之前就已经构建了DOM并开始插入图像并应用CSS。 这也意味着您的代码将执行得更快,因为它不需要等待页面的onload事件-仅在所有页面的依赖项加载完成后才会触发。

So with the script tags placed at the end of the document, when the browser does encounter them, will still halt operations for however long it needs to, but at this point the visitor is reading your page and unaware of what's going on behind the scenes. You've just bought yourself the time to surreptitiously load your script files.

因此,将脚本标签放置在文档的末尾,当浏览器确实遇到脚本标签时,脚本标签仍会停止操作,无论需要多长时间,但这时访问者正在阅读您的页面,并且不知道幕后情况。 。 您已经为自己度过了秘密加载脚本文件的时间。

去异步 (Go Async)

There is another way to load JavaScript files which won't block your browser, and that's to insert the script tags into your page using JavaScript. Dynamically including a script tag into the DOM causes it to be loaded asynchronously. The only trouble with that is that you can't rely on the code within the script file to be available immediately after you've included it. What you'll need is a callback function that is executed once your script is done loading. There are several ways of doing this. A lot of libraries have built in async script loading functionality, so you're likely better off using that. But if you want to do it yourself, be ready to deal with the idiosyncrasies of different browsers. For example, where one browser will fire off an onload event for the script, another will not.

还有另一种加载JavaScript文件的方法,该方法不会阻止您的浏览器,那就是使用JavaScript将script标签插入页面。 在DOM中动态包含脚本标签会导致其异步加载。 唯一的麻烦是,您不能依靠脚本文件中的代码来将其包括在内。 您需要的是一个在脚本加载完成后执行的回调函数。 有几种方法可以做到这一点。 许多库都内置了异步脚本加载功能,因此最好使用它。 但是,如果您想自己做,请准备好应对不同浏览器的特质。 例如,一个浏览器将触发脚本的onload事件,而另一个浏览器则不会。

偷懒 (Be Lazy)

So now that we know how to load scripts behind the scenes, is there anything more we can do to improve performance? Of course.

因此,既然我们知道如何在后台加载脚本,我们还有什么可以做来提高性能的? 当然。

Say for example your page loads up a large script that gives your site a fancy navigation menu. What if the user never uses the navigation menu? What if they only navigate your site through links in your content? Did you really need to load that script in the first place? What if you could load the necessary code only when it was needed? You can. It's a technique called lazy loading. The principle is simple, instead of binding your fancy navigation script to the menu in your page, you'd bind a simple loader script instead. It would detect an onmouseover event for example, and then insert a script tag with the fancy nav code into the page. Once the tag is done loading, a callback function wires up all the necessary events and presto bingo, your nav menu starts working. This way, your site doesn't have to needlessly bog visitors down with code they'll never use.

假设您的网页加载了一个大型脚本,该脚本为您的网站提供了精美的导航菜单。 如果用户从不使用导航菜单怎么办? 如果他们仅通过您内容中的链接导航您的网站怎么办? 您真的需要首先加载该脚本吗? 如果仅在需要时才加载必要的代码怎么办? 您可以。 这是一种称为延迟加载的技术。 原理很简单,您可以将简单的加载程序脚本绑定到页面中,而不是将精美的导航脚本绑定到页面菜单中。 例如,它将检测onmouseover事件,然后将带有精美导航代码的脚本标签插入页面。 标签加载完成后,回调函数会连接所有必需的事件并保存宾果,您的导航菜单开始工作。 这样,您的网站就不必不必要地使访客不再使用他们永远不会使用的代码。

一口大小 (Bite Size)

In keeping with lazy loading, try to also load only the core components that are needed to make your page work. This is especially the case when it comes to libraries. A lot of the time a library will force you to load up a huge amount of code when all you want to do is add an event handler, or modify class names. If the library doesn't let you pull down only what you need, try ripping out what you want and only load that instead. There's no point in forcing visitors to download 60k of code when all you need is 4k of it.

为了保持延迟加载,请尝试也仅加载使页面正常工作所需的核心组件。 对于库,尤其是这种情况。 当您要做的只是添加事件处理程序或修改类名称时,很多时候库会迫使您加载大量代码。 如果该库不允许您仅提取所需内容,请尝试提取所需内容,然后仅加载所需内容。 当您只需要4k的代码时,就没有必要强迫访问者下载60k的代码。

你需要它吗? (Do You Need It?)

Finally, the best way to speed up JavaScript load times is to not include any JavaScript at all. A lot of times people go nuts for the latest fad and include it in their site without even asking themselves if they really need it. Does this fancy accordion thing actually help my visitors get to my content easier? Does fading everything in and out and bouncing things all over the place actually improve my site's usability? So the next time you feel like adding a three dimensional spinning rainbow tag cloud to your site, ask yourself, "do I really need this?"

最后,加快JavaScript加载时间的最佳方法是根本不包含任何JavaScript。 很多时候,人们对最新的时尚狂热,甚至不问自己是否真的需要它而将其包含在自己的网站中。 这种花哨的手风琴式的东西实际上是否可以帮助访问者更轻松地访问我的内容? 淡入淡出并在各处弹跳,是否真的改善了我网站的可用性? 因此,下次您想在自己的网站上添加三维旋转彩虹标签云时,问自己:“我真的需要这个吗?”

I'd like to thank Ara for the great article, it's pleasure for me to be the blog host!

我要感谢Ara的精彩文章,我很高兴成为博客主持人!

Also wanted to offer some additional links for your reading pleasure:

还希望提供一些其他链接以使您的阅读愉快:

  • Steve Souders has done extensive research on different options for non-blocking async loading, check out this blog post, also code examples from his book, another technique

    史蒂夫·索德斯(Steve Souders)对非阻塞异步加载的不同选项进行了广泛的研究,请查看此博客文章,以及他的书中的代码示例,另一种技术

  • Deferred eval on the SproutCore blog

    SproutCore博客上的递延评估

  • Non-blocking JavaScript downloads on the YUIblog

    YUIblog上的非阻塞JavaScript下载

  • Two articles by another JavaScript book author - Nicholas Zakas

    二篇由另一个JavaScript书的作者-尼古拉斯Zakas

  • LABjs - on-demand JavaScript loader

    LABjs-按需JavaScript加载器

  • LazyLoad - library-agnostic JS/CSS loader

    LazyLoad-与库无关的JS / CSS加载器

Please comment if you can think of more good resources on the topic.

如果您能想到该主题的更多有用资源,请发表评论。

Tell your friends about this post on Facebook and Twitter

在Facebook和Twitter上告诉您的朋友有关此帖子的信息

翻译自: https://www.phpied.com/javascript-loading-strategies/

javascript加载


http://www.niftyadmin.cn/n/1306182.html

相关文章

zTree实现获取一级节点数据

zTree实现获取一级节点数据 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"stylesheet" type…

出版一本书可以赚多少钱_今年出版5本书

出版一本书可以赚多少钱So Ill be publishing 5 books this year. Isnt that incredible? Is it even possible? And good quality books at that? Its a nice challenge (my last years challenge failed, I didnt even bother to count how bad it failed). I think its p…

zTree实现清空选中的第一个节点的子节点

zTree实现清空选中的第一个节点的子节点 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"styleshee…

zTree实现获取当前选中的第一个节点在同级节点中的序号

zTree实现获取当前选中的第一个节点在同级节点中的序号 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel&…

SpringBoot搭建简单留言板项目

简介 之前在刚开始学习JavaEE的时候写了一篇JSPServletJavaBean传统方式实现留言板的博客&#xff0c;在那篇博客中放了我跟着教材做的一个简单的留言板。一年多过去了&#xff0c;从刚开始学习servlet&#xff0c;到后来的Struts2&#xff0c;Spring&#xff0c;Hibernate&…

zTree实现更新根节点中第i个节点的名称

zTree实现更新根节点中第i个节点的名称 1、实现源码 <!DOCTYPE html> <html> <head><title>zTree实现基本树</title><meta http-equiv"content-type" content"text/html; charsetUTF-8"><link rel"stylesheet…

B+树的Java实现(B+ Tree)

B树 B Tree 定义 B树是一种多路平衡查找树,是对B树(B-Tree)的扩展. 首先,一个M阶的B树的定义为: 每个节点最多有M个子节点&#xff1b;每一个非叶子节点&#xff08;除根节点&#xff09;至少有ceil(M/2)个子节点&#xff1b;如果根节点不是叶子节点&#xff0c;那么至少有两…

利用PowerDesigner15在win7系统下对MySQL 进行反向工程(一)

利用PowerDesigner15在win7系统下对MySQL 进行反向工程 1、首先&#xff0c;安装以下的驱动 2、找到“C:\Windows\System32” 3、双击“odbcad32.exe” 4、选择“系统DSN”&#xff0c;并单击“添加” 5、创建新数据源 6、选择“MySQL Connector/ODBC5.00.11” 7、填写好MySQL驱…