改善JavaScript Web应用程序的性能

JavaScript is one if not the most popular programming language in the world. Found in web pages, software, mobile apps, console applications, etc.

JavaScript是世界上最受欢迎的编程语言之一。 在网页,软件,移动应用程序,控制台应用程序等中找到。

JavaScript is everywhere and it is definitely here to stay. The problem with this language is with its rise, a lot of applications that use it feel "janky" (slow). We are here today to try and optimize (reduce jank in) our JavaScript applications.

JavaScript无处不在,而且绝对可以保留。 这种语言的问题在于它的兴起,许多使用它的应用程序感到“简陋”(缓慢)。 我们今天在这里尝试并优化(减少垃圾邮件)我们JavaScript应用程序。

节流和去抖动 ( Throttling & Debounce )

When we add event listeners to user actions like a scroll, we ignore the fact that listener(s) fire when our events get triggered. This is a potential bottleneck for our JavaScript application.

当我们将事件侦听器添加到用户动作(如滚动)时,我们将忽略触发事件时侦听器触发的事实。 这是我们JavaScript应用程序的潜在瓶颈。

Take the scroll event for example, when we do something like this

以滚动事件为例,当我们做这样的事情时

function scrollHandler() {
    return console.log('yippeeeee');
}

window.addEventListener('scroll', scrollHandler);

Everytime a user scrolls, "yippeeeee" gets logged to the console.

每次用户滚动时,“ yippeeeee”都会记录到控制台。

This doesn't seem bad, but with more expensive operations like checking if an element is in the viewport so we can animate, this becomes expensive with time and uses more memory.

这看起来似乎还不错,但是如果执行更昂贵的操作(例如检查元素是否在视口中以便我们进行动画处理),则随着时间的推移它会变得很昂贵,并且会占用更多的内存。

A simple way to fix this is to either debounce or throttle the scrollHandler function. Wait, what?

解决此问题的一种简单方法是debouncethrottle scrollHandler函数。 等一下

It sounds complicated, but:

听起来很复杂,但是:

Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called."

防反跳强制在不经过一定时间的情况下才再次调用该函数。 就像“仅在经过100毫秒而不调用它时才执行此函数”中一样。

while

Throttling enforces a maximum number of times a function can be called over time. As in "execute this function at most once every 100 milliseconds."

节流会强制函数在一段时间内被调用的最大次数。 如“每100毫秒最多执行一次此功能”。

A quick example, using Lodash to debounce our application is

一个简单的示例,使用Lodash来反跳我们的应用程序是

window.addEventListener('scroll', _.debounce(scrollHandler, 300));

// or

window.addEventListener('scroll', _.throttle(scrollHandler, 300));

Another library I'll recommend is Underscore. You can either use one of the libraries above or you can rip the functions out of the codebase and add to yours.

我推荐的另一个库是Underscore 。 您可以使用上面的库之一,也可以将功能从代码库中提取出来并添加到您的库中。

