【人工智能系列】python的Quepy库的上

前者性能优化

  • 削减HTTP请求数量
    • CSS Sprites
    • 内联图片(图片base64)
    • 最大化合并JS、CSS模块
    • 利用浏览器缓存
  • 减多少HTTP请求大小
    • 压缩HTTP响应包(Accept-Encoding: gzip, deflate)
    • 压缩HTML、CSS、JS模块
  • DOM方面
    • 离线操作DOM
    • 行使innerHTML进行大气底DHTML操作
    • 动用事件代理
    • 缓存布局信息
    • 移除页面上不在的事件处理程序
  • JavaScript语言本身的优化
    • 下部分变量代替全部变量,减少作用域链遍历标识符的日
    • 压缩对象成员以及数组项的探寻次数
    • 免以with语句和eval函数
  • ajax优化
    • get或者post请求
    • multipart XHR
    • ajax缓存
  • 另方的习性优化
    • 动用CDN加载静态资源
    • CSS样式放在头部
    • JS脚本放在脚
    • 避采用CSS表达式
    • 外联JS、CSS
    • 减少DNS查找
    • 避免URL重定向

第一篇 了解

转载请注明出处: 前者性能优化

什么是Quepy

减HTTP请求数量

quepy是一个Python框架改造自然语言问题在数据库查询语言查询。它好充分容易地定制不同品种的题材,在自然语言和数据库查询。因此,用好少的代码,你得成立和谐之系,自然语言访问您的数据库。

CSS Sprites

以多单图片合并成一摆放图,只如图发送一不行呼吁的技能。此时好经background-position依据职务一定及不同的图样。虽然联合后的平等摆放图片包含附加的空区域,会让人口认为比单个图片合并起来的图片要生。实际上,合并后底图会较分别之图形的总和要稍微,因为同样来用反复呼吁合并成为了同样不行,二来降低了图片自身的开支(颜色表,格式信息等等)。

选举个例证,如果产生要请四独25k之图样,那么直接求100k的图纸会比发送四软呼吁而趁早有。因为屡屡http请求会产生性能开销和图自身之支出。

时下quepy
支持SPARQL言及MQL数据库查询语言。我们计划以她扩展及外数据库查询语言。

内联图片

经过使用data:
URL模式可当Web页面包含图表但随便需外附加的HTTP请求。data:
URL中之URL是经过base64编码的。格式如下

<img src="data:image/gif;base64....." alt="home">

鉴于下内联图片(图片base64)是内联在HTML中的,因此于超页面时无见面给缓存。一般情况下,不要以网站的Logo做图片base64的处理,因为编码过的Logo会导致页面变大。可拿图片作为背景,放在CSS样式表中,此时CSS可叫浏览器缓存

.home {
 background-image: url(data:image/gif;base64.....)
}

说明:

最大化JS、CSS的合并

设想到HTTP请求会带格外的特性开销,因此下载单个100kb的文件较下充斥4只25kb的文书再度快。最大化合并JS、CSS将会晤改善性。

卿待安装docopt和NumPy。除此之外,您得但键入:

运浏览器缓存

减去呈现页面时所必备的HTTP请求的数量是加快用户体验的顶尖办法。可以透过最大化浏览器缓存组件的力量来实现。

pip install
quepy

咦是缓存

设若组件(HTML、CSS、JavsScript、图片资源相当)被缓存到浏览器被,在下次再度加载的上有或从组件中取缓存,而休是通往服务器发送HTTP请求。减去HTTP请求有利于前端性能优化

汝可以于此间获得更多的装细节:

浏览器如何缓存

浏览器在下载组件(HTML、CSS、JavsScript、图片资源相当),会用她们缓存到浏览器被。如果某个组件确实更新了,但是依旧以缓存中。这时候可以给组件添加版本号的法子(md5)避免读取缓存。

http://quepy.readthedocs.org/en/latest/installation.html

浏览器还下充斥组件时,如何确认是缓存的零部件

