0

0

为初学者测试和增强 jQuery 代码

王林

王林

发布时间:2023-09-01 12:09:04

|

1114人浏览过

|

来源于php中文网

原创

jquery 的到来使得 javascript 的编写过程变得异常简单。但是,您会注意到对代码进行小的更改可以显着提高可读性和/或性能。以下是一些可帮助您优化代码的提示。


设置平台

我们需要一个可靠的平台来进行测试。以下是测试页面的 HTML 标记,我们将在其中运行所有测试:

 
<!DOCTYPE html>
<html lang="en-GB">

<head>
<title>Testing out performance enhancements - Siddharth/NetTuts+</title>
</head>

<body>

<div id="container">
<div class="block">
<p id="first">
  Some text here
</p>
<ul id="someList">
  <li class="item"></li>
  <li class="item selected" id="mainItem">Oh, hello there!</li>
  <li class="item"></li>
  <li class="item"></li>
</ul>
</div>
</div>

<script  src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
  console.profile() ;
  
  // Our code here

  console.profileEnd();
</script>

</body>
</html>

这里没有什么特别的;只是我们可以定位和测试的一堆元素。我们使用 Firebug 来记录此处的时间。 profile 开始该过程,profileEnd 停止该过程,并记录该任务花费的时间。我通常使用 Firebug 的 main profile 方法,但对于我们的不正当目的,这就足够了。


1.检测元素是否存在

通常情况下,您将向站点中的所有页面提供包含代码的单个脚本文件。这通常是经常对当前页面中不存在的元素执行操作的代码。尽管 jQuery 非常优雅地处理此类问题,但这并不意味着您可以忽略任何问题。事实上,如果您在空集合上调用 jQuery 的方法,它们将不会运行。

作为最佳实践,仅运行适用于当前加载页面的代码,而不是将所有代码集中到单个文档就绪检查中,并将其提供给客户端。

让我们看看第一个场景:

console.profile();
var ele = $("#somethingThatisNotHere");
ele.text("Some text").slideUp(300).addClass("editing");
$("#mainItem");
console.profileEnd();
    
//Some more awesome, ground shattering code here ._.

Firebug 输出以下结果:

为初学者测试和增强 jQuery 代码

这一次,我们在执行操作之前先检查一下要执行操作的元素是否存在。

console.profile() ;
var ele = $("#somethingThatisNotHere");
if ( ele[0] ) {
   ele.text("Some text").slideUp(300).addClass("editing"); 
}
$("#mainItem");
console.profileEnd();
    
//Some more awesome, ground shattering code here ._.

结果:

为初学者测试和增强 jQuery 代码

看到了吗?这非常简单,切中要点并完成工作。 请注意,您无需检查代码的每一位是否都存在元素。您会在页面中注意到某些较大的部分通常会从此方法中受益。在这里运用你的判断。


2.有效使用选择器

尝试使用 ID 而不是传递类。

这是一个很大的主题,所以我会尽可能简洁。首先,在传递选择器时,尝试使用 ID 而不是传递类。 jQuery 直接使用本机 getElementById 方法通过 ID 查找元素,而对于类,它必须执行一些内部巫术才能获取它,至少在旧版浏览器中是这样。

我们将了解可用于定位第二个 li 元素的不同选择器。我们将测试它们中的每一个以及它们如何改变性能。

第一种方法,也是最简单的方法,是使用 selected 类明确地定位它。让我们看看 Firebug 的探查器返回什么。

console.profile() ;
 
$(".selected");
 
console.profileEnd();
为初学者测试和增强 jQuery 代码

结果:0.308ms。接下来,我们为标签名称添加前缀以缩小范围。这样,我们可以通过首先使用 document.getElementsByTagName 仅定位选定的 DOM 元素来缩小搜索范围。

console.profile() ;
 
$("li.selected");
 
 console.profileEnd();
为初学者测试和增强 jQuery 代码

结果:0.291ms。大约缩短了 0.02 毫秒。由于我们在 Firefox 中进行测试,这一点可以忽略不计;但是,应该指出的是,这种性能提升在较旧的浏览器(例如 Internet Explorer 6)中会明显更高。

接下来,我们从父元素的 ID 开始下降。

console.profile() ;
 
$("#someList .selected");
 
console.profileEnd();
为初学者测试和增强 jQuery 代码

结果:0.283ms。让我们尝试更具体一点。除了祖先的 ID 之外,我们还指定元素的类型。

