高性能网站优化-创建快速响应的Web

news/2024/7/20 12:58:23 标签: javascript, ui, 内存管理

《高性能网站建设进阶指南》

优化原则

优化的目的是希望降低程序的整体开销。

减少开销

通常认为开销就是程序的执行时间。而在进行优化工作时,应该把重点放在对程序开销影响最大的那部分。
假设我们有四个模块:A,B,C,D,其中模块A运行所需开销54%,模块B运行所需开销4%,模块C运行开销30%,模块D运行开销12%。
即使可以通过某种方法将模块B性能开销减少到2%,其实也只是降低了整体开销的2%。如果A的开销减少10%,却可以获得更好的效果,而显然模块A更值得去优化。优化那些开销不大的模块回报太低。

优化循环

程序大部分的时间都消耗在循环上,优化那些只执行一次的代码得到的回报微不足道。但优化循环得到的好处却总是让人欣慰。

合理利用Ajax

利用Ajax技术,客户端将较小的数据包发送到服务端,然后服务端响应请求返回另一个较小的数据包,客户端的JavaScript程序处理服务端返回的数据包,更新浏览器中的页面。这样数据的传输量和反馈时间间隔都大大减少,同时客户端和服务端工作量也减少。万万不可将所有的应用数据都发送给浏览器,这样反而会增加服务端的响应时间,而返回给客户端的数据也增加程序运行的压力,从而降低性能。

注意DOM

浏览器不是为应用平台而设计的,所以在处理Ajax应用程序的时候具有挑战。但是浏览器的发展速度很快,远远超出想象,已经有足够的能力去处理和执行复杂的应用。通过Ajax库可以碾碎很多障碍。
但是浏览器对DOM的解析依然低效。浏览器运行时,最大的开销往往是解析DOM而不是JavaScript 。注意优化DOM结构,避免多余的开销大的DOM操作。


伪多线程

就像所有的GUI应用程序一样,浏览器按队列顺序完成其队列中单独事件的处理。它按照先进先出的顺序从队列中取出,然后决定如何处理。但是,在浏览器中这个过程是单线程的,浏览器每次只能处理这些任务中的一个,并且其他任意一个任务都可以阻止其他任务的执行。由于JavaScript现在不支持多线程,所以无法创建一个后台程序执行开销很大的代码。而实际上,我们有一些方法可以在JavaScript中实现多线程的工作,但是却没有线程之间相互入侵的危险。

定时器

待完善

Web Workers

使用 setTimeout()、setInterval()、XMLHttpRequest 和事件处理程序等技术模拟“并行”,确实都是异步运行的。但没有阻碍未必就意味着并行。系统会在生成当前执行脚本后处理异步事件。可以通过Web Worker执行一些操作,同时却不会阻碍UI和其他脚本。

内存管理">内存管理

JavaScript中绝大部分的运行环境(?为什么是绝大部分?)都实现了垃圾回收。但是自动管理内存是有开销的。在执行回收时,它们会冻结整个运行环境,包括正在调用的主线程,直到遍历完整整个创建对象的“堆”。在这个过程中查找不再使用或者能够回收内存的对象。
对于大部分应用程序而言,GC是完全透明的。冻结运行环境的时间短到完全可以忽略。但是随着内存占用的增加,遍历整个内存中保存着对象的“堆”查找不再使用的对象的时间将增长,最终引起注意。
当这种情况发生是,应用程序开始定期出现间歇迟钝,更严重一点整个浏览器可能出现反映迟钝。
在编写代码时要注意:

  • 使用delete关键词从内存中移除不再需要的对象;

  • 从网页DOM树中移除不再需要的节点

通过拆分节省下载