叩问再多,你得于此找到教程:

1.Expires头

可透过服务端配置,将有组件的过期时设置的丰富片。比如,公司Logo不会经常变化等。浏览器在下载组件时,会以那个缓存。在持续页面的查被,如果当指定时间外,表明组件是匪过的,则足以直接读取缓存,而非用走HTTP请求。如果在指定时间他,则表明组件是晚点的,此时并无会见及时发起一个HTTP请求,而是发起一个极GET请求。

http://quepy.readthedocs.org/en/latest/tutorial.html

2.条件GET请求

若是缓存的零部件过期了(或者用户reload,refresh了页面),浏览器在重新用其之前须优先反省其是否还有效。这称之为一个准绳GET请求。这个要是浏览器必须发起的。如果响应头部的Last-Modified(最后修改时,服务器传回的价)与请求头部的If-Modified-Since(最新修改时间)得值相当,则会回304响应(Not-Modified),即直接从浏览器被读取缓存,而非是倒HTTP请求。

这里发生完全的文档:

3.Etag(实体标签)

Etag其实与标准化GET请求很像,也是由此检测浏览器缓存中的组件和原有服务器上之零部件是否匹配。如果响应头部的Etag与请求头部的If-None-Match的价互相配合,则会回来304响应。

Etag存在的一对题目:

  1. 一旦只生同尊服务器,使用Etag没有呀问题。如果起差不多玉服务器,从不同服务器下充斥同之组件返回的Etag会不同,即使内容一律,也不见面由缓存中读取,而是发起HTTP请求。
  2. Etag降低了代理缓存的频率。
  3. If-None-Match比If-Modified-Since拥有更胜似之事先级。即使极GET请求的应头部及请求头部的少数个价相同,在装有多宝服务器的情事下,不是于缓存中读取,而是依然会倡导HTTP请求。

出零星种办法可缓解此问题

  1. 当服务端配置Etag。
  2. 每当劳务端转换除了Etag。移除Etag可以减少响应与继续HTTP请求头的分寸。Last-Modified可以供了等价格的信

http://quepy.readthedocs.org/

调减HTTP请求大小

 

1.组件(HTML, CSS, JavaScript)压缩处理

第二篇 学习

2.配置请求头部信息:Accept-encoding: gzip, deflate。此时服务器返回的应头部中见面包含Content-encoding: gzip的音讯,表明http响应包被抽。

一个例

为说明你可做呀以及quepy,我们连一个示范应用程序通过她们之sparql端点访问DBpedia内容。

乃可当此间品尝在线示例:在线演示

要,您可透过以下措施尝试这示例:

python examples/dbpedia/main.py "Who is Tom Cruise?"

它会输出这样的东西:

SELECT DISTINCT?x1 WHERE { 
    ?x0 rdf:type foaf:Person。
    ?x0 rdfs:label“Tom Cruise”@en。
    ?x0 rdfs:comment?x1。
} 
#输出
Thomas Cruise Mapother IV, widely known as Tom Cruise, is an...

 从自然语言到sparql的变是经首先使特殊形式的正则表达式来形成的:

person_name = Group(Plus(Pos("NNP")), "person_name")
regex = Lemma("who") + Lemma("be") + person_name + Question(Pos("."))

 然后用与有益之法子来发表语义关系:

person  =  IsPerson () +  HasKeyword (person_name )
definition  =  DefinitionOf (person )

 转换的其余部分由框架自动处理,最终死成这sparql:

SELECT  DISTINCT  ?x1  WHERE  { 
    ?x0  rdf :type  foaf :Person 。
    ?x0  rdfs :label  “Tom Cruise” @ en 。
    ?x0  rdfs :comment  ?x1 。
}

 使用十分相像之历程,您可扭转与MQL查询同一之题目取得:

[{
    "/common/topic/description": [{}],
    "/type/object/name": "Tom Cruise",
    "/type/object/type": "/people/person"
}]

 