console.profile() ;
 
$("#someList li.selected");
 
console.profileEnd();
为初学者测试和增强 jQuery 代码

结果:0.275 毫秒。还有一小部分被剃掉了。最后,我们直接使用 ID 来定位它。

console.profile() ;
 
$("#mainItem");
 
console.profileEnd();
为初学者测试和增强 jQuery 代码

结果:0.165ms。感人的!这确实向您展示了运行本机方法的速度有多快。请注意,虽然现代浏览器可以利用 getElementsByClassName 之类的功能,但旧版浏览器却不能 - 导致性能大大降低。编码时始终考虑这一点。


3. 解释 Sizzle 的解析模型并添加范围

Sizzle,jQuery 使用的选择器引擎 - 由 John Resig 构建 - 从右到左解析选择器,这会引发一些意想不到的解析链。

考虑这个选择器:

$("#someList .selected");

当Sizzle遇到这样的选择器时,它首先构建DOM结构,使用选择器作为根,丢弃不具有所需类的项目,并且对于具有该类的每个元素,它检查其父元素是否具有ID 为 someList

为了解决这个问题,请确保选择器最右侧的部分尽可能具体。例如,通过指定 li.selected 而不是 .selected,您可以减少必须检查的节点数量。这就是上一节中性能跳跃的原因。通过添加额外的约束,您可以有效地减少必须检查的节点数量。

为了更好地调整元素的获取方式,您应该考虑为每个请求添加上下文。

Bolt.new
Bolt.new

Bolt.new是一个免费的AI全栈开发工具

下载
var someList = $('#someList')[0];
$(".selected", someList);

通过添加上下文,搜索元素的方式完全改变。现在,首先搜索提供上下文的元素(在我们的示例中为 someList),一旦获得该元素,就会删除不具有必需类的子元素。

请注意,将 DOM 元素作为 jQuery 选择器的上下文传递通常是最佳实践。当上下文存储在某个变量中时,使用上下文是最有帮助的。否则,您可以简化该过程并使用 find() —— jQuery 本身就是在幕后做的。

$('#someList').find('.selected');

我想说性能提升将会被明确定义,但我不能。我已经在许多浏览器上运行了测试,范围方法的性能是否优于普通版本取决于许多因素,包括浏览器是否支持特定方法。


4.避免查询浪费

当您浏览别人的代码时,您经常会发现。

// Other code

$(element).doSomething();

// More code

$(element).doSomethingElse();

// Even more code

$(element).doMoreofSomethingElse();

请不要这样做。 永远。开发人员一遍又一遍地实例化这个“元素”。这是浪费。

让我们看看运行这样可怕的代码需要多长时间。

 console.profile() ;
 
 $("#mainItem").hide();
 $("#mainItem").val("Hello");
 $("#mainItem").html("Oh, hey there!");
 $("#mainItem").show();
 
 console.profileEnd();
为初学者测试和增强 jQuery 代码

如果代码的结构如上所示,一个接一个,您可以像这样使用链接:

console.profile();
 
$("#mainItem").hide().val("Hello").html("Oh, hey there!").show();
 
console.profileEnd();

通过链接,获取最初传入的元素,并将引用传递给每个后续调用,从而减少执行时间。否则每次都会创建一个新的 jQuery 对象。

但是,如果与上面不同,引用该元素的部分不是并发的,则您必须缓存该元素,然后执行与以前相同的所有操作。

console.profile() ;
 
var elem = $("#mainItem");

elem.hide();

//Some code
elem.val("Hello");

//More code
elem.html("Oh, hey there!");

//Even more code
elem.show();
 
console.profileEnd();
为初学者测试和增强 jQuery 代码

从结果中可以明显看出,缓存或链接大大减少了执行时间。


5.更智能地执行 DOM 操作

我之前的文章中建议进行非传统 DOM 操作,但在被证明性能提升确实值得之前,遭到了一些人的批评。我们现在将亲自测试一下。

对于测试,我们将创建 50 个 li 元素,并将它们附加到当前列表,并确定需要多少时间。

我们将首先回顾一下正常的、低效的方法。我们实质上是在每次循环运行时将元素附加到列表中。

console.profile() ;
 
var list = $("#someList");

for (var i=0; i<50; i++)
{
   list.append('<li>Item #' + i + '</li>');   
}

console.profileEnd();

让我们看看效果如何,好吗?