将JavaScript分成两部分:一部分是渲染初始页面必须的,剩下的作为另一部分。在初始化时只加载必要的 JavaScript,其余的JavaScript稍后再加载。
拆分JavaScript代码的一个难点就是要避免出现未定义标识符错误。如果在执行的时候引用到了一个被延时加载的标识符时,就会出现这种问题。不过也有解决方法:
在延迟加载的代码和UI界面相关联的情况下,可以通过提示来巧妙的避开与用户的冲突。比如菜单中可以添加一个“加载中”的图标,告诉用户正在加载。或者干脆在延迟加载的代码里绑定事件处理程序,这样一来代码还未加载执行时,点击不会执行任何JavaScript代码。将两者结合更佳。

延时加载的代码不与页面元素相关联的情况下,可以使用模拟函数(stub function)来解决这个问题。模拟函数是一个与原函数名称相同但是函数体为空,或者包含一些临时代码的函数。当调用它们时,动态加载其他的JavaScript代码。当增的JavaScript代码下载完成之后,模拟函数便被新的函数覆盖。JavaScript函数没有重载。

转载于:https://www.cnblogs.com/zhanglun/p/3684777.html


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

相关文章

Linux驱动入门——构建和运行模块

Hello world模块 本文介绍如何向内核中添加一个hello模块。该模块的功能是在模块加载时,向系统日志输出“hello world\n” 在模块卸载时输出“Good bye,cruel world!". 一个模块源代码一般有含有一个init函数(加载时调用)和…

ef4.0和ef5.0增删改查的写法区别及执行Sql的方法

public T AddEntity(T entity) {//EF4.0的写法 添加实体//db.CreateObjectSet<T>().AddObject(entity);//EF5.0的写法db.Entry<T>(entity).State EntityState.Added;//下面的写法统一db.SaveChanges();return entity;}public bool UpdateEntity(T entity){//EF4.…

Linux设备驱动——简单的字符驱动

本文介绍Linux字符设备的静态注册方法&#xff0c;其中涉及到的模块加载&#xff0c;不了解的可以先参考构建和运行模块1. 还是线上源代码&#xff1a;//memdev.h#ifndef _MEMDEV_H_#define _MEMDEV_H_#ifndef MEMDEV_MAJOR#define MEMDEV_MAJOR 200#endif#ifndef MEMDEV_NR_DE…

word-wrap

平时的网页制作中碰到过这样的情况&#xff0c;比如说在blog中制作了一个完美而且又靓丽的评论布局&#xff0c;让你的用户浏览网页是可以给你添加评论&#xff0c;但当有人发布了一个原始网址或者其它超长的文本时&#xff0c;你此时的布局就被他们给彻底的破坏了&#xff0c;…

字符设备驱动——申请设备号、注册字符设备

1. 设备号 主设备号&#xff1a;用来标识与设备文件相关的驱动程序&#xff0c; ——反应设备类型次设备号&#xff1a;为内核所用&#xff0c;被驱动程序用来辨别操作那个设备文件 ——区分同类型的具体某个设备1.1 设备号的内部表达在内核中&#xff0c;保存设备号…

如何做好站内锚文本?

对于锚文本的作用相信每个专业的SEOer是不会陌生&#xff0c;锚文本可分为内部和外部锚文本&#xff0c;目前对网站排名起决定作用的锚文本还是来自其他网站或者网页给予自身网站的认知程度&#xff0c;因此现在很多SEOer都非常注重其他网站或网页的锚文本出现关键词链接即外部…

任务栏上最小化程序后,应用程序仍然处于激活状态

做项目的时候&#xff0c;需要在程序处于非激活状态&#xff0c;做一些清理工作&#xff0c;而判断非激活状态是根据 WM_ACTIVATEAPP 进行的。测试的时候发现&#xff0c;当在任务栏点击图标使应用最小化时&#xff0c;应用仍然处于激活状态&#xff0c;使用Spy&#xff0c;查看…

一个简单的信号量的例子

1. 信号量 Linux提供了控制线程执行和访问代码临界区域的方法。其中最基本的两种办法是信号量和互斥量。 关于互斥量&#xff0c;笔者在Linux互斥量中介绍 本文只介绍semaphore.h 相关的信号量的简单的操作。关于信号量在笔者其他博客里有详细介绍。 Linux还有其他共享内存…