为了求证什么使用quepy作为数据库的自然语言界面的框架,我们拿构建(逐步)一个走访DBpedia的示范应用程序 。

完成的以身作则应用程序可以在线尝试: 在线演示

成功的示范代码可以于此间找到: 代码

先是步是挑我们愿意因此dbpedia数据库回答的题目,然后我们拿付出一个方可将它们转换成为SPARQL查询的机关。

DOM方面

所选择问题

在咱们的演示应用程序中,我们以谋求对以下问题:

谁是<someone>,例如:

  • 汤姆克鲁斯是哪位?
  • 谁是奥巴马总统?

什么是<something>,例如:

  • 哟是汽车?
  • 哎是Python编程语言?

列出<brand> <something>,例如:

  • 列出Microsoft软件
  • 排有菲亚特汽车
离线DOM操作

一旦急需给页面及有元素进行某种DOM操作时(如增加有子节点或者增加某段文字或去某个节点),如果直白指向在页面及进展更新,此时浏览器需要再次计算页面及享有DOM节点的尺码,进行再排与重绘。现场进行的DOM更新更多,所花费的辰便越长。重排是赖有DOM节点发生位置变动时(删除、移动、CSS盒模型等),重新绘制渲染树的历程。重绘是靠用生位置变动之DOM节点重新绘制到页面上的经过。

var list = document.getElementById("myList"),
   item,
   i;
for (i=0; i < 10; i++) {
 item = document.createElement("li");
 list.appendChild(item);
 item.appendChild(document.createTextNode("Item " + i));
}

以上因素进行了20浅现场更新,有10破是以li插入到list元素中,另外10糟文本节点。这里虽生出了20潮DOM的还排和重绘。此时足行使以下办法,
来减少DOM元素的重拍和重绘。

一致凡是用文档碎片(),一凡拿li元素最后才插入到页面上

一:使用文档碎片(推荐)
var list = document.getElementById("myList"),
   item,
   i,
   frag = document.createDocumentFragment();  // 文档碎片
for (i=0; i < 10; i++) {
 item = document.createElement("li");
 frag.appendChild(item);
 item.appendChild(document.createTextNode("Item " + i));
}
document.body.appendChild(frag)

二:循环结束时插入li
var list = document.getElementById("myList"),
   item,
   i;
for (i=0; i < 10; i++) {
 item = document.createElement("li");
 item.appendChild(document.createTextNode("Item " + i));
}
list.appendChild(item);

开班一个quepy项目

比方开动一个quepy项目,您要创造一个quepy应用程序。在咱们的例证,我们的应用程序被称呼DBpedia中,我们由此运行应用程序:

$ quepy.py startapp dbpedia

你会发现一个文件夹和一些创建的文件。它应该是这样的:

$ cd dbpedia
$ tree .

.
├── dbpedia
│   ├── __init__.py
│   ├── parsing.py
│   ├── dsl.py
│   └── settings.py
└── main.py

1 directory, 4 files

 

这是每个门类之中心构造。

  • dbpedia /
    parsing.py:您将定义和自然语言问题相当并拿那易为架空语义表示的正则表达式的公文。
  • dbpedia /
    dsl.py:您将当其中定义数据库模式之地面特定语言的文件。在SPARQL的情景下,您将当此处指定通常是于本体中的事物:关系名称等。
  • dbpedia / settings.py:安装的一些地方的部署文件。
  • main.py:该文件是一个可选的kickstart点,您得在里面所有和应用程序交互所用的有代码。如果用,您可高枕无忧地抹此文件。
采用innerHTML方法

来点儿种植于页面及开创 DOM 节点的法:使用像 createElement()和
appendChild()之类的DOM
方法,以及采取innerHTML。对于小的DOM更改而言,两种办法效率还多。然而,对于好之
DOM 更改,使用 innerHTML 要比使用规范 DOM 方法创建同的 DOM
结构快得差不多。当把innerHTML设置为某个值时,后台会创造一个HTML解析器,然后采用中的DOM
调用来创造 DOM
结构,而不基于JavaScript的DOM调用。由于里方法是编译好之而无讲施行的,所以实行快得几近。