为初学者测试和增强 jQuery 代码

现在,我们将走一条稍微不同的道路。我们首先会将所需的 HTML 字符串附加到变量中,然后仅回流 DOM 一次。

console.profile() ;
 
var list = $("#someList");
var items = "";

for (var i=0; i<50; i++){  
     items += '<li>Item #' + i + '</li>';  
 }
 
list.append(items);

console.profileEnd();
为初学者测试和增强 jQuery 代码

正如预期的那样,所花费的时间显着减少。

为初学者测试和增强 jQuery 代码

如果您使用 jQuery 作为 getElementById 的替代品,但从未使用它提供的任何方法,那么您就做错了。

如果您想更进一步,问问自己是否真的需要创建一个新的 jQuery 对象来定位某些元素?如果您使用 jQuery 作为 document.getElementById 的替代品,但从未使用它提供的任何方法,那么您就做错了。在这种情况下,我们可以使用原始 JS。

console.profile() ;
 
var list = document.getElementById('someList');
var items = '';

for (var i=0; i<50; i++){  
     items += '<li>Item #' + i + '</li>';  
 }
 
list.innerHTML = items;

console.profileEnd();

一些注意事项

您会注意到优化代码和未优化代码之间的执行时间差异只有几分之一毫秒。这是因为我们的测试文档非常小,节点数量少得令人难以置信。一旦您开始使用包含数千个节点的生产级站点,它就会真正增加。

另请注意,在大多数测试中,我只是访问元素。当您开始对它们应用适当的函数时,执行时间的增量将会增加。

我也明白这不是测试性能的最科学的方法,但是,为了大致了解这些变化对性能的影响程度,我认为这已经足够了。

最后,在大多数网络应用程序中,相关网络服务器的连接速度和响应时间对应用程序性能的影响比对代码的调整影响更大。尽管如此,这仍然是重要的信息,并且当您试图从代码中获得尽可能多的性能时,它将帮助您。


这就是大家

我们就完成了。当您尝试优化代码时需要记住以下几点;当然,这并不是所有的调整列表,并且这些要点不一定适用于所有情况。无论哪种方式,我都会密切关注评论,以阅读您对这个主题的看法。你看到这里有什么错误吗?请在下面给我留言。

有疑问吗?好话要说吗?批评?点击评论部分并给我留言。快乐编码!

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

38

2026.03.10

Kotlin Android模块化架构与组件化开发实践
Kotlin Android模块化架构与组件化开发实践

本专题围绕 Kotlin 在 Android 应用开发中的架构实践展开,重点讲解模块化设计与组件化开发的实现思路。内容包括项目模块拆分策略、公共组件封装、依赖管理优化、路由通信机制以及大型项目的工程化管理方法。通过真实项目案例分析,帮助开发者构建结构清晰、易扩展且维护成本低的 Android 应用架构体系,提升团队协作效率与项目迭代速度。

83

2026.03.09

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

97

2026.03.06

Rust内存安全机制与所有权模型深度实践
Rust内存安全机制与所有权模型深度实践

本专题围绕 Rust 语言核心特性展开,深入讲解所有权机制、借用规则、生命周期管理以及智能指针等关键概念。通过系统级开发案例,分析内存安全保障原理与零成本抽象优势,并结合并发场景讲解 Send 与 Sync 特性实现机制。帮助开发者真正理解 Rust 的设计哲学,掌握在高性能与安全性并重场景中的工程实践能力。

223

2026.03.05

PHP高性能API设计与Laravel服务架构实践
PHP高性能API设计与Laravel服务架构实践

本专题围绕 PHP 在现代 Web 后端开发中的高性能实践展开,重点讲解基于 Laravel 框架构建可扩展 API 服务的核心方法。内容涵盖路由与中间件机制、服务容器与依赖注入、接口版本管理、缓存策略设计以及队列异步处理方案。同时结合高并发场景,深入分析性能瓶颈定位与优化思路,帮助开发者构建稳定、高效、易维护的 PHP 后端服务体系。

458

2026.03.04

AI安装教程大全
AI安装教程大全

2026最全AI工具安装教程专题:包含各版本AI绘图、AI视频、智能办公软件的本地化部署手册。全篇零基础友好,附带最新模型下载地址、一键安装脚本及常见报错修复方案。每日更新,收藏这一篇就够了,让AI安装不再报错!

169

2026.03.04

Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

246

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

34

2026.03.03

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号