云顶娱乐集团

当前位置:云顶娱乐集团 > 云顶娱乐集团 > 入门教程,减弱HTTP央求之统一图片详解

入门教程,减弱HTTP央求之统一图片详解

来源:http://www.clubskodakaroq.com 作者:云顶娱乐集团 时间:2019-10-01 21:35

WebSocket:5分钟从入门到精晓

2018/01/08 · HTML5 · 1 评论 · websocket

原稿出处: 前后相继猿小卡   

减去HTTP央求之统一图片详解(大型网址优化本领)

2015/11/26 · HTML5 · HTTP

原稿出处: Kelly   

一、相关知识授课

看过雅虎的前端优化35条提议,都领会优化前端是有多么主要。页面包车型大巴加载速度一贯影响到客商的体验。十分八的终端顾客响应时间都花在了前端上,个中相当多岁月都在下载页面上的各种零件:图片,样式表,脚本,Flash等等。

削减组件数一定能够收缩页面提交的HTTP须要数。那是让页面更加快的要害。减少页面组件数的一种办法是简化页面设计。但有未有一种格局能够在构建复杂的页面同不经常候加快响应时间吗?嗯,确实有鱼和熊掌兼得的措施。

这里大家就拿雅虎的首先条提议:尽量收缩HTTP央浼数里的滑坡图片需要数量 实行教学。

小编们都精晓,三个网址的贰个页面可能有那个小Logo,比如某个开关、箭头等等。当加载html文书档案时,只要遭受有图片的,都会活动构建起HTTP乞请下载,然后将图片下载到页面上,那几个小图片大概也正是十几K大依然1K都不到,借使我们的三个页面有九十八个小Logo,大家在加载页面时,就要发送100个HTTP诉求,假若你的网址访谈量比很大并发量也极高,假使上百万访问量,那发起的乞请正是相对品级了,服务器是有明确的压力的,并且八个客户的多少个页面要发起那么多诉求,是很耗费时间的。

于是,大家优化的方案就是:将这几个十几K、几K的小Logo合併在一张图片里,然后用CSS的background-imagebackground-position属性来牢固要展现的片段。

二、代码落成

1、思路:

将二个文书夹里的Logo,自动生成在一张图片里面,同期自动生成对应的css文件,大家只要在HTML里的价签中增加相应的属性值就可以显得图片了。

2、达成进程:

XHTML