var ul = document.querySelector('ul')
var html = ''
for (var i = 0; i < 10; i++) {
 html += '<li>'+ i +'</li>'
 // 避免在for循环中使用innerHTML, 因为在循环中使用innerHTML会导致现场更新!
}
ul.innerHTML = html   // 循环结束时插入到ul元素中

顿时段代码构建了一个 HTML 字符串,然后拿其指定到
list.innerHTML,便创建了亟需的DOM结构。虽然字符串连接达连年有硌性能损失,但这种方式还是要比进行多只DOM操作更快。

配置应用程序

先是保证您已下载了nltk标记器的不可或缺数据。如果无检查 装有。

当今编辑dbpedia / settings.py连拿nltk数据的门路上加到 NLTK_DATA变量。这个文件发出一些其它安排选,但我们不待这例子。

还要配置LANGUAGE,在此例子中我们拿使用sparql

缓存布局信息

当以实质上利用被待取得页面及有DOM节点的布局信息经常,如offset dimension,
client
dimension或者是体等,浏览器为回时值,会刷新整个DOM树去赢得。最好之做法是缓存布局信息,减少布局信息之得到次数。获取之后将该缓存到有变量中,然后再次操作是有变量。

倘,需要将有DOM节点沿对角线移动,一差走一个像素,从100100
移动到500
500。

如果这样做,对于性能优化来说是低效的。
div.style.left = 1 + div.clientLeft + 'px'
div.style.top = 1 + div.clientTop + 'px'
if (div.style.clientLeft >= 500 && div.style.clientTop >= 500) {
  // 停止累加..
}

下面使用局部变量缓存布局信息,对于性能优化来说是高效的。
let left = div.clientLeft, right = div.clientTop
div.style.left = 1 + left + 'px'
div.style.top = 1 + right+ 'px'
if (div.style.clientLeft >= 500 && div.style.clientTop >= 500) {
  // 停止累加..
}

概念正则表达式

为了处理正则表达式,quepy使用refo,一个着实棒库来行使正则表达式作为靶子。您可以在这里读书更多关于refo的信息。

我们用定义跟自然语言问题相互配合并将那个更换为架空语义表示的正则表达式。这将概念具体哪些问题系统以能够处理与如何处理。

当我们的言传身教中,我们将编辑dbpedia /
parsing.py
文件。我们来拘禁一下正则表达式的事例来拍卖“What is
…”的
 问题。整个定义将如下所示:

from refo import Group, Question
from quepy.dsl import HasKeyword
from quepy.parsing import Lemma, Pos, QuestionTemplate

from dsl import IsDefinedIn

class WhatIs(QuestionTemplate):
    """
    Regex for questions like "What is ..."
    Ex: "What is a car"
    """

    target = Question(Pos("DT")) + Group(Pos("NN"), "target")
    regex = Lemma("what") + Lemma("be") + target + Question(Pos("."))

    def interpret(self, match):
        thing = match.target.tokens
        target = HasKeyword(thing)
        definition = IsDefinedIn(target)
        return definition

 

现给我们一样步一步地谈论是历程。

首先,请小心正则表达式处理程序需要是一个子类 quepy.parsing.QuestionTemplate。他们还用定义一个regex利用refo
regex 调用的类属性。

下一场,我们拿输入问题之布局描述为正则表达式,并将那储存于正则表达式性能被。在咱们的事例中,这是于第14推行吃好的:

未完!

事件代理

于javascript中,在页面渲染时上加到页面上之事件处理程序数量一直关系及页面的圆运行性能。最直接的影响是页面的事件处理程序更为多,访问DOM节点的次数也即越是多。另外函数是目标,会占据内存。内存中的对象越多,性能就越来越差。