切换到HTTP / 2并且不捆绑 ( Switch to HTTP/2 and don't bundle )

HTTP/2 is beginning to rise and unlike before where the best advice we got when serving JavaScript files was to combine our files into a large bundle, now we don't need to do that anymore.

HTTP / 2开始兴起,与以前不同的是,在提供JavaScript文件时,我们获得的最佳建议是将文件合并成一个大包,现在我们不再需要这样做了。

HTTP/2 is multiplexed meaning that it's built to handle many file requests in a more optimal form. HTTP/2 can use one TCP connection to request many files unlike HTTP/1 where we had separate connections for each request. This makes HTTP/2 a lot faster when compared to HTTP/1 where we could only request files one at a time.

HTTP / 2是多路复用的,这意味着它可以以更优化的形式处理许多文件请求。 HTTP / 2可以使用一个TCP连接来请求许多文件,这与HTTP / 1不同,在HTTP / 1中,每个请求都有单独的连接。 与HTTP / 1相比,HTTP / 2一次只能请求一个文件,这使HTTP / 2的速度大大提高。

Thus serving up many files is now a good thing, as long as you are using HTTP/2. But not too much (too much of anything is bad).

因此,只要您使用的是HTTP / 2,提供许多文件现在是一件好事。 但是不要太多(太多的东西都是不好的)。

修剪脂肪 ( Trim the fat )

If you use NPM to install dependencies, then you have a lot of junk in your build file. From a meme of Guy Fieri to localization files you "may" use.

如果使用NPM安装依赖项,则在构建文件中会有很多垃圾。 从Guy Fieri的模因到您可以使用的本地化文件。

Instead of including the entire codebase to use a part of it, just include what you need. Take Lodash for example, it comes with a lot of functions we may use, instead of keeping what we "may" use, why not require what we want.

不必包括整个代码库以使用一部分代码,而只需包括您需要的内容即可。 以Lodash为例,它带有许多我们可能使用的功能,而不是保留我们“可能”使用的功能,为什么不要求我们想要什么。

Like this:

像这样:

// Load the full build.
var _ = require('lodash');

// Load only the array helper.
var arr = require('lodash/array');

// Load only the debounce function.
var debounce = require('lodash/debounce');

Doing this will reduce file size and speed up parsing by the browser.

这样做将减小文件大小并加快浏览器的解析速度。

缩小 ( Minify )

This has been one of most talked about JavaScript optimization technique ever.

这是有史以来最受关注JavaScript优化技术之一。

Minification refers to the removal of unwanted/cumbersome elements from our JavaScript source.

缩小是指从我们JavaScript来源中删除不需要/繁琐的元素。

Unwanted refers to comments, semi-colons, whitespace etc. While cumbersome refers to shortening function and variable names, reducing an if-else into ternary etc.

多余的是指注释,分号,空格等。繁琐的是指缩短函数和变量名,将if-else减少为三进制等。

We can achieve minification with build tools like UglifyJs, Google Closure compiler or online tools like JS Compress, JS minifier etc.

我们可以使用UglifyJsGoogle Closure编译器等构建工具或JS CompressJS minifier等在线工具来实现最小化

异步和延迟 ( Async & Defer )

async and defer are attributes we can add to script tags to make them either load asynchronously to the page or defer until the page has completely loaded.

asyncdefer是我们可以添加到脚本标签的属性,以使它们要么异步加载到页面,要么延迟直到页面完全加载。

Doing either async or defer doesn't block the DOM from rendering, which makes the application feel faster.

进行asyncdefer不会阻止DOM渲染,这使应用程序感觉更快。

<!-- load meh.js asynchronously to the page -->
<script src="meh.js" async></script>

<!-- load meh.js after the page has loaded -->
<script src="meh.js" defer></script>

回收/减少Dom ( Recycle/Reduce the Dom )

Look at Facebook, Twitter, Instagram, 9gag, the list goes on when it comes to websites with infinite scrolling enabled. The problem with infinite scrolling is that the more dynamic content you add to the DOM, the more elements we have to query. This is bad for performance and quickly slows the browser by consuming memory (RAM).

看一下Facebook,Twitter,Instagram,9gag,当启用无限滚动的网站时,该列表就会出现。 无限滚动的问题在于,添加到DOM中的动态内容越多,我们必须查询的元素就越多。 这会降低性能,并通过占用内存(RAM)Swift降低浏览器的速度。

9gag's approach to solving the problem of too many elements is quite cool. After reading a certain number of memes, 9gags shows you a button you can use to clear out memes you passed. If you click on the button, all the previous memes get deleted from the page and you begin to notice the site speed up.

9gag解决过多元素问题的方法非常酷。 读取一定数量的模因后,9gags将显示一个按钮,您可以使用该按钮清除传递的模因。 如果单击该按钮,则所有以前的模因都会从页面中删除,您会开始注意到该站点的速度加快了。

9gag's solution is stellar, but another thing you can do is recycle DOM elements. You allocate some elements to use for displaying content to the DOM and when that elements exit the viewport, you take it back to the bottom as illustrated below.

9gag的解决方案很出色,但是您可以做的另一件事是回收DOM元素。 您分配了一些元素以用于向DOM显示内容,并且当这些元素退出视口时,将其带回到底部,如下所示。

requestAnimationFrame ( requestAnimationFrame )

There's this myth that JavaScript animations are slow. The truth is they are if not properly written same goes for CSS animations. But we can change that.

有一个神话是JavaScript动画很慢。 事实是,如果没有正确编写它们,CSS动画也是如此。 但是我们可以改变这一点。

With requestAnimationFrame, we tell the browser to call a function to render a frame. The reason why this is so performant when compared to something like setTimeout is because it triggers the GPU for a faster and better rendering.

使用requestAnimationFrame ,我们告诉浏览器调用一个函数来渲染框架。 与setTimeout东西相比,它之所以如此出色,是因为它触发了GPU,以实现更快,更好的渲染。

Thus making our animation render at 60fps (or a frame every 16.667ms) which is just perfect for the human eyes when it comes to speed it can comfortably understand.

因此,使我们的动画以60fps (或每16.667ms帧)的速度渲染,就速度而言,它对于人眼来说是完美的,可以轻松理解。

To use it.

要使用它。

var start = null;
var element = document.getElementById('SomeElementYouWantToAnimate');
element.style.position = 'absolute';

// Takes in the timestamp of the current frame
function step(timestamp) {
    if (!start) start = timestamp;

    // calculate total time passed
    var progress = timestamp - start;

    // get the number of pixels the element should move every frame
    element.style.left = Math.min(progress / 10, 200) + 'px';

    // only animate if time passed is lesser than 2000ms or 2 seconds
    if (progress < 2000) {
        window.requestAnimationFrame(step);
    }
}

window.requestAnimationFrame(step);

This feels like too much work just to make a box move left. But there are JavaScript libraries like Anime.js, Gsap that make animation a breeze.

只是为了使盒子向左移动,这感觉工作量很大。 但是有些JavaScript库(例如Anime.js,Gsap)使动画变得轻而易举。

下线 ( Go Offline )

One use of JavaScript service workers is to cache files for use offline. The thing is that the files are not only cached to be used offline, they can also be used when there is an internet connection. This helps your application skip the request for a JavaScript file and just fetch it from its cache which is definitely faster and better optimised when compared to fetching the file from the server.

JavaScript服务工作者的一种用法是缓存文件以供离线使用。 事实是,这些文件不仅可以缓存以供脱机使用,还可以在有互联网连接时使用。 这可以帮助您的应用程序跳过对JavaScript文件的请求,而仅从其缓存中获取请求,与从服务器中获取文件相比,绝对可以更快,更好地进行优化。

Also, going offline gives your web app the feel of a desktop or mobile app (depending on the screen) which gives the illusion of a faster application.

同样,脱机使您的Web应用程序具有桌面或移动应用程序的感觉(取决于屏幕),从而产生了更快的应用程序的幻觉。

使用承诺 ( Use Promises )

JavaScript promises use a fluent API to describe code and being a native function, they are completely optimised and should be used frequently. The fact that promises are asychronous means they are not blocking thus improving the speed of your application

JavaScript承诺使用流畅的API来描述代码,并且是本机函数,它们已完全优化,应经常使用。 Promise是异步的,这意味着它们不会被阻塞,从而提高了应用程序的速度

分析您的代码 ( Profile your code )

Chrome developer tools is a very robust range of tools. Apart from a console, DOM inspector, it also comes with a profiler. Chrome developer tools is a very robust set. Apart from a console, DOM inspector, it also comes with a profiler (learn about Chrome's JavaScript Profiler).

Chrome开发人员工具是一系列非常强大的工具。 除了控制台,DOM检查器之外,它还带有事件探查器。 Chrome开发者工具集非常强大。 除了控制台,DOM检查器之外,它还带有分析器( 了解ChromeJavaScript Profiler )。

Soon to be called "Memory Panel", this tool checks runs a series of tests on your web application and looks for memory leaks. If it discovers anything, it is then displayed in a graph, showing you potential bottlenecks and memory leaks.

很快被称为“内存面板”,此工具将检查在Web应用程序上运行的一系列测试,并查找内存泄漏。 如果发现任何内容,它将显示在图形中,向您显示潜在的瓶颈和内存泄漏。

After you fix these problems, you will definitely notice an improvement in your app performance and prevent JavaScript from quitting on you :).

解决这些问题后,您一定会注意到您的应用程序性能有所改善,并防止JavaScript退出您的:)。

结论 ( Conclusion )

These are just some ways to make your JavaScript application faster. I'm sure there are other ways to optimise JavaScript for performance, let us know down in the comments.

这些只是使您JavaScript应用程序更快的一些方法。 我确信还有其他方法可以优化JavaScript的性能,请在评论中告诉我们。

Sources:

资料来源:

翻译自: https://scotch.io/tutorials/improve-the-performance-of-your-javascript-web-application

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值