<?php //本人定义一个根目录 define('ROOT', $_SERVER['DOCUMENT_ROOT'].'iconwww'); //那么些是图表的目录 define('RES_BASE_URL', ''); /** * 生成背景图的函数 */ function generateIcon() { //网址根目录 $webRoot = rtrim(ROOT, '/'); //背景图目录 $root = "$webRoot/img/bg"; //Php-SPL库中 的 目录文件遍历器 $iterator = new DirectoryIterator($root); //伊始遍历该背景图目录下的目录,大家是把想生成背景图的目录,放在bg目录中以一一模块的目录分类贮存foreach ($iterator as $file) { //蒙受目录遍历 if (!$file->isDot() && $file->isDir()) { //获得文件名 $fileName = $file->getFilename(); generateIconCallback("$root/$fileName", "$webRoot/img/$fileName", "$webRoot/css/$fileName.css"); } } } /** * 客商生成合併的背景图和css文件的函数 * @param string $dir 生成背景图的Logo所在的目录路线 * @param string $bgSavePath 背景图所保存的路线 * @param string $cssSavePath css保存的路线 */ function generateIconCallback($dir, $bgSavePath, $cssSavePath) { $shortDir = str_replace('\', '/', substr($dir, strlen(ROOT-1))); //重返文件路线消息 $pathInfo = pathinfo($bgSave帕特h.'.png'); $bgSaveDir = $pathInfo['dirname']; //确定保障目录可写 ensure_writable_dir($bgSaveDir); //背景图名字 $bgName = $pathInfo['filename']; //调用generateIconCallback_GetFileMap()函数生成每一个Logo所急需的数据结构 $fileMap = array('a' => generateIconCallback_GetFileMap($dir)); $iterator = new DirectoryIterator($dir); foreach ($iterator as $file) { if ($file->isDot()) continue; if ($file->isDir()) { //二级目录也要管理 $fileMap['b-'.$file->getFilename()] = generateIconCallback_GetFileMap($file->getReal帕特h()); } } ksort($fileMap); //深入分析一边fileMap,总计整个背景图的大大小小和每四个Logo的offset //起始化偏移量和背景图 $offsetX = $offsetY = $bgWidth = 0; //设定每一个小Logo之间的距离 $spaceX =$spaceY = 5; //图片最大幅度面 $maxWidth = 800; $fileMd5List =array(); //这里供给打字与印刷下$fileMap就领悟它的数据结构了 foreach ($fileMap as $k1 => $innerMap) { foreach ($innerMap as $k2 => $itemList) { //行高姐X轴偏移量开端化 $offsetX = $lineHeight = 0; foreach ($itemList as $k3 => $item) { //变量分别是:Logo的幅度,中度,类型,文件名,路线,MD5加密字符串 list($imageWidth, $imageHeight, $imageType, $fileName, $filePathname, $fileMd5) = $item; $fileMd5List []= $fileMd5; //纵然图片的宽窄+偏移量 > 最大开间(800) 那就换行 if ($offsetX !== 0 && $imageWidth + $offsetX > $maxWidth) { $offsetY += $spaceY + $lineHeight; $offsetX = $lineHeight = 0; } //假如图片高度 > 当前行高 那就讲图片中度付给行高大家那的 if ($imageHeight > $lineHeight) $lineHeight = $imageHeight; $fileMap[$k1][$k2][$k3] = array($imageWidth, $imageHeight, $offsetX, $offsetY, $imageType, $fileName, $filePathname); //X轴偏移量的测算 $offsetX += $imageWidth + $spaceX; if ($offsetX > $bgWidth) $bgWidth = $offsetX; } //Y轴偏移量的妄想 $offsetY += $lineHeight + $spaceY; } } //把右下两侧多加了的空白距离给干掉 $bgWidth -= $spaceX; $bgHeight = $offsetY - $spaceY; $fileMd5List = implode("n", $fileMd5List); //生成背景图和 css文件 //能源路径 $resBaseUrl = RES_BASE_URL; $suffix = base_convert(abs(crc32($fileMd5List)), 10, 36); $writeHandle = fopen($cssSavePath, 'w'); fwrite($writeHandle, "/** bg in dir: $shortDir/ */n[icon-$bgName]{background:url({$resBaseUrl}/$bgName.png?$suffix) no-repeat;display:inline-block;}"); //做图片,那么些函数具体能够查阅PHP手册 $destResource = imagecreatetruecolor($bgWidth, $bgHeight); image阿尔法blending($destResource, false); imagesave阿尔法($destResource, false); $color = imagecolorallocate阿尔法($destResource, 255, 255, 255, 127); imagefill($destResource, 0, 0, $color); //对每一张小图片张开管理,生成在大背景图里,并生成css文件 foreach ($fileMap as $innerMap) { foreach ($innerMap as $itemList) { foreach ($itemList as $item) { list($imageWidth, $imageHeight, $offsetX, $offsetY, $imageType, $fileName, $filePathname) = $item; if ($imageType === IMAGETYPE_PNG) { $srcResource = imagecreatefrompng($filePathname); } else if ($imageType === IMAGETYPE_JPEG) { $srcResource = imagecreatefromjpeg($filePathname); } imagecopy($destResource, $srcResource, $offsetX, $offsetY, 0, 0, $imageWidth, $imageHeight); imagedestroy($srcResource); //写入css $posX = $offsetX === 0 ? 0 : "-{$offsetX}px"; $posY = $offsetY === 0 ? 0 : "-{$offsetY}px"; fwrite($writeHandle, "n[icon-$bgName="$fileName"]{width:{$imageWidth}px;height:{$imageHeight}px;background-position:$posX $posY;}"); } } } //压缩品级 7 imagepng($destResource, "$bgSavePath.png", 7); imagedestroy($destResource); fclose($writeHandle); $shortCssSavePath = substr($cssSavePath, strlen(ROOT)); } /** * 将图片的音讯管理成大家想要的数据结构 * @param [type] $dir [description] * @return [type] [description] */ function generateIconCallback_GetFileMap($dir) { $map = $sort = array(); $iterator = new DirectoryIterator($dir); foreach($iterator as $file) { if(!$file->isFile()) continue; $filePathname = str_replace("\", '/', $file->getRealPath()); //这一个函数能够查看PHP手册 $imageInfo = getimagesize($filePathname); $imageWidth = $imageInfo[0]; $imageHeight = $imageInfo[1]; $imageType = $imageInfo[2]; if(!in_array($imageType, array(IMAGETYPE_JPEG, IMAGETYPE_PNG))) { $fileShortName = substr($filePathname, strlen(ROOT) - 1); echo "<p> $fileShortName 图片被忽视: 因为图片类型不是png|jpg.</p>"; continue; } //那是大家的图形规格,行高分别有 16 32 64 128 256 99999 foreach(array(16, 32, 64, 128, 256, 99999) as $height) { if($imageHeight <= $height) { $mapKey = $height; break; } } if(!isset($map[$mapKey])) $map[$mapKey] = array(); $filePathInfo = pathinfo($filePathname); $map[$mapKey] []= array($imageWidth, $imageHeight, $imageType, $filePathInfo['filename'], $filePathname, md5_file($filePathname)); $sort[$mapKey] []= str_pad($imageHeight, 4, '0', STR_入门教程,减弱HTTP央求之统一图片详解。PAD_LEFT) . $filePathInfo['filename']; } foreach($map as $k => $v) array_multisort($map[$k], SORT_ASC, SORT_NUMERIC, $sort[$k]); ksort($map, SORT_NUMERIC); return $map; } /** * 判别目录是不是可写 * @param string $dir 目录路线 */ function ensure_writable_dir($dir) { if(!file_exists($dir)) { mkdir($dir, 0766, true); @chmod($dir, 0766); @chmod($dir, 0777); } else if(!is_writable($dir)) { @chmod($dir, 0766); @chmod($dir, 0777); if(!@is_writable($dir)) { throw new BusinessLogicException("目录不可写", $dir); } } } generateIcon(); ?> <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="css/Pink.css"> <title></title> </head> <body> <div>大家直接引进所生成的css文件,并测验一下是不是中标</div> <br> <div>这里在span标签 增添属性 icon-Pink ,值为About-40,平常突显图片</div> <span icon-Pink="About-40"></span> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
<?php
    //自己定义一个根目录
    define('ROOT', $_SERVER['DOCUMENT_ROOT'].'iconwww');
    //这个是图片的目录
    define('RES_BASE_URL', 'http://localhost:8080/iconwww/img');
 
    /**
     * 生成背景图的函数
     */
    function generateIcon() {
        //网站根目录
        $webRoot = rtrim(ROOT, '/');
        //背景图目录
        $root = "$webRoot/img/bg";
        //Php-SPL库中 的 目录文件遍历器
        $iterator = new DirectoryIterator($root);
        //开始遍历该背景图目录下的目录,我们是把想生成背景图的目录,放在bg目录中以各个模块的目录分类存放
        foreach ($iterator as $file) {
            //遇到目录遍历
            if (!$file->isDot() && $file->isDir()) {
                //取得文件名
                $fileName = $file->getFilename();
                generateIconCallback("$root/$fileName", "$webRoot/img/$fileName", "$webRoot/css/$fileName.css");
            }
        }
    }
 
    /**
     * 用户生成合并的背景图和css文件的函数
     * @param  string $dir         生成背景图的图标所在的目录路径
     * @param  string $bgSavePath  背景图所保存的路径
     * @param  string $cssSavePath css保存的路径
     */
    function generateIconCallback($dir, $bgSavePath, $cssSavePath) {
        $shortDir = str_replace('\', '/', substr($dir, strlen(ROOT-1)));
        //返回文件路径信息
        $pathInfo = pathinfo($bgSavePath.'.png');
 
        $bgSaveDir = $pathInfo['dirname'];
        //确保目录可写
        ensure_writable_dir($bgSaveDir);
        //背景图名字
        $bgName = $pathInfo['filename'];
        //调用generateIconCallback_GetFileMap()函数生成每一个图标所需要的数据结构
        $fileMap = array('a' => generateIconCallback_GetFileMap($dir));
 
        $iterator = new DirectoryIterator($dir);
        foreach ($iterator as $file) {
            if ($file->isDot()) continue;
            if ($file->isDir()) {
                //二级目录也要处理
                $fileMap['b-'.$file->getFilename()] = generateIconCallback_GetFileMap($file->getRealPath());
            }
        }
        ksort($fileMap);
 
        //分析一边fileMap,计算整个背景图的大小和每一个图标的offset
        //初始化偏移量和背景图    
        $offsetX = $offsetY = $bgWidth = 0;
        //设定每个小图标之间的距离
        $spaceX =$spaceY = 5;
        //图片最大宽度
        $maxWidth = 800;
        $fileMd5List =array();
        //这里需要打印下$fileMap就知道它的数据结构了
        foreach ($fileMap as $k1 => $innerMap) {
            foreach ($innerMap as $k2 => $itemList) {
                //行高姐X轴偏移量初始化
                $offsetX = $lineHeight = 0;
                foreach ($itemList as $k3 => $item) {
                    //变量分别是:图标的宽度,高度,类型,文件名,路径,MD5加密字符串
                    list($imageWidth, $imageHeight, $imageType, $fileName, $filePathname, $fileMd5) = $item;
                    $fileMd5List []= $fileMd5;
                    //如果图片的宽度+偏移量 > 最大宽度(800) 那就换行
                    if ($offsetX !== 0 && $imageWidth + $offsetX > $maxWidth) {
                        $offsetY += $spaceY + $lineHeight;
                        $offsetX = $lineHeight = 0;
                    }
                    //如果图片高度 > 当前行高  那就讲图片高度付给行高我们这的
                    if ($imageHeight > $lineHeight) $lineHeight = $imageHeight;
                    $fileMap[$k1][$k2][$k3] = array($imageWidth, $imageHeight, $offsetX, $offsetY, $imageType, $fileName, $filePathname);
                    //X轴偏移量的计算
                    $offsetX += $imageWidth + $spaceX;
                    if ($offsetX > $bgWidth) $bgWidth = $offsetX;
                }
                //Y轴偏移量的计算
                $offsetY +=  $lineHeight + $spaceY;
            }
        }
        //把右下两边多加了的空白距离给干掉
        $bgWidth -= $spaceX;
        $bgHeight = $offsetY - $spaceY;
        $fileMd5List = implode("n", $fileMd5List);
 
        //生成背景图和 css文件
 
        //资源路径
        $resBaseUrl = RES_BASE_URL;
        $suffix = base_convert(abs(crc32($fileMd5List)), 10, 36);
        $writeHandle = fopen($cssSavePath, 'w');
        fwrite($writeHandle, "/** bg in dir: $shortDir/ */n[icon-$bgName]{background:url({$resBaseUrl}/$bgName.png?$suffix) no-repeat;display:inline-block;}");
 
        //做图片,这些函数具体可以查看PHP手册
        $destResource = imagecreatetruecolor($bgWidth, $bgHeight);
        imagealphablending($destResource, false);
        imagesavealpha($destResource, false);
        $color = imagecolorallocatealpha($destResource, 255, 255, 255, 127);
 
        imagefill($destResource, 0, 0, $color);
 
        //对每一张小图片进行处理,生成在大背景图里,并生成css文件
        foreach ($fileMap as $innerMap) {
            foreach ($innerMap as $itemList) {
                foreach ($itemList as $item) {
                     list($imageWidth, $imageHeight, $offsetX, $offsetY, $imageType, $fileName, $filePathname) = $item;
                     if ($imageType === IMAGETYPE_PNG) {
                        $srcResource = imagecreatefrompng($filePathname);
                     } else if ($imageType === IMAGETYPE_JPEG) {
                        $srcResource = imagecreatefromjpeg($filePathname);
                     }
                     imagecopy($destResource, $srcResource, $offsetX, $offsetY, 0, 0, $imageWidth, $imageHeight);
                     imagedestroy($srcResource);
 
                     //写入css
                     $posX = $offsetX === 0 ? 0 : "-{$offsetX}px";
                     $posY = $offsetY === 0 ? 0 : "-{$offsetY}px";
                     fwrite($writeHandle, "n[icon-$bgName="$fileName"]{width:{$imageWidth}px;height:{$imageHeight}px;background-position:$posX $posY;}");
                 }
            }
        }
 
        //压缩级别 7
        imagepng($destResource, "$bgSavePath.png", 7);
        imagedestroy($destResource);
        fclose($writeHandle);
 
        $shortCssSavePath = substr($cssSavePath, strlen(ROOT));
    }
 
    /**
     * 将图片的信息处理成我们想要的数据结构
     * @param  [type] $dir [description]
     * @return [type]      [description]
     */
    function generateIconCallback_GetFileMap($dir) {
        $map = $sort = array();
        $iterator = new DirectoryIterator($dir);
        foreach($iterator as $file) {
            if(!$file->isFile()) continue;
            $filePathname = str_replace("\", '/', $file->getRealPath());
            //这些函数可以查看PHP手册
            $imageInfo = getimagesize($filePathname);
            $imageWidth = $imageInfo[0];
            $imageHeight = $imageInfo[1];
            $imageType = $imageInfo[2];
 
            if(!in_array($imageType, array(IMAGETYPE_JPEG, IMAGETYPE_PNG))) {
                $fileShortName = substr($filePathname, strlen(ROOT) - 1);
                echo "<p> $fileShortName 图片被忽略: 因为图片类型不是png|jpg.</p>";
                continue;
            }
 
            //这是我们的图片规格,行高分别有 16 32 64 128 256 99999
            foreach(array(16, 32, 64, 128, 256, 99999) as $height) {
                if($imageHeight <= $height) {
                    $mapKey = $height;
                    break;
                }
            }
            if(!isset($map[$mapKey])) $map[$mapKey] = array();
            $filePathInfo = pathinfo($filePathname);
            $map[$mapKey] []= array($imageWidth, $imageHeight, $imageType, $filePathInfo['filename'], $filePathname, md5_file($filePathname));
            $sort[$mapKey] []= str_pad($imageHeight, 4, '0', STR_PAD_LEFT) . $filePathInfo['filename'];
        }
        foreach($map as $k => $v) array_multisort($map[$k], SORT_ASC, SORT_NUMERIC, $sort[$k]);
        ksort($map, SORT_NUMERIC);
        return $map;
    }
 
    /**
     * 判断目录是否可写
     * @param  string $dir 目录路径
     */
    function ensure_writable_dir($dir) {
        if(!file_exists($dir)) {
            mkdir($dir, 0766, true);
            @chmod($dir, 0766);
            @chmod($dir, 0777);
        }
        else if(!is_writable($dir)) {
            @chmod($dir, 0766);
            @chmod($dir, 0777);
            if(!@is_writable($dir)) {
                throw new BusinessLogicException("目录不可写", $dir);
            }
        }
    }
 
    generateIcon();
?>
<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" type="text/css" href="css/Pink.css">
    <title></title>
 
</head>
<body>
<div>我们直接引入所生成的css文件,并测试一下是否成功</div>
<br>
<div>这里在span标签 添加属性 icon-Pink ,值为About-40,正常显示图片</div>
<span icon-Pink="About-40"></span>
</body>
</html>

调用以上代码,大家的浏览器是这么展现的:

图片 1

接下来css目录生成了Pink.css文件:

图片 2

img目录下生成了Pink.png文件:

图片 3

走访生成的背景图是长啥样子:

图片 4

 

接下去我们再看一下所生成的图片大小与Pink文件夹里全数小图片总和的大小,对它们做个相比:

图片 5

 

图片 6

从上海体育场地可以观察,大家调换的图纸的轻重明显低于文件夹全部图片的高低,所以在将玖21个小图标下载下来的进度会分明低于 将背景图下载下来和将CSS下载下来的快慢。

当访谈量大时,或许小图片的量大时,会起到很猛烈的优化职能!!!

代码中的每八个点都大约有注释,很方便大家去领会,只要大家用心去看,断定能将这一网址优化技巧用到协调的品类中。

此次博文就写到那!!!

只要此博文中有哪里讲得令人为难驾驭,接待留言调换,若有解说错的地点招待指出。

假设您认为你能在此博管历史学到了新知识,请为自家顶五个,如作品中有分解错的地点,应接提议。

  相互学习,共同提高!

2 赞 3 收藏 评论

图片 7

Chrome调控台 怎么样调节和测验Javascript

2015/01/12 · JavaScript · Chrome

初稿出处: ctriphire   

上边的稿子早就大概介绍了一晃console对象实际有哪些方面以及大旨的利用,下边简单介绍一下什么样选用好chrome调控台那一个神器好好调节和测量试验javascript代码(那么些才是大家实在能用到实处的地点)

1、先说一下源码定位

大家打开测量试验网页   见到页面右下方有贰个引入的Logo吗?右击推荐Logo,选用检查核对成分,展开谷歌(Google)调节台,如下图所示

图片 8

咱俩今天想驾驭votePost方法到底在哪?跟着本人这么做,在Console面板里面输入votePost然后回车

图片 9

直白点击上海体育场地标红的链接,调节台将一定到Sources面板中,浮现如下图所示

图片 10

大家看了地点那一个图形之后揣摸头都要晕了啊,这么多js都整在一行,令人怎么看呀,不用缅想,按下图操作就可以(也正是点击中间面板左下方的Pretty print就行了)

图片 11

此时我们再回到Console面板时会惊喜的觉察原本的链接前面包车型地铁1以往成为91了(其实这里的数字1要么91就是表示votePost方法在源码中的行号 )今后收看Pretty print按键的无敌之处了啊

精通了怎么查看某七个按键的源码,那接下去的办事便是调解了,调节和测量检验第一步必要做的正是安装断点,其实设置断点相当粗略,点击一下上图所示的92就能够,这时你会发觉92行号旁边会多了一个Logo,这里解释一下为啥不在91处安装断点,你能够试下,事实上根本就无可奈何在91处上安装断点,因为它是函数的定义处,所以没办法在此设置断点。

图片 12

安装好了断点后,你就能够在右边Breakpoints方框里见到刚刚安装的断点。

小编们先来介绍一下用到的调节和测验火速键吧(事实上大家也能够毫无下表所示的快速键,直接点击上海教室所示右边栏最上层的一排按键来扩充调试,具体用哪些按键,把鼠标放到开关上方一会就能够展现它对应的唤起)

 

快捷键 功能
F8 恢复运行
F10 步过,遇到自定义函数也当成一个语句执行,而不会进入函数内部
F11 步入,遇到自定义函数就跟入到函数内部
Shift + F11 步出,跳出当前自定义函数

在那之中值得提的是,当大家点击“推荐”开关进行调节和测量检验的时候会意识,不管我们是按的F10进行调养照旧按F11实行逐级调节和测量检验,都没办法实行$.ajax函数内部,纵然大家在函数内部设置了断点也尚未办法进入,这里按F8才是真的起效果的,不相信你尝试。

当我们在调节和测量试验的时候,侧面Scope Variables里面会彰显当前功效域以及她的父级作用域,以及闭包。你非但能在左边手Scope Variables(变量功用域) 一栏处见到眼下变量,何况还是能把鼠标直接移到跋扈变量上,就可以查阅该变量的值。

用图说话(哈哈)

图片 13

 

刚巧大家介绍的只是在html里面能够看收获它绑定了onclick事件,这样大家就找到它绑定的js函数,假如它是在jQuery页面加载成功函数里面绑定的,那时候我们怎么通晓它绑定的是哪些js函数呢,假使大家不亮堂绑定的js函数就更为不用说调节和测量试验进去了

上面介绍一下怎么样查看,依旧以刚刚那些测量试验网页为例子吗,可是这一次我们来看“提交商议”作表达呢,

右击“提交商量”–>审查成分,我们能够领略的来看在那个开关上未绑定任何事件。在Console面板内输入如下代码

JavaScript

function lookEvents (elem) { return $.data ? $.data( elem, "events", undefined, true ) : $._data( elem, "events" ); } var event = lookEvents($("#btn_comment_submit")[0]); // 获取绑定的事件

1
2
3
4
function lookEvents (elem) {
    return $.data ? $.data( elem, "events", undefined, true ) : $._data( elem, "events" );
}
var event = lookEvents($("#btn_comment_submit")[0]); // 获取绑定的事件

正如图所示:

图片 14

依据上述介绍的方法定位到实际的blog-common.js里面,找到postComment  然后一难得一见的找到切实可行的代码,再安装断点就好了。

末尾介绍一下二个神器,很好用的debugger

要是您本人写的代码,你试行的时候想让它在某一处停下来,只要写上的debugger就好了,不相信你试试!哈哈

赞 1 收藏 评论

图片 15

渐进式Web应用(PWA)入门教程(下)

2018/05/25 · 基础技巧 · PWA

最先的作品出处: Craig Buckler   译文出处:草龙珠城控件   

上篇小说大家对渐进式Web应用(PWA)做了部分骨干的牵线。

渐进式Web应用(PWA)入门教程(上)

在这一节中,我们将介绍PWA的原理是什么样,它是怎么着开首工作的。

外人家的面试题:总结“1”的个数

2016/05/27 · JavaScript · 5 评论 · Javascript, 算法

正文笔者: 伯乐在线 - 十年踪迹 。未经作者许可,禁止转发!
招待参加伯乐在线 专栏撰稿人。

小胡子哥 @Barret李靖 给自身推荐了贰个写算法刷题的地点 leetcode.com,没有 ACM 那么难,但难题很有趣。何况传闻那一个难题都来自一些小卖部的面试题。好啊,解解别人公司的面试题其实很有意思,既可以整理思路磨练技巧,又不要操心漏题 ╮(╯▽╰)╭。

长途电话短说,让大家来看一道题:

一、内容大概浏览

WebSocket的出现,使得浏览器材有了实时双向通讯的工夫。本文按部就班,介绍了WebSocket如何建设构造连接、调换数据的底细,以及数据帧的格式。别的,还简单介绍了针对WebSocket的平安攻击,以及协调是什么样抵抗类似攻击的。

第一步:使用HTTPS

渐进式Web应用程序须求运用HTTPS连接。固然接纳HTTPS会令你服务器的花费变多,但使用HTTPS能够令你的网址变得更安全,HTTPS网址在Google上的排行也会更靠前。

是因为Chrome浏览器会暗中认可将localhost以及127.x.x.x地址视为测验地点,所以在本示例中您并无需开启HTTPS。另外,出于调节和测量检验指标,您能够在运转Chrome浏览器的时候使用以下参数来关闭其对网址HTTPS的检讨:

  • –user-data-dir
  • –unsafety-treat-insecure-origin-as-secure

统计“1”的个数

给定二个非负整数 num,对于率性 i,0 ≤ i ≤ num,总计 i 的值对应的二进制数中 “1” 的个数,将这么些结果重返为三个数组。

例如:

当 num = 5 时,重回值为 [0,1,1,2,1,2]。

/** * @param {number} num * @return {number[]} */ var countBits = function(num) { //在这里达成代码 };

1
2
3
4
5
6
7
/**
* @param {number} num
* @return {number[]}
*/
var countBits = function(num) {
    //在此处实现代码
};

二、什么是WebSocket

HTML5起来提供的一种浏览器与服务器实行全双工通信的互连网本领,属于应用层左券。它根据TCP传输合同,并复用HTTP的抓手通道。

对大多数web开辟者来讲,上边这段描述有一点枯燥,其实只要记住几点:

  1. WebSocket能够在浏览器里使用
  2. 支撑双向通讯
  3. 选择很轻松

其次步:制造三个应用程序清单(Manifest)

应用程序清单提供了和当下渐进式Web应用的连锁音信,如:

  • 应用程序名
  • 描述
  • 怀有图片(富含主荧屏Logo,运行显示屏页面和用的图形恐怕网页上用的图样)

实质上讲,程序清单是页面上用到的Logo和宗旨等能源的元数据。

程序清单是多少个放在您使用根目录的JSON文件。该JSON文件重回时必需抬高Content-Type: application/manifest+json 或者 Content-Type: application/jsonHTTP头消息。程序清单的文本名不限,在本文的演示代码中为manifest.json

{ "name" : "PWA Website", "short_name" : "PWA", "description" : "An example PWA website", "start_url" : "/", "display" : "standalone", "orientation" : "any", "background_color" : "#ACE", "theme_color" : "#ACE", "icons": [ { "src" : "/images/logo/logo072.png", "sizes" : "72x72", "type" : "image/png" }, { "src" : "/images/logo/logo152.png", "sizes" : "152x152", "type" : "image/png" }, { "src" : "/images/logo/logo192.png", "sizes" : "192x192", "type" : "image/png" }, { "src" : "/images/logo/logo256.png", "sizes" : "256x256", "type" : "image/png" }, { "src" : "/images/logo/logo512.png", "sizes" : "512x512", "type" : "image/png" } ] }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
{
  "name"              : "PWA Website",
  "short_name"        : "PWA",
  "description"       : "An example PWA website",
  "start_url"         : "/",
  "display"           : "standalone",
  "orientation"       : "any",
  "background_color"  : "#ACE",
  "theme_color"       : "#ACE",
  "icons": [
    {
      "src"           : "/images/logo/logo072.png",
      "sizes"         : "72x72",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo152.png",
      "sizes"         : "152x152",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo192.png",
      "sizes"         : "192x192",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo256.png",
      "sizes"         : "256x256",
      "type"          : "image/png"
    },
    {
      "src"           : "/images/logo/logo512.png",
      "sizes"         : "512x512",
      "type"          : "image/png"
    }
  ]
}

程序清单文件营造完现在,你须要在各样页面上引用该公文:

<link rel="manifest" href="/manifest.json">

1
<link rel="manifest" href="/manifest.json">

以下属性在程序清单中一时使用,介绍表明如下:

  • name: 客户观望的应用名称
  • short_name: 应用短名称。当展现应用名称的地点远远不够时,将运用该名称。
  • description: 选择描述。
  • start_url: 动用开始路线,相对路径,默认为/。
  • scope: UPRADOL范围。例如:假诺你将“/app/”设置为ULacrosseL范围时,那么些应用就能够直接在那几个目录中。
  • background_color: 款待页面的背景颜色和浏览器的背景颜色(可选)
  • theme_color: 运用的大旨颜色,日常都会和背景颜色一样。那几个设置决定了应用怎么样显示。
  • orientation: 优先旋转方向,可选的值有:any, natural, landscape, landscape-primary, landscape-secondary, portrait, portrait-primary, and portrait-secondary
  • display: 展现格局——fullscreen(无Chrome),standalone(和原生应用同样),minimal-ui(最小的一套UI控件集)可能browser(最古老的利用浏览器标签展现)
  • icons: 三个含有全体图片的数组。该数组中种种成分包蕴了图片的UHavalL,大小和类型。

解题思路

那道题咋一看还挺轻便的,无非是:

  • 福寿齐天三个措施 countBit,对任性非负整数 n,计算它的二进制数中“1”的个数
  • 循环 i 从 0 到 num,求 countBit(i),将值放在数组中回到。

JavaScript中,计算 countBit 能够取巧:

function countBit(n){ return n.toString(2).replace(/0/g,"").length; }

1
2
3
function countBit(n){
    return n.toString(2).replace(/0/g,"").length;
}

上边的代码里,大家向来对 n 用 toString(2) 转成二进制表示的字符串,然后去掉个中的0,剩下的正是“1”的个数。

接下来,大家写一下完好无缺的顺序:

版本1

function countBit(n){ return n.toString(2).replace(/0/g,'').length; } function countBits(nums){ var ret = []; for(var i = 0; i <= nums; i++){ ret.push(countBit(i)); } return ret; }

1
2
3
4
5
6
7
8
9
10
11
function countBit(n){
   return n.toString(2).replace(/0/g,'').length;
}
 
function countBits(nums){
   var ret = [];
   for(var i = 0; i <= nums; i++){
       ret.push(countBit(i));
   }
   return ret;
}

上边这种写法十三分得益,好处是 countBit 利用 JavaScript 语言特色完结得非凡简单,坏处是借使前天要将它改写成别的语言的本子,就有十分的大希望懵B了,它不是很通用,况兼它的属性还在于 Number.prototype.toString(2) 和 String.prototype.replace 的落到实处。

故而为了追求越来越好的写法,我们有必不可缺思虑一下 countBit 的通用达成法。

咱俩说,求贰个整数的二进制表示中 “1” 的个数,最常见的自然是三个 O(logN) 的不二等秘书籍:

function countBit(n){ var ret = 0; while(n > 0){ ret += n & 1; n >>= 1; } return ret; }

1
2
3
4
5
6
7
8
function countBit(n){
    var ret = 0;
    while(n > 0){
        ret += n & 1;
        n >>= 1;
    }
    return ret;
}

因而大家有了版本2

那般完结也很简单不是吗?可是这样完结是还是不是最优?提出此处思量10分钟再往下看。


1、有哪些亮点

聊到优点,这里的对照参照物是HTTP左券,回顾地说正是:协助双向通信,更加灵敏,越来越高速,可扩张性更加好。

  1. 援助双向通讯,实时性越来越强。
  2. 更加好的二进制支持。
  3. 很少的决定开荒。连接创造后,ws客商端、服务端实行数据调换时,合同决定的多少建邺部相当的小。在不带有底部的意况下,服务端到顾客端的宁德独有2~10字节(决议于数量包长度),顾客端到服务端的来讲,须求充裕额外的4字节的掩码。而HTTP左券每便通讯都急需指导完整的头顶。
  4. 补助扩展。ws磋商定义了增添,客商能够扩张左券,也许完结自定义的子公约。(比方扶助自定义压缩算法等)

对于背后两点,未有色金属商讨所究过WebSocket合同正式的同桌大概知道起来相当不够直观,但不影响对WebSocket的就学和利用。

其三步:创设叁个 Service Worker

Service Worker 是二个可编程的服务器代理,它能够阻挡或然响应互连网诉求。Service Worker 是坐落应用程序根目录的二个个的JavaScript文件。

您需求在页面临应的JavaScript文件中注册该ServiceWorker:

if ('serviceWorker' in navigator) { // register service worker navigator.serviceWorker.register('/service-worker.js'); }

1
2
3
4
if ('serviceWorker' in navigator) {
  // register service worker
  navigator.serviceWorker.register('/service-worker.js');
}

一旦您不需求离线的连锁职能,您能够只开创三个 /service-worker.js文件,那样客户就足以平素设置您的Web应用了!

ServiceWorker那几个定义恐怕相比难懂,它实在是贰个行事在其他线程中的规范的Worker,它不得以访谈页面上的DOM成分,未有页面上的API,可是能够阻挡全体页面上的网络央求,饱含页面导航,必要能源,Ajax央求。

地点便是运用全站HTTPS的尤为重要缘由了。假若你未有在你的网址中应用HTTPS,一个第三方的脚本就足以从任何的域名注入他和煦的ServiceWorker,然后篡改全数的央浼——那的确是老大危险的。

Service Worker 会响应几个事件:install,activate和fetch。

更快的 countBit

上贰个版本的 countBit 的时刻复杂度已是 O(logN) 了,难道还是可以更加快啊?当然是能够的,大家不须求去看清每壹个人是否“1”,也能知道 n 的二进制中有多少个“1”。

有多个秘技,是依靠以下贰个定律:

  • 对此自由 n, n ≥ 1,有如下等式创建:

countBit(n & (n - 1)) === countBit(n) - 1

1
countBit(n & (n - 1)) === countBit(n) - 1

本条很轻易领会,我们借使想转手,对于自由 n,n – 1 的二进制数表示正好是 n 的二进制数的最末三个“1”退位,因而 n & n – 1 恰好将 n 的最末一人“1”消去,比方:

  • 6 的二进制数是 110, 5 = 6 – 1 的二进制数是 101,6 & 5 的二进制数是 110 & 101 == 100
  • 88 的二进制数是 101一千,87 = 88 – 1 的二进制数是 1010111,88 & 87 的二进制数是 1011000 & 1010111 == 1010000

于是乎,大家有了二个越来越快的算法:

版本3

function countBit(n){ var ret = 0; while(n > 0){ ret++; n &= n - 1; } return ret; } function countBits(nums){ var ret = []; for(var i = 0; i <= nums; i++){ ret.push(countBit(i)); } return ret; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function countBit(n){
    var ret = 0;
    while(n > 0){
        ret++;
        n &= n - 1;
    }
    return ret;
}
 
function countBits(nums){
   var ret = [];
   for(var i = 0; i <= nums; i++){
       ret.push(countBit(i));
   }
   return ret;
}

上面的 countBit(88) 只循环 3 次,而“版本2”的 countBit(88) 却须求循环 7 次。

优化到了那几个水平,是还是不是整整都截止了吧?从算法上来讲如同早已经是极致了?真的吗?再给大家30 秒时间动脑筋一下,然后再往下看。


2、要求学习怎么着东西

对网络应用层左券的就学来说,最要害的频仍就是总是创设进度数据调换教程。当然,数据的格式是逃不掉的,因为它直接决定了商谈本身的本领。好的数额格式能让协议更敏捷、扩展性越来越好。

下文首要围绕上面几点进展:

  1. 何以树立连接
  2. 怎么样调换数据
  3. 数据帧格式
  4. 哪些保持连接

Install事件

该事件将在利用设置到位后触发。大家通常在那边运用Cache API缓存一些要求的文书。

首先,大家须求提供如下配置

  1. 缓存名称(CACHE)以及版本(version)。应用能够有八个缓存存款和储蓄,可是在使用时只会采取在那之中三个缓存存储。每当缓存存款和储蓄有转变时,新的本子号将会钦命到缓存存款和储蓄中。新的缓存存款和储蓄将会作为当下的缓存存款和储蓄,在此之前的缓存存款和储蓄将会被作废。
  2. 二个离线的页面地址(offlineU陆风X8L):当顾客访谈了后面从没访谈过的地址时,该页面将交易会示。
  3. 三个包罗了独具必需文件的数组,满含保持页面符合规律职能的CSS和JavaScript。在本示例中,笔者还增添了主页和logo。当有两样的U本田UR-VL指向同八个能源时,你也能够将这一个UPRADOL分别写到那么些数组中。offlineUEscortL将会踏向到那个数组中。
  4. 作者们也得以将一些非需求的缓存文件(installFilesDesirable)。这一个文件在装置进程中校会被下载,但只要下载退步,不会触发安装退步。

// 配置文件 const version = '1.0.0', CACHE = version + '::PWAsite', offlineU昂科威L = '/offline/', installFilesEssential = [ '/', '/manifest.json', '/css/styles.css', '/js/main.js', '/js/offlinepage.js', '/images/logo/logo152.png' ].concat(offlineURL), installFilesDesirable = [ '/favicon.ico', '/images/logo/logo016.png', '/images/hero/power-pv.jpg', '/images/hero/power-lo.jpg', '/images/hero/power-hi.jpg' ];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 配置文件
const
  version = '1.0.0',
  CACHE = version + '::PWAsite',
  offlineURL = '/offline/',
  installFilesEssential = [
    '/',
    '/manifest.json',
    '/css/styles.css',
    '/js/main.js',
    '/js/offlinepage.js',
    '/images/logo/logo152.png'
  ].concat(offlineURL),
  installFilesDesirable = [
    '/favicon.ico',
    '/images/logo/logo016.png',
    '/images/hero/power-pv.jpg',
    '/images/hero/power-lo.jpg',
    '/images/hero/power-hi.jpg'
  ];

installStaticFiles() 方法运用基于Promise的秘诀使用Cache API将文件存款和储蓄到缓存中。

// 安装静态财富 function installStaticFiles() { return caches.open(CACHE) .then(cache => { // 缓存可选文件 cache.addAll(installFilesDesirable); // 缓存必需文件 return cache.addAll(installFilesEssential); }); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 安装静态资源
function installStaticFiles() {
  return caches.open(CACHE)
    .then(cache => {
      // 缓存可选文件
      cache.addAll(installFilesDesirable);
      // 缓存必须文件
      return cache.addAll(installFilesEssential);
    });
}

最终,大家抬高四个install的风云监听器。waitUntil主意保险了service worker不会设置直到其有关的代码被实践。这里它会实践installStaticFiles()方法,然后self.skipWaiting()措施来激活service worker:

// 应用设置 self.addEventListener('install', event => { console.log('service worker: install'); // 缓存主要文件 event.waitUntil( installStaticFiles() .then(() => self.skipWaiting()) ); });

1
2
3
4
5
6
7
8
9
10
11
12
// 应用安装
self.addEventListener('install', event => {
  console.log('service worker: install');
  // 缓存主要文件
  event.waitUntil(
    installStaticFiles()
    .then(() => self.skipWaiting())
  );
});

countBits 的时刻复杂度

考虑 countBits, 上面包车型大巴算法:

  • “版本1” 的年月复杂度是 O(N*M),M 决计于 Number.prototype.toString 和 String.prototype.replace 的复杂度。
  • “版本2” 的小运复杂度是 O(N*logN)
  • “版本3” 的时刻复杂度是 O(N*M),M 是 N 的二进制数中的“1”的个数,介于 1 ~ logN 之间。

地点八个本子的 countBits 的时光复杂度都超越 O(N)。那么有未有时间复杂度 O(N) 的算法呢?

其实,“版本3”已经为大家提示了答案,答案就在上边的十三分定律里,笔者把特别等式再写贰回:

countBit(n & (n - 1)) === countBit(n) - 1

1
countBit(n & (n - 1)) === countBit(n) - 1

也正是说,假设大家驾驭了 countBit(n & (n - 1)),那么大家也就了解了 countBit(n)

而小编辈精晓 countBit(0) 的值是 0,于是,大家能够很简单的递推:

版本4

function countBits(nums){ var ret = [0]; for(var i = 1; i <= nums; i++){ ret.push(ret[i & i - 1] + 1); } return ret; }

1
2
3
4
5
6
7
function countBits(nums){
   var ret = [0];
   for(var i = 1; i <= nums; i++){
       ret.push(ret[i & i - 1] + 1);
   }
   return ret;
}

原先就像是此轻巧,你想到了呢 ╮(╯▽╰)╭

上述正是有所的内容,轻巧的标题思索起来很有趣啊?技士就相应追求完美的算法,不是啊?

那是 leetcode 算法面试题类别的率开始时期,上期大家研究另外一道题,那道题也很风趣:决断一个非负整数是不是是 4 的大背头次方,别告诉作者你用循环,想想更抢眼的法子呢~

打赏帮忙小编写出越来越多好文章,多谢!

打赏我

三、入门例子

在正儿八经介绍契约细节前,先来看多少个简练的例子,有个直观感受。例子包蕴了WebSocket服务端、WebSocket顾客端(网页端)。完整代码可以在 这里 找到。

那边服务端用了ws本条库。比异常的大家熟稔的socket.iows金玉满堂更轻量,更切合学习的目标。

Activate 事件

本条事件会在service worker被激活时发生。你也许无需这些事件,可是在演示代码中,大家在该事件时有发生时将老的缓存全体清理掉了:

// clear old caches function clearOldCaches() { return caches.keys() .then(keylist => { return Promise.all( keylist .filter(key => key !== CACHE) .map(key => caches.delete(key)) ); }); } // application activated self.addEventListener('activate', event => { console.log('service worker: activate'); // delete old caches event.waitUntil( clearOldCaches() .then(() => self.clients.claim()) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// clear old caches
function clearOldCaches() {
  return caches.keys()
    .then(keylist => {
      return Promise.all(
        keylist
          .filter(key => key !== CACHE)
          .map(key => caches.delete(key))
      );
    });
}
// application activated
self.addEventListener('activate', event => {
  console.log('service worker: activate');
    // delete old caches
  event.waitUntil(
    clearOldCaches()
    .then(() => self.clients.claim())
    );
});

注意self.clients.claim()进行时将会把当前service worker作为被激活的worker。

Fetch 事件 该事件将会在网络最早央浼时发起。该事件管理函数中,我们能够应用respondWith()艺术来威迫HTTP的GET必要然后重返:

  1. 从缓存中取到的能源文件
  2. 如若第一步失利,财富文件将会从网络中应用Fetch API来收获(和service worker中的fetch事件非亲非故)。获取到的能源将会进入到缓存中。
  3. 如果第一步和第二步均未果,将会从缓存中回到正确的能源文件。

// application fetch network data self.addEventListener('fetch', event => { // abandon non-GET requests if (event.request.method !== 'GET') return; let url = event.request.url; event.respondWith( caches.open(CACHE) .then(cache => { return cache.match(event.request) .then(response => { if (response) { // return cached file console.log('cache fetch: ' + url); return response; } // make network request return fetch(event.request) .then(newreq => { console.log('network fetch: ' + url); if (newreq.ok) cache.put(event.request, newreq.clone()); return newreq; }) // app is offline .catch(() => offlineAsset(url)); }); }) ); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// application fetch network data
self.addEventListener('fetch', event => {
  // abandon non-GET requests
  if (event.request.method !== 'GET') return;
  let url = event.request.url;
  event.respondWith(
    caches.open(CACHE)
      .then(cache => {
        return cache.match(event.request)
          .then(response => {
            if (response) {
              // return cached file
              console.log('cache fetch: ' + url);
              return response;
            }
            // make network request
            return fetch(event.request)
              .then(newreq => {
                console.log('network fetch: ' + url);
                if (newreq.ok) cache.put(event.request, newreq.clone());
                return newreq;
              })
              // app is offline
              .catch(() => offlineAsset(url));
          });
      })
  );
});

offlineAsset(url)措施中应用了有个别helper方法来回到正确的数码:

// 是不是为图片地址? let iExt = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].map(f => '.' + f); function isImage(url) { return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false); } // return 再次来到离线能源 function offlineAsset(url) { if (isImage(url)) { // 重返图片 return new Response( '<svg role="img" viewBox="0 0 400 300" xmlns=" d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>', { headers: { 'Content-Type': 'image/svg+xml', 'Cache-Control': 'no-store' }} ); } else { // return page return caches.match(offlineURL); } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 是否为图片地址?
let iExt = ['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp'].map(f => '.' + f);
function isImage(url) {
  
  return iExt.reduce((ret, ext) => ret || url.endsWith(ext), false);
  
}
  
  
// return 返回离线资源
function offlineAsset(url) {
  
  if (isImage(url)) {
  
    // 返回图片
    return new Response(
      '<svg role="img" viewBox="0 0 400 300" xmlns="http://www.w3.org/2000/svg"><title>offline</title><path d="M0 0h400v300H0z" fill="#eee" /><text x="200" y="150" text-anchor="middle" dominant-baseline="middle" font-family="sans-serif" font-size="50" fill="#ccc">offline</text></svg>',
      { headers: {
        'Content-Type': 'image/svg+xml',
        'Cache-Control': 'no-store'
      }}
    );
  
  }
  else {
  
    // return page
    return caches.match(offlineURL);
  
  }
  
}

offlineAsset()办法检查央浼是或不是为多少个图纸,然后重回三个包蕴“offline”文字的SVG文件。别的央浼将会回去 offlineUENVISIONL 页面。

Chrome开拓者工具中的ServiceWorker部分提供了有关当前页面worker的新闻。个中交易会示worker中生出的失实,还是能强制刷新,也足以让浏览器步向离线格局。

Cache Storage 部分例举了前段时间怀有曾经缓存的能源。你能够在缓存需求立异的时候点击refresh按键。

打赏帮忙自个儿写出越来越多好文章,谢谢!

任选一种支付办法

图片 16 图片 17

3 赞 8 收藏 5 评论

本文由云顶娱乐集团发布于云顶娱乐集团,转载请注明出处:入门教程,减弱HTTP央求之统一图片详解

关键词:

上一篇:没有了

下一篇:没有了