事件代理就是釜底抽薪’过多的事件处理程序’的。事件代理基于事件冒泡机制。因此,可以以一如既往事件类的波还绑定到document对象及,根据事件目标的target属性下的id,
class
或者name属性,判断用给何人DOM节点绑定事件处理程序。这种事件代理体制在页面渲染时用拜访数DOM节点减少及了同样软,因为此时咱们特需要访问document对象。如下实现

document.addEventListener('click', function (e) {
 switch (e.target.id) {
   case 'new':
     console.log('new')
     break
   case 'name':
     console.log('name')
     break
   case 'sex':
     console.log('sex')
     break
 }
}, false)

使事件代理有以下优点:

  1. 可以于页面生名周期的外时刻点上添加添加事件处理程序(无需等待DOMContentLoaded和Load事件)。换句话说,只要有需要加上事件处理程序的元素是页面及,就得绑定相应的事件。
  2. DOM节点访问次数减少。
  3. 事件处理程序时函数,而函数是目标。对象见面占内存。事件处理程序减少了,所占有的内存空间就丢掉了,就能晋级整体性能。
移除事件处理程序

假设有这样一个求:页面上产生一个按钮,在点击时用替换成有文本。如果一直调换该按钮,由于该按钮的事件处理程序都是内存中了,此时移除按钮并无用事件处理程序并移除,页面还有所对拖欠按钮事件处理程序的援。一旦这种场面出现反复,那么原来增长到元素中之事件处理程序会占用内存。在事件代理中呢发话了,函数是目标,内存中之对象越多,性能有越来越差。除了文本替换他,还可能出现于移除(removeChild)、替换(replaceChild)带有事件处理程序的DOM节点。

如果科学的做法是,在移除该按钮的而,移除事件处理程序。

<div class="content">
 <button class='btn'>点击</button>
</div>
var btn = document.querySelector('.btn')
btn.addEventListener('click', function func(e) {
 btn.removeEventListener('click', func, false) // 在替换前,移除该按钮的事件处理程序
 document.querySelector('.content').innerHTML = '替换button按钮拉!'
}, false)

JavaScript的优化

使一些变量代替全局变量,减少在图域链上搜寻标识符的岁月

以JavaScript中,作用域分为函数作用域和词法作用域。当我们实施了某函数时,会创一个执环境。如果在实行环境受到怀念搜寻某个变量,会经历以下行为:

第一由此时此刻词法作用域开始物色,如果找到了此变量,那么就是已搜索,返回该变量;如果找不至,那么即使见面寻找外层的词法作用域,一直发展冒泡;如果还是没有以大局意图域下仍然没寻找到拖欠变量,浏览器就是见面报RefferceError类型的谬误,此错误表示与作用域相关。最后,此函数的行环境让灭绝。

自性能方面考虑,如果拿有变量放在全局意图域下,那么读写及拖欠变量的时日会见较部分变量多很多。变量在作用域中之职位更怪,访问所用时间尽管越长。由于全局变量总是(document,
window对象)处在作用域链的无限后面,因此访问速度是无与伦比缓慢的。
语言 1
语言 2

举个例证吧。比如我们操作DOM元素时,必不可免的见面采用到document对象。这个目标是window对象下的一个性,也算是一个全局变量吧。因此,当我们操作DOM时,可以用那缓存,作为有变量是,那么就是避免了企图域链搜索全局变量的进程。

let func = () => {
  let doc = document  // document作为局部变量存在
  let body = doc.body  // body作为局部变量存在
  let p = doc.createElement('p')
  let text = doc.createTextNode('document和body作为局部变量存在')
  body.appendChld(p)
}
压缩对象成员频繁组项的探寻次数

当即点主要反映在循环体上。以for循环为例,缓存数组长度,而未是于历次循环中获。

假设有有一个arr数组,长度为50000
// 低效的, 每次都要获取数组长度
for (var i = 0; i < arr.length; i++) {
  // do something...
}
// for循环性能优化:缓存数组长度
for ( var i = 0, len = arr.length; i < len; i++) {
  // do something
}

Ajax方面的优化

get或者post请求

此处可以拉一下get和post请求的区分。

于get请求来说,重在用以获取(查询)数据。get请求的参数需要以query
string的办法上加于URL后面的。当我们需要由服务器获取或者查询有数经常,都应该采取get请求。优点在gei请求于post请求而尽早,同时get请求可以吃浏览器缓存。缺点在于get请求的参数大于2048单字符时,超过的字符会被截取,此时内需post请求。

对此post请求来说,主要用以保存(增加值、修改值、删除值)数据。post请求的参数是作为请求的主导提交到服务器。优点在没有字节的限。缺点是无法让浏览器缓存。

get和post请求有一个共同点:虽然于请时,get请求将参数带以url后面,post请求将参数作为请求的本位提交。但是要参数还是因name1=value1&name2=value2
的章程发送到服务器的。

let data ['name1=value1', 'name2=value2']
let xhr = new window.XMLHttpRequest()
xhr.addEventListener('readystatechange', () => {
  if (xhr.readyState === 4) {
    if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
      console.log(xhr.responseText)
    }
  }
}, false)
let getPram = '?' + data.join('&')
let postPram = data.join('&')
// open方法:
xhr.open('get', 'url' + getPram, true)
// post方法, 作为请求的主体提交
// xhr.send(postPram)

据此,扯了那多。要专注的是,get请求用于查询(获取)数据,post请求用于保存(增删改)数据。

跨域JSONP

鉴于同源政策之界定,ajax只会在同域名、同协议、同端口的情形下才足以拜。也就是说,跨域是那个的。但是得运用JSONP的法绕了同源政策。

JSONP实现的法则:动态创建script标签。通过src属性添加需要看的地址,将赶回的数码作参数封装在回调函数中

let script = document.createElement('script')
script.src = 'url...'
script.id = 'script'
document.head.appendChild(script)

script.addEventListener('load', e => {
  if (this.readyState === 'complete') {
    let data = e
    // do something...
  }
}, false)

JSONP的优点:

  1. 跨域请求。
  2. 由返回的参数是JavaScript代码,而休是用作字符串需要更为处理。所以速度快

JSONP的缺点:

  1. 只是会因get请求发送。
  2. 无法也错误、失败事件设置事件处理程序。
  3. 束手无策设请求头。
multipart XHR

暂时不以了,占位占位、等以过了再度创新:)

ajax缓存

优先占位。目前正在开发一个小型类jQuery库。主要目的来:熟悉面向对象编程思想,熟悉DOM操作。到时刻开发完ajax模块再回填坑。

外点的性质优化

用样式表放在顶部

CSS样式表可以在两单地方,一凡文档头部,一是文档底部。位置的不同会带不同之体会。

当样式表放在文档底部时,不同浏览器会油然而生不同之意义

IE浏览器在初窗口打开、刷新页面时,浏览器会阻塞内容之渐渐呈现,取而代之的是白屏一段时间,等到CSS样式下载了之后再也以内容和样式渲染到页面上;在点击链接、书签栏、reload时,浏览器会优先用内容日益显现,等到CSS样式加载了之后重新渲染DOM树,此时会见发无样式内容之闪耀问题

火狐浏览器不管坐什么艺术打开浏览器都见面用内容日益呈现,然后等交css样式加载了后重新又渲染DOM树,发生无样式内容的闪耀的问题。

当样式表放在文档顶部时,虽然浏览器需要先加载CSS样式,速度可能比较位居脚的慢些,但是由足使页面内容日益呈现,所以针对用户来常常还是抢的。因为生情呈现了要非是白屏,发生无样式内容之闪耀,用户体验为会见自己些。毕竟,有内容比较白屏要好过多吧…

将样式放在文档顶部有星星点点种植方法。当用link标签将样式放在head时,浏览器会如内容日益呈现,但是会发出无样式内容之闪光问题;当使用@import规则,由于会有模块(图片、样式、脚本)下载时之无序性,可能会见起白屏的景。另外,在style标签下可以应用多独import规则,但是得放于任何规则之前。link和@import引入样式也设有性能问题,推荐引入样式时犹使link标签。

参考文章:link标签及@import规则的性能区别

文章中,简言之的游说即使是都是故link标签或者都是为此@import规则加载CSS样式时会并行下载;若果混用link标签以及@import规则导致体制无法并行下载,而是逐个下载。鉴于@import规则会招致模块下载的无序性问题,所以还是引进全部用到link标签引入css样式

以脚本放在脚

用脚本放在文档顶部会促成如下问题:

  1. 脚本会阻塞其后组件的并行下载和实行
  2. 脚本会阻塞其后页面的日益呈现

HTTP1.1确定,建议每个浏览器从服务器并行下载两只零部件。这也意味着,增加服务器的数码,并推行下载的数额也会大增。如果出三三两两大服务器,那么并行下载组件的数量为4。
语言 3
语言 4
除去用脚本放在脚可以缓解者以上两单问题,script标签`的async和defer属性也足以缓解就有限个问题。

asnyc属性(异步脚本)表示脚本可以及时下载,下载就后自行执行,但非答应妨碍页面中之另操作。比如下载其他模块(图片、样式、脚本)。由于是异步的,所以剧本下载没有先后顺序,没有各个的脚本就要管每个脚本不见面互相依赖。只对外表脚论文件中。异步脚本一定会以页面load事件前实行,但或许会见于DOMContentLoaded事件触发前后执行。由于async属性可以异步加载脚本,所以可以置身页面的别职务。

defer属性(延迟脚本)表示脚本可以立即下载,但是会推迟至文档完全受解析和显示之后又履行。在DOMContentLoaded事件后,load事件之前实施。由于defer属性可以缓脚本的施行,因此得以放在页面的外位置。

以尚未asnyc属性和defer属性的script标签时,由于js是单线程的原由,所以不得不下载了第一单script才能够下载第二只,才到第三独,第四独……

避免语言使CSS表达式

本条理应怪少人所以吧…毕竟网上对css表达式介绍的少之又少…反正我是没有因此了之

外联javascript、css

他联javascript、css文件相对于内联有以下优点。外联的艺术可以经script标签或者link标签引入,也可由此动态方式开创script标签和link标签(动态脚本、动态样式),此时经动态方式创造的台本和体不见面卡住页面其他零件的下载和呈现。

通用函数
let loadScript = (url, cb) => {
  let script = document.createElement('script')
  支持readystatechange事件的浏览器有IE、Firefox4+和Opera,谷歌不支持该事件。存在兼容性问题。
  if (script.readyState) {
    script.addEventListener('readystatechange', function change () {
      if (script.readyState === 'loaded' || script.readyState === 'complete') {
        // 移除readystatechange,避免触发两次
        script.removeEventListener('readystatechange', change, false)
        cb()
      }
    }, false)
  } else {
    script.addEventListener('load', () => {
      cb()
    }, false)
  }
  script.src = url
  document.body.appendChild(script)
}

// 依次解析和执行a.js、b.js、c.js。
loadScript('./a.js', () => {
  alert('a done')
  loadScript('./b.js', () => {
    alert('b done')
    loadScript('./c.js', () => {
      alert('c done')
    })
  })
})
  1. 好于浏览器缓存。
  2. 作组件复用。
减少DNS查找

DNS的用意是将域名解析为IP地址。通常状态下,浏览器查找一个深受定主机名的IP地址需要花20-120ms。在DNS服务器查找完成前,浏览器不可知从服务器那里下载任何东西。减少DNS查找的法门如下。

  1. 减掉服务器数量。减少服务器数量意味着并行下载组件的数据也会减小,但是这见面减少DNS查找的时。应基于现实事务场景做取舍。
  2. 浏览器缓存DNS记录。可以经过服务器配置DNS缓存的时日。
  3. 配置Keep-alive。由于客户端服务器连接是坚持不懈的,因此无论需DNS查找。
避免url重定向

先占位。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图