Merge pull request #1805 from omnivore-app/fix/content-parsing
fix/content parsing
This commit is contained in:
@ -93,7 +93,7 @@ export const createPageSaveRequest = async (
|
||||
url: normalizedUrl,
|
||||
})
|
||||
if (page) {
|
||||
console.log('Page already exists', page)
|
||||
console.log('Page already exists', page.id, page.url)
|
||||
articleSavingRequestId = page.id
|
||||
} else {
|
||||
page = {
|
||||
|
||||
@ -203,7 +203,7 @@ export const parsePreparedContent = async (
|
||||
return {
|
||||
canonicalUrl: url,
|
||||
parsedContent: null,
|
||||
domContent: preparedDocument.document,
|
||||
domContent: document,
|
||||
pageType: PageType.Unknown,
|
||||
}
|
||||
}
|
||||
@ -223,7 +223,7 @@ export const parsePreparedContent = async (
|
||||
if (!article?.textContent && allowRetry) {
|
||||
const newDocument = {
|
||||
...preparedDocument,
|
||||
document: '<html>' + preparedDocument.document + '</html>',
|
||||
document: '<html>' + document + '</html>',
|
||||
}
|
||||
return parsePreparedContent(
|
||||
url,
|
||||
@ -239,7 +239,9 @@ export const parsePreparedContent = async (
|
||||
// to the handlers, and have some concept of postHandle
|
||||
if (article?.content) {
|
||||
const articleDom = parseHTML(article.content).document
|
||||
const codeBlocks = articleDom.querySelectorAll('code')
|
||||
const codeBlocks = articleDom.querySelectorAll(
|
||||
'code, pre[class^="prism-"], pre[class^="language-"]'
|
||||
)
|
||||
if (codeBlocks.length > 0) {
|
||||
codeBlocks.forEach((e) => {
|
||||
if (e.textContent) {
|
||||
@ -337,7 +339,7 @@ export const parsePreparedContent = async (
|
||||
logger.info('parse-article completed')
|
||||
|
||||
return {
|
||||
domContent: preparedDocument.document,
|
||||
domContent: document,
|
||||
parsedContent: article,
|
||||
canonicalUrl,
|
||||
pageType: parseOriginalContent(dom),
|
||||
|
||||
@ -35,7 +35,7 @@ import { EveryIoHandler } from './newsletters/every-io-handler'
|
||||
import { EnergyWorldHandler } from './newsletters/energy-world'
|
||||
import { IndiaTimesHandler } from './newsletters/india-times-handler'
|
||||
|
||||
const validateUrlString = (url: string) => {
|
||||
const validateUrlString = (url: string): boolean => {
|
||||
const u = new URL(url)
|
||||
// Make sure the URL is http or https
|
||||
if (u.protocol !== 'http:' && u.protocol !== 'https:') {
|
||||
@ -49,6 +49,8 @@ const validateUrlString = (url: string) => {
|
||||
if (/^(10|172\.16|192\.168)\..*/.test(u.hostname)) {
|
||||
throw new Error('Invalid URL is private ip')
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
const contentHandlers: ContentHandler[] = [
|
||||
|
||||
@ -7,7 +7,6 @@ const { encode } = require("urlsafe-base64");
|
||||
const crypto = require("crypto");
|
||||
|
||||
const Url = require('url');
|
||||
// const puppeteer = require('puppeteer-extra');
|
||||
const axios = require('axios');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const { promisify } = require('util');
|
||||
@ -26,9 +25,10 @@ puppeteer.use(StealthPlugin());
|
||||
|
||||
// Add adblocker plugin to block all ads and trackers (saves bandwidth)
|
||||
const AdblockerPlugin = require('puppeteer-extra-plugin-adblocker');
|
||||
const createDOMPurify = require("dompurify");
|
||||
puppeteer.use(AdblockerPlugin({ blockTrackers: true }));
|
||||
|
||||
const createDOMPurify = require("dompurify");
|
||||
|
||||
const storage = new Storage();
|
||||
const ALLOWED_ORIGINS = process.env.ALLOWED_ORIGINS ? process.env.ALLOWED_ORIGINS.split(',') : [];
|
||||
const previewBucket = process.env.PREVIEW_IMAGE_BUCKET ? storage.bucket(process.env.PREVIEW_IMAGE_BUCKET) : undefined;
|
||||
@ -296,7 +296,7 @@ async function fetchContent(req, res) {
|
||||
|
||||
if (contentType === 'application/pdf') {
|
||||
const uploadedFileId = await uploadPdf(finalUrl, userId, articleSavingRequestId);
|
||||
const l = await saveUploadedPdf(userId, finalUrl, uploadedFileId, articleSavingRequestId);
|
||||
await saveUploadedPdf(userId, finalUrl, uploadedFileId, articleSavingRequestId);
|
||||
} else {
|
||||
if (!content || !title) {
|
||||
const result = await retrieveHtml(page, logRecord);
|
||||
@ -409,32 +409,6 @@ function getUrl(req) {
|
||||
return parsed.href;
|
||||
}
|
||||
|
||||
async function blockResources(client) {
|
||||
const blockedResources = [
|
||||
// Assets
|
||||
// '*/favicon.ico',
|
||||
// '.css',
|
||||
// '.jpg',
|
||||
// '.jpeg',
|
||||
// '.png',
|
||||
// '.svg',
|
||||
// '.woff',
|
||||
|
||||
// Analytics and other fluff
|
||||
'*.optimizely.com',
|
||||
'everesttech.net',
|
||||
'userzoom.com',
|
||||
'doubleclick.net',
|
||||
'googleadservices.com',
|
||||
'adservice.google.com/*',
|
||||
'connect.facebook.com',
|
||||
'connect.facebook.net',
|
||||
'sp.analytics.yahoo.com',
|
||||
]
|
||||
|
||||
await client.send('Network.setBlockedURLs', { urls: blockedResources });
|
||||
}
|
||||
|
||||
async function retrievePage(url, logRecord, functionStartTime) {
|
||||
validateUrlString(url);
|
||||
|
||||
@ -494,8 +468,6 @@ async function retrievePage(url, logRecord, functionStartTime) {
|
||||
} catch {}
|
||||
});
|
||||
|
||||
await blockResources(client);
|
||||
|
||||
/*
|
||||
* Disallow MathJax from running in Puppeteer and modifying the document,
|
||||
* we shall instead run it in our frontend application to transform any
|
||||
@ -504,7 +476,8 @@ async function retrievePage(url, logRecord, functionStartTime) {
|
||||
await page.setRequestInterception(true);
|
||||
let requestCount = 0;
|
||||
page.on('request', request => {
|
||||
if (['font', 'image', 'media'].includes(request.resourceType())) {
|
||||
if (request.resourceType() === 'font') {
|
||||
// Disallow fonts from loading
|
||||
request.abort();
|
||||
return;
|
||||
}
|
||||
@ -584,7 +557,7 @@ async function retrieveHtml(page, logRecord) {
|
||||
}
|
||||
})();
|
||||
}),
|
||||
await page.waitForTimeout(5000),
|
||||
page.waitForTimeout(5000),
|
||||
]);
|
||||
logRecord.timing = { ...logRecord.timing, pageScrolled: Date.now() - pageScrollingStart };
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@ Readability.prototype = {
|
||||
|
||||
// These are the classes that readability sets itself.
|
||||
CLASSES_TO_PRESERVE: [
|
||||
"page", "twitter-tweet", "tweet-placeholder", "instagram-placeholder", "morning-brew-markets"
|
||||
"page", "twitter-tweet", "tweet-placeholder", "instagram-placeholder", "morning-brew-markets", "prism-code"
|
||||
],
|
||||
|
||||
// Classes of placeholder elements that can be empty but shouldn't be removed
|
||||
|
||||
@ -236,6 +236,12 @@
|
||||
<a href="./test-pages/milkroad/distiller.html" target="iframe_b">[dom-distiller]</a>
|
||||
</li>
|
||||
|
||||
<li>robinwieruch.de<br />
|
||||
<a href="./test-pages/robinwieruch.de/source.html" target="iframe_b">[source]</a>
|
||||
<a href="./test-pages/robinwieruch.de/expected.html" target="iframe_b">[readability]</a>
|
||||
<a href="./test-pages/robinwieruch.de/distiller.html" target="iframe_b">[dom-distiller]</a>
|
||||
</li>
|
||||
|
||||
<li>github-blog<br />
|
||||
<a href="./test-pages/github-blog/source.html" target="iframe_b">[source]</a>
|
||||
<a href="./test-pages/github-blog/expected.html" target="iframe_b">[readability]</a>
|
||||
@ -266,6 +272,12 @@
|
||||
<a href="./test-pages/erik-engheim/distiller.html" target="iframe_b">[dom-distiller]</a>
|
||||
</li>
|
||||
|
||||
<li>habr.com<br />
|
||||
<a href="./test-pages/habr.com/source.html" target="iframe_b">[source]</a>
|
||||
<a href="./test-pages/habr.com/expected.html" target="iframe_b">[readability]</a>
|
||||
<a href="./test-pages/habr.com/distiller.html" target="iframe_b">[dom-distiller]</a>
|
||||
</li>
|
||||
|
||||
<li>fast-company<br />
|
||||
<a href="./test-pages/fast-company/source.html" target="iframe_b">[source]</a>
|
||||
<a href="./test-pages/fast-company/expected.html" target="iframe_b">[readability]</a>
|
||||
@ -416,6 +428,12 @@
|
||||
<a href="./test-pages/ft.com/distiller.html" target="iframe_b">[dom-distiller]</a>
|
||||
</li>
|
||||
|
||||
<li>yuyue.com<br />
|
||||
<a href="./test-pages/yuyue.com/source.html" target="iframe_b">[source]</a>
|
||||
<a href="./test-pages/yuyue.com/expected.html" target="iframe_b">[readability]</a>
|
||||
<a href="./test-pages/yuyue.com/distiller.html" target="iframe_b">[dom-distiller]</a>
|
||||
</li>
|
||||
|
||||
<li>debugger.medium<br />
|
||||
<a href="./test-pages/debugger.medium/source.html" target="iframe_b">[source]</a>
|
||||
<a href="./test-pages/debugger.medium/expected.html" target="iframe_b">[readability]</a>
|
||||
|
||||
243
packages/readabilityjs/test/test-pages/habr.com/distiller.html
Normal file
243
packages/readabilityjs/test/test-pages/habr.com/distiller.html
Normal file
@ -0,0 +1,243 @@
|
||||
<div><div>
|
||||
<span>4 мин</span>
|
||||
</div><div><span title="Количество просмотров"> <span>22K</span></span>
|
||||
</div><img src="https://habrastorage.org/webt/ai/z5/gz/aiz5gztttvvkegk_annvvgtumv8.png"/><div><i><span>Картинка, конечно, стронгли анрилейтед</span></i><br/>
|
||||
<br/>
|
||||
Разные трюки я тестировал на Google Chrome 107.0.5304.107 и Mozilla Firefox 107.0 на Windows 10.<br/>
|
||||
<br/>
|
||||
Чтобы результаты всегда были железно воспроизводимыми, я отключил все С-State’ы, ядра зафиксировал на 5 ГГц.<br/>
|
||||
<br/>
|
||||
У меня 9900К, это Coffee Lake c AVX256, какие оптимизации применит Jit для вашего процессора — я не знаю, результат на вашем компьютере может отличаться от моего, в т.ч. из-за микроархитектуры процессора.<br/>
|
||||
<br/>
|
||||
Скорость парсинга кода тоже входит в бенчмарк, поэтому браузер с быстрым парсером будет впереди.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Есть ли у переменной оверхед?</span>
|
||||
</h2><div><br/>
|
||||
Есть ли смысл использовать только dot notation? Какова цена выноса лишней переменной?<br/>
|
||||
<br/>
|
||||
</div><pre><code><span>var</span> array = <span>new</span> <span>Array</span>(<span>65535</span>).fill()
|
||||
|
||||
|
||||
<span>var</span> a = array.map(<span>(<span>x</span>) =></span> x)
|
||||
<span>var</span> b = array.map(<span>(<span>x</span>) =></span> x)
|
||||
<span>var</span> c = array.map(<span>(<span>x</span>) =></span> x)
|
||||
|
||||
|
||||
<span>var</span> a = array.map(<span>(<span>x</span>) =></span> x)
|
||||
<span>var</span> b = array.map(<span>(<span>x</span>) =></span> x).map(<span>(<span>x</span>) =></span> x)
|
||||
|
||||
|
||||
<span>var</span> a = array.map(<span>(<span>x</span>) =></span> x).map(<span>(<span>x</span>) =></span> x).map(<span>(<span>x</span>) =></span> x)</code></pre><div><br/>
|
||||
Чтобы узнать, гоняет ли браузер память туда-сюда, делаем мы <code>.map</code> на массив длиной 65535 с нулями внутри. <a href="https://www.measurethat.net/Benchmarks/Show/22097/0/1-var-vs-2-vars-vs-3-vars">Линк</a>.<br/>
|
||||
<br/>
|
||||
<i><span>Здесь и далее в качестве единицы измерения на графиках будет указано кол-во выполнений кода в секунду, включая парсинг и компиляцию. Больше — лучше</span></i><br/>
|
||||
<br/>
|
||||
Хром не заметил разницы, а вот лиса заметила. Применительно к лисе, у лишней переменной есть измеряемый оверхед.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Есть ли разница между var, let, const или их отсутствием?</span>
|
||||
</h2><div><br/>
|
||||
<br/>
|
||||
Проверим. Используя разные биндинги — создадим POJO с переменной <code>е</code>. Потом добавим ему функцию <code>о</code> и запустим эту функцию. Бенчмарк простой, но движущихся частей много. <a href="https://www.measurethat.net/Benchmarks/Show/22083/0/const-vs-let-vs-var-vs-sloppy">Линк</a>.<br/>
|
||||
<br/>
|
||||
</div><pre><code><span>var</span> g = { <span>e</span>: [] }
|
||||
g.o = <span><span>function</span>(<span>x</span>) </span>{ g.e.push(...[<span>1</span>,<span>2</span>,<span>3</span>]) }
|
||||
g.o()</code></pre><div><br/>
|
||||
Код выглядит так, отличаются только биндинги.<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
Результат неожиданный, но железно воспроизводимый. <code>var</code>, быстрее.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Bounce pattern, Switch case, длинная тернарка</span>
|
||||
</h2><div><br/>
|
||||
Если обе конструкции логически одинаковые, они должны строить одно и то же синтаксическое дерево, верно? Давайте проверим.<br/>
|
||||
<br/>
|
||||
</div><pre><code>
|
||||
<span><span>function</span> <span>thing</span>(<span>e</span>) </span>{
|
||||
<span>switch</span> (e) {
|
||||
<span>case</span> <span>0</span>:
|
||||
<span>return</span> <span>"0"</span>;
|
||||
|
||||
<span>case</span> <span>1</span>:
|
||||
<span>return</span> <span>"1"</span>;
|
||||
|
||||
<span>case</span> <span>2</span>:
|
||||
<span>return</span> <span>"2"</span>;
|
||||
|
||||
<span>case</span> <span>3</span>:
|
||||
<span>return</span> <span>"3"</span>;
|
||||
|
||||
<span>default</span>:
|
||||
<span>return</span> <span>""</span>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
<span><span>function</span> <span>bounce</span>(<span>x</span>)
|
||||
</span>{
|
||||
<span>if</span> (x === <span>0</span>) <span>return</span> <span>"0"</span>;
|
||||
<span>if</span> (x === <span>1</span>) <span>return</span> <span>"1"</span>;
|
||||
<span>if</span> (x === <span>2</span>) <span>return</span> <span>"2"</span>;
|
||||
<span>if</span> (x === <span>3</span>) <span>return</span> <span>"3"</span>;
|
||||
|
||||
<span>return</span> <span>""</span>
|
||||
}
|
||||
|
||||
|
||||
<span><span>function</span> <span>bounce</span>(<span>x</span>) </span>{
|
||||
<span>return</span> <span>0</span> === x ? <span>"0"</span> : <span>1</span> === x ? <span>"1"</span> : <span>2</span> === x ? <span>"2"</span> : <span>3</span> === x ? <span>"3"</span> : <span>""</span>;
|
||||
}</code></pre><div><br/>
|
||||
Вот так выглядит код. Для всех вариантов он одинаков, отличаются только вызовы.<br/>
|
||||
<br/>
|
||||
</div><h3>
|
||||
<span>▍ 1. Вызов в цикле</span>
|
||||
</h3><pre><code><span>for</span> (<span>let</span> t = <span>0</span>; <span>1e5</span> > t; t++) bounce(<span>0</span>), bounce(<span>2</span>), bounce(<span>6</span>);</code></pre><div><br/>
|
||||
Вызов выглядит так. <a href="https://www.measurethat.net/Benchmarks/Show/22099/0/no-type-coercion-switch-case-vs-bounce-pattern-vs-terna">Линк</a>.<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
</div><h3>
|
||||
<span>▍ 2. В цикле с другим типом</span>
|
||||
</h3><pre><code><span>for</span> (<span>let</span> t = <span>0</span>; <span>1e5</span> > t; t++) bounce(<span>"0"</span>), bounce(<span>"2"</span>), bounce(<span>""</span>);</code></pre><div><br/>
|
||||
Тут мы покидываем строку вместо числа. В свитче и <code>if</code> блоках используется строгое равенство, поэтому свитч выходит только через <code>default</code>, а <code>if</code>’ы выходят только последний <code>return</code>. <a href="https://www.measurethat.net/Benchmarks/Show/22098/0/type-coercion-switch-case-vs-bounce-pattern-vs-ternary">Линк</a>.<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
</div><h3>
|
||||
<span>▍ 3. Без цикла</span>
|
||||
</h3><pre><code>bounce(<span>0</span>), bounce(<span>2</span>), bounce(<span>6</span>)</code></pre><div><br/>
|
||||
Просто три вызова подряд, никаких циклов. <a href="https://www.measurethat.net/Benchmarks/Show/22100/0/no-loop-switch-case-vs-bounce-pattern-vs-ternary">Линк</a>.<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
Похоже, что после первоначальной компиляции лиса не пытается дальше оптимизировать цикл, как это делает хром.<br/>
|
||||
<br/>
|
||||
Также лиса, похоже, не строит одно и то же AST, как это делает хром. Рекомендую заменить ваши длинные <code>if</code>’ы и bounce паттерны на свитчи, чтобы избежать лисиных тормозов.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Инициализация массива</span>
|
||||
</h2><div><br/>
|
||||
Для примера возьму из паттернов функционального программирования, когда ты инициализируешь массив, прокидывая лямбду в инициализатор. Просто ради примера, в качестве этой лямбды будет fizzbuzz.<br/>
|
||||
<br/>
|
||||
</div><pre><code><span>var</span> times = <span>65535</span>;
|
||||
|
||||
<span><span>function</span> <span>initializer</span>(<span>val, z</span>) </span>{
|
||||
<span>const</span> i = z % <span>5</span> | <span>0</span>;
|
||||
<span>return</span> <span>0</span> == (z % <span>3</span> | <span>0</span>) ? <span>0</span> === i ? <span>"fizzbuzz"</span> : <span>"fizz"</span> : <span>0</span> === i ? <span>"buzz"</span> : z;
|
||||
}
|
||||
|
||||
|
||||
<span>var</span> b = <span>new</span> <span>Array</span>(times);
|
||||
<span>for</span> (<span>var</span> i = <span>0</span>; i < times; i++) {
|
||||
b[i] = initializer(b[i], i)
|
||||
}
|
||||
b
|
||||
|
||||
|
||||
<span>var</span> c = [];
|
||||
<span>for</span> (<span>var</span> i = <span>0</span>; i < times; i++) {
|
||||
c.push(initializer(c[i], i))
|
||||
}
|
||||
c
|
||||
|
||||
|
||||
<span>new</span> <span>Array</span>(times).fill().map(initializer)
|
||||
</code></pre><div><br/>
|
||||
Это не самый красивый fizzbuzz, но это мой fizzbuzz. <a href="https://www.measurethat.net/Benchmarks/Show/22086/0/array-initialization-for-for-push-fill-map">Линк на бенч</a>.<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
Вариант с <code>fill map</code> создаёт два массива, сначала при вызове конструктора, потом при вызове map. Но такой вариант безальтернативно быстрее на хроме.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Конкатенация массивов</span>
|
||||
</h2><pre><code>
|
||||
arr.reduce(<span>(<span>acc, val</span>) =></span> acc.concat(val), [])
|
||||
|
||||
|
||||
arr.flatMap(<span><span>x</span> =></span> x)
|
||||
|
||||
|
||||
arr.flat()
|
||||
|
||||
|
||||
arr.reduce(<span>(<span>acc, val</span>) =></span> {
|
||||
<span>if</span> (val) val.forEach(<span><span>a</span> =></span> acc.push(a));
|
||||
<span>return</span> acc;
|
||||
}, [])
|
||||
|
||||
|
||||
<span>let</span> acc = [];
|
||||
|
||||
arr.forEach(<span><span>val</span> =></span> {
|
||||
val && val.forEach(<span><span>v</span> =></span> acc.push(v));
|
||||
}), acc;
|
||||
|
||||
|
||||
[].concat(...arr)
|
||||
</code></pre><div><br/>
|
||||
Конкатенация массивов на 1 уровень, поведение идентичное <code>flat(1)</code>. <a href="https://www.measurethat.net/Benchmarks/Show/22085/0/flat-vs-flatmap-vs-reduce-vs-reduce-push-vs-foreach-pus">Линк</a>.<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
Иногда я не понимаю, почему разработчики движков оставили такой потенциал для оптимизации.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Уничтожение хрома</span>
|
||||
</h2><div><br/>
|
||||
Бенчмарки ниже я перепроверял по нескольку раз, результат одинаковый и верный. Лиса действительно такая быстрая.<br/>
|
||||
<br/>
|
||||
</div><h3>
|
||||
<span>▍ Итерация по массиву</span>
|
||||
</h3><div><br/>
|
||||
Сравнивать будем <code>Array.prototype.forEach vs for...of vs for</code>. На код смотрите <a href="https://www.measurethat.net/Benchmarks/Show/22095/0/side-effect-for-i-vs-for-of-vs-foreach-fix">по линку</a>.<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
Ради производительности, циклы <code>for</code>, лучше переделать в <code>forEach</code>, чтобы хром не отставал.<br/>
|
||||
<br/>
|
||||
</div><h3>
|
||||
<span>▍ Содержит ли строка значение</span>
|
||||
</h3><pre><code>
|
||||
url.includes(<span>'matchthis'</span>)
|
||||
|
||||
|
||||
/matchthis/.test(url)
|
||||
|
||||
|
||||
url.match(<span>/matchthis/</span>).length >= <span>0</span>
|
||||
|
||||
|
||||
url.indexOf(<span>'matchthis'</span>) >= <span>0</span>
|
||||
|
||||
|
||||
url.search(<span>'matchthis'</span>) >= <span>0</span>
|
||||
</code></pre><div><br/>
|
||||
<br/>
|
||||
<br/>
|
||||
Трюк с <code>IndexOf</code> быстрее и на лисе, и на хроме. Используйте трюк с <code>IndexOf</code>. <a href="https://www.measurethat.net/Benchmarks/Show/22090/0/includes-vs-test-vs-match-vs-indexof-vs-search-fix">Линк на бенчмарк</a>.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Преобразование строки в число</span>
|
||||
</h2><div><br/>
|
||||
Тестируем неявное преобразование, парсинг и вызов конструктора.<br/>
|
||||
<br/>
|
||||
</div><pre><code>
|
||||
<span>var</span> imp = + strNum
|
||||
|
||||
|
||||
<span>var</span> toStr = <span>parseFloat</span>(strNum)
|
||||
|
||||
|
||||
<span>var</span> num = <span>Number</span>(strNum)
|
||||
</code></pre><div><br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<a href="https://www.measurethat.net/Benchmarks/Show/21897/0/implicit-vs-parseint-vs-number-string-to-num">Линк на бенч</a>.<br/>
|
||||
<br/>
|
||||
</div><h3>
|
||||
<span>▍ Float</span>
|
||||
</h3><div><br/>
|
||||
<br/>
|
||||
<br/>
|
||||
Я перепроверял, это не ошибка. Неявный каст стринги в инт практически бесплатный у лисы. <a href="https://www.measurethat.net/Benchmarks/Show/22092/0/implicit-vs-parsefloat-vs-number-string-to-num">Линк на бенч</a>.<br/>
|
||||
<br/>
|
||||
</div><h2>
|
||||
<span>Выводы</span>
|
||||
</h2><ol><li>Лисичка похорошела.</li><li>JS сделан за неделю на коленке.</li><li>Я не пишу на JS.</li><li>Вы тоже прекращайте.</li></ol></div>
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "Js, трюки, наблюдения, бенчмарки и как Лиса уничтожает Хром. Я протестировал всё, что вам было лень",
|
||||
"byline": "programmerguru",
|
||||
"dir": null,
|
||||
"excerpt": "Картинка, конечно, стронгли анрилейтед Разные трюки я тестировал на Google Chrome 107.0.5304.107 и Mozilla Firefox 107.0 на Windows 10. Чтобы результаты всегда...",
|
||||
"siteName": "Habr",
|
||||
"siteIcon": "https://assets.habr.com/habr-web/img/favicons/favicon-16.png",
|
||||
"previewImage": "https://habr.com/share/publication/712386/ff74768c013a8fb6236b5cbace64588a/",
|
||||
"publishedDate": "2023-01-24T09:00:03.000Z",
|
||||
"language": "Russian",
|
||||
"readerable": true
|
||||
}
|
||||
277
packages/readabilityjs/test/test-pages/habr.com/expected.html
Normal file
277
packages/readabilityjs/test/test-pages/habr.com/expected.html
Normal file
@ -0,0 +1,277 @@
|
||||
<DIV class="page" id="readability-page-1">
|
||||
<article>
|
||||
<!---->
|
||||
<div id="post-content-body" data-gallery-root="" lang="ru" xml:lang="ru" xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://habr.com/ru/company/ruvds/blog/712386/">
|
||||
<p><img src="https://habrastorage.org/r/w1560/webt/ai/z5/gz/aiz5gztttvvkegk_annvvgtumv8.png" data-src="https://habrastorage.org/webt/ai/z5/gz/aiz5gztttvvkegk_annvvgtumv8.png">
|
||||
</p>
|
||||
</a>
|
||||
<p><i><SPAN color="#999999">Картинка, конечно, стронгли анрилейтед</SPAN></i></p>
|
||||
<p> Разные трюки я тестировал на Google Chrome 107.0.5304.107 и Mozilla Firefox 107.0 на Windows 10.</p>
|
||||
<p> Чтобы результаты всегда были железно воспроизводимыми, я отключил все С-State’ы, ядра зафиксировал на 5 ГГц.</p>
|
||||
<p> У меня 9900К, это Coffee Lake c AVX256, какие оптимизации применит Jit для вашего процессора — я не знаю, результат на вашем компьютере может отличаться от моего, в т.ч. из-за микроархитектуры процессора.</p>
|
||||
<p> Скорость парсинга кода тоже входит в бенчмарк, поэтому браузер с быстрым парсером будет впереди.<br>
|
||||
<a name="habracut" id="habracut"></a>
|
||||
</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Есть ли у переменной оверхед?</SPAN>
|
||||
</h2>
|
||||
<p> Есть ли смысл использовать только dot notation? Какова цена выноса лишней переменной?</p>
|
||||
<pre><code><span>var</span> array = <span>new</span> <span>Array</span>(<span>65535</span>).fill()
|
||||
|
||||
<span>// 3</span>
|
||||
<span>var</span> a = array.map(<span>(<span>x</span>) =></span> x)
|
||||
<span>var</span> b = array.map(<span>(<span>x</span>) =></span> x)
|
||||
<span>var</span> c = array.map(<span>(<span>x</span>) =></span> x)
|
||||
|
||||
<span>// 2</span>
|
||||
<span>var</span> a = array.map(<span>(<span>x</span>) =></span> x)
|
||||
<span>var</span> b = array.map(<span>(<span>x</span>) =></span> x).map(<span>(<span>x</span>) =></span> x)
|
||||
|
||||
<span>// 1</span>
|
||||
<span>var</span> a = array.map(<span>(<span>x</span>) =></span> x).map(<span>(<span>x</span>) =></span> x).map(<span>(<span>x</span>) =></span> x)</code></pre>
|
||||
<p> Чтобы узнать, гоняет ли браузер память туда-сюда, делаем мы <code>.map</code> на массив длиной 65535 с нулями внутри. <a href="https://www.measurethat.net/Benchmarks/Show/22097/0/1-var-vs-2-vars-vs-3-vars">Линк</a>.</p>
|
||||
<p><i><SPAN color="#999999">Здесь и далее в качестве единицы измерения на графиках будет указано кол-во выполнений кода в секунду, включая парсинг и компиляцию. Больше — лучше</SPAN></i></p>
|
||||
<p> Хром не заметил разницы, а вот лиса заметила. Применительно к лисе, у лишней переменной есть измеряемый оверхед.</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Есть ли разница между var, let, const или их отсутствием?</SPAN>
|
||||
</h2><br>
|
||||
<p> Проверим. Используя разные биндинги — создадим POJO с переменной <code>е</code>. Потом добавим ему функцию <code>о</code> и запустим эту функцию. Бенчмарк простой, но движущихся частей много. <a href="https://www.measurethat.net/Benchmarks/Show/22083/0/const-vs-let-vs-var-vs-sloppy">Линк</a>.</p>
|
||||
<pre><code><span>var</span> g = { <span>e</span>: [] }
|
||||
g.o = <span><span>function</span>(<span>x</span>) </span>{ g.e.push(...[<span>1</span>,<span>2</span>,<span>3</span>]) }
|
||||
g.o()</code></pre>
|
||||
<p> Код выглядит так, отличаются только биндинги.</p>
|
||||
<p> Результат неожиданный, но железно воспроизводимый. <code>var</code>, быстрее.</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Bounce pattern, Switch case, длинная тернарка</SPAN>
|
||||
</h2>
|
||||
<p> Если обе конструкции логически одинаковые, они должны строить одно и то же синтаксическое дерево, верно? Давайте проверим.</p>
|
||||
<pre><code><span>// switch case</span>
|
||||
<span><span>function</span> <span>thing</span>(<span>e</span>) </span>{
|
||||
<span>switch</span> (e) {
|
||||
<span>case</span> <span>0</span>:
|
||||
<span>return</span> <span>"0"</span>;
|
||||
|
||||
<span>case</span> <span>1</span>:
|
||||
<span>return</span> <span>"1"</span>;
|
||||
|
||||
<span>case</span> <span>2</span>:
|
||||
<span>return</span> <span>"2"</span>;
|
||||
|
||||
<span>case</span> <span>3</span>:
|
||||
<span>return</span> <span>"3"</span>;
|
||||
|
||||
<span>default</span>:
|
||||
<span>return</span> <span>""</span>;
|
||||
}
|
||||
}
|
||||
|
||||
<span>// bounce pattern</span>
|
||||
<span><span>function</span> <span>bounce</span>(<span>x</span>)
|
||||
</span>{
|
||||
<span>if</span> (x === <span>0</span>) <span>return</span> <span>"0"</span>;
|
||||
<span>if</span> (x === <span>1</span>) <span>return</span> <span>"1"</span>;
|
||||
<span>if</span> (x === <span>2</span>) <span>return</span> <span>"2"</span>;
|
||||
<span>if</span> (x === <span>3</span>) <span>return</span> <span>"3"</span>;
|
||||
|
||||
<span>return</span> <span>""</span>
|
||||
}
|
||||
|
||||
<span>// ternary</span>
|
||||
<span><span>function</span> <span>bounce</span>(<span>x</span>) </span>{
|
||||
<span>return</span> <span>0</span> === x ? <span>"0"</span> : <span>1</span> === x ? <span>"1"</span> : <span>2</span> === x ? <span>"2"</span> : <span>3</span> === x ? <span>"3"</span> : <span>""</span>;
|
||||
}</code></pre>
|
||||
<p> Вот так выглядит код. Для всех вариантов он одинаков, отличаются только вызовы.</p>
|
||||
<h3>
|
||||
<SPAN color="#3AC1EF">▍ 1. Вызов в цикле</SPAN>
|
||||
</h3><br>
|
||||
<pre><code><span>for</span> (<span>let</span> t = <span>0</span>; <span>1e5</span> > t; t++) bounce(<span>0</span>), bounce(<span>2</span>), bounce(<span>6</span>);</code></pre>
|
||||
<p> Вызов выглядит так. <a href="https://www.measurethat.net/Benchmarks/Show/22099/0/no-type-coercion-switch-case-vs-bounce-pattern-vs-terna">Линк</a>.</p><br>
|
||||
<h3>
|
||||
<SPAN color="#3AC1EF">▍ 2. В цикле с другим типом</SPAN>
|
||||
</h3><br>
|
||||
<pre><code><span>for</span> (<span>let</span> t = <span>0</span>; <span>1e5</span> > t; t++) bounce(<span>"0"</span>), bounce(<span>"2"</span>), bounce(<span>""</span>);</code></pre>
|
||||
<p> Тут мы покидываем строку вместо числа. В свитче и <code>if</code> блоках используется строгое равенство, поэтому свитч выходит только через <code>default</code>, а <code>if</code>’ы выходят только последний <code>return</code>. <a href="https://www.measurethat.net/Benchmarks/Show/22098/0/type-coercion-switch-case-vs-bounce-pattern-vs-ternary">Линк</a>.</p><br>
|
||||
<h3>
|
||||
<SPAN color="#3AC1EF">▍ 3. Без цикла</SPAN>
|
||||
</h3><br>
|
||||
<pre><code>bounce(<span>0</span>), bounce(<span>2</span>), bounce(<span>6</span>)</code></pre>
|
||||
<p> Просто три вызова подряд, никаких циклов. <a href="https://www.measurethat.net/Benchmarks/Show/22100/0/no-loop-switch-case-vs-bounce-pattern-vs-ternary">Линк</a>.</p>
|
||||
<p> Похоже, что после первоначальной компиляции лиса не пытается дальше оптимизировать цикл, как это делает хром.</p>
|
||||
<p> Также лиса, похоже, не строит одно и то же AST, как это делает хром. Рекомендую заменить ваши длинные <code>if</code>’ы и bounce паттерны на свитчи, чтобы избежать лисиных тормозов.</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Инициализация массива</SPAN>
|
||||
</h2>
|
||||
<p> Для примера возьму из паттернов функционального программирования, когда ты инициализируешь массив, прокидывая лямбду в инициализатор. Просто ради примера, в качестве этой лямбды будет fizzbuzz.</p>
|
||||
<pre><code><span>var</span> times = <span>65535</span>;
|
||||
|
||||
<span><span>function</span> <span>initializer</span>(<span>val, z</span>) </span>{
|
||||
<span>const</span> i = z % <span>5</span> | <span>0</span>;
|
||||
<span>return</span> <span>0</span> == (z % <span>3</span> | <span>0</span>) ? <span>0</span> === i ? <span>"fizzbuzz"</span> : <span>"fizz"</span> : <span>0</span> === i ? <span>"buzz"</span> : z;
|
||||
}
|
||||
|
||||
<span>// for i</span>
|
||||
<span>var</span> b = <span>new</span> <span>Array</span>(times);
|
||||
<span>for</span> (<span>var</span> i = <span>0</span>; i < times; i++) {
|
||||
b[i] = initializer(b[i], i)
|
||||
}
|
||||
b
|
||||
|
||||
<span>// for push</span>
|
||||
<span>var</span> c = [];
|
||||
<span>for</span> (<span>var</span> i = <span>0</span>; i < times; i++) {
|
||||
c.push(initializer(c[i], i))
|
||||
}
|
||||
c
|
||||
|
||||
<span>// Fill Map</span>
|
||||
<span>new</span> <span>Array</span>(times).fill().map(initializer)
|
||||
</code></pre>
|
||||
<p> Это не самый красивый fizzbuzz, но это мой fizzbuzz. <a href="https://www.measurethat.net/Benchmarks/Show/22086/0/array-initialization-for-for-push-fill-map">Линк на бенч</a>.</p>
|
||||
<p> Вариант с <code>fill map</code> создаёт два массива, сначала при вызове конструктора, потом при вызове map. Но такой вариант безальтернативно быстрее на хроме.</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Конкатенация массивов</SPAN>
|
||||
</h2><br>
|
||||
<br>
|
||||
<pre><code><span>// reduce</span>
|
||||
arr.reduce(<span>(<span>acc, val</span>) =></span> acc.concat(val), [])
|
||||
|
||||
<span>// flatMap</span>
|
||||
arr.flatMap(<span><span>x</span> =></span> x)
|
||||
|
||||
<span>// flat</span>
|
||||
arr.flat()
|
||||
|
||||
<span>// reduce push</span>
|
||||
arr.reduce(<span>(<span>acc, val</span>) =></span> {
|
||||
<span>if</span> (val) val.forEach(<span><span>a</span> =></span> acc.push(a));
|
||||
<span>return</span> acc;
|
||||
}, [])
|
||||
|
||||
<span>// forEach push</span>
|
||||
<span>let</span> acc = [];
|
||||
|
||||
arr.forEach(<span><span>val</span> =></span> {
|
||||
val && val.forEach(<span><span>v</span> =></span> acc.push(v));
|
||||
}), acc;
|
||||
|
||||
<span>//concat spread</span>
|
||||
[].concat(...arr)
|
||||
</code></pre>
|
||||
<p> Конкатенация массивов на 1 уровень, поведение идентичное <code>flat(1)</code>. <a href="https://www.measurethat.net/Benchmarks/Show/22085/0/flat-vs-flatmap-vs-reduce-vs-reduce-push-vs-foreach-pus">Линк</a>.</p>
|
||||
<p> Иногда я не понимаю, почему разработчики движков оставили такой потенциал для оптимизации.</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Уничтожение хрома</SPAN>
|
||||
</h2>
|
||||
<p> Бенчмарки ниже я перепроверял по нескольку раз, результат одинаковый и верный. Лиса действительно такая быстрая.</p>
|
||||
<h3>
|
||||
<SPAN color="#3AC1EF">▍ Итерация по массиву</SPAN>
|
||||
</h3>
|
||||
<p> Сравнивать будем <code>Array.prototype.forEach vs for...of vs for</code>. На код смотрите <a href="https://www.measurethat.net/Benchmarks/Show/22095/0/side-effect-for-i-vs-for-of-vs-foreach-fix">по линку</a>.</p>
|
||||
<p> Ради производительности, циклы <code>for</code>, лучше переделать в <code>forEach</code>, чтобы хром не отставал.</p>
|
||||
<h3>
|
||||
<SPAN color="#3AC1EF">▍ Содержит ли строка значение</SPAN>
|
||||
</h3><br>
|
||||
<pre><code><span>// text.includes()</span>
|
||||
url.includes(<span>'matchthis'</span>)
|
||||
|
||||
<span>// text.test()</span>
|
||||
/matchthis/.test(url)
|
||||
|
||||
<span>// text.match()</span>
|
||||
url.match(<span>/matchthis/</span>).length >= <span>0</span>
|
||||
|
||||
<span>// text.indexOf()</span>
|
||||
url.indexOf(<span>'matchthis'</span>) >= <span>0</span>
|
||||
|
||||
<span>// text.search()</span>
|
||||
url.search(<span>'matchthis'</span>) >= <span>0</span>
|
||||
</code></pre>
|
||||
<p> Трюк с <code>IndexOf</code> быстрее и на лисе, и на хроме. Используйте трюк с <code>IndexOf</code>. <a href="https://www.measurethat.net/Benchmarks/Show/22090/0/includes-vs-test-vs-match-vs-indexof-vs-search-fix">Линк на бенчмарк</a>.</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Преобразование строки в число</SPAN>
|
||||
</h2>
|
||||
<p> Тестируем неявное преобразование, парсинг и вызов конструктора.</p>
|
||||
<pre><code><span>// implicit</span>
|
||||
<span>var</span> imp = + strNum
|
||||
|
||||
<span>// parseFloat</span>
|
||||
<span>var</span> toStr = <span>parseFloat</span>(strNum)
|
||||
|
||||
<span>//Number</span>
|
||||
<span>var</span> num = <span>Number</span>(strNum)
|
||||
</code></pre><br>
|
||||
<h3>
|
||||
<SPAN color="#3AC1EF">▍ Int</SPAN>
|
||||
</h3>
|
||||
<p><a href="https://www.measurethat.net/Benchmarks/Show/21897/0/implicit-vs-parseint-vs-number-string-to-num">Линк на бенч</a>.</p>
|
||||
<h3>
|
||||
<SPAN color="#3AC1EF">▍ Float</SPAN>
|
||||
</h3>
|
||||
<p> Я перепроверял, это не ошибка. Неявный каст стринги в инт практически бесплатный у лисы. <a href="https://www.measurethat.net/Benchmarks/Show/22092/0/implicit-vs-parsefloat-vs-number-string-to-num">Линк на бенч</a>.</p>
|
||||
<h2>
|
||||
<SPAN color="#3AC1EF">Выводы</SPAN>
|
||||
</h2><br>
|
||||
<ol>
|
||||
<li>Лисичка похорошела. </li>
|
||||
<li>JS сделан за неделю на коленке. </li>
|
||||
<li>Я не пишу на JS. </li>
|
||||
<li>Вы тоже прекращайте. </li>
|
||||
</ol><br>
|
||||
<blockquote>
|
||||
<b><a href="https://t.me/ruvds_community/130"><SPAN color="#3AC1EF">Играй в нашу новую игру прямо в Telegram!</SPAN></a></b>
|
||||
</blockquote>
|
||||
<p><a href="http://ruvds.com/ru-rub?utm_source=habr&utm_medium=article&utm_campaign=programmerguru&utm_content=js_tryuki_nablyudeniya_benchmarki_i_kak_lisa_unichtozhaet_xrom_ya_protestiroval_vsyo_chto_vam_bylo_len"><img src="https://habrastorage.org/r/w1560/webt/sz/7j/pf/sz7jpfj8i1pa6ocj-eia09dev4q.png" data-src="https://habrastorage.org/webt/sz/7j/pf/sz7jpfj8i1pa6ocj-eia09dev4q.png"></a>
|
||||
</p>
|
||||
</div>
|
||||
<!---->
|
||||
<div>
|
||||
<div>
|
||||
<p><span>Теги:</span></p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/search/?target_type=posts&order=relevance&q=%5Bjavascript%5D">javascript</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/search/?target_type=posts&order=relevance&q=%5Bgoogle%20chrome%5D">google chrome</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/search/?target_type=posts&order=relevance&q=%5Bmozilla%20firefox%5D">mozilla firefox</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/search/?target_type=posts&order=relevance&q=%5B%D0%B1%D1%80%D0%B0%D1%83%D0%B7%D0%B5%D1%80%D1%8B%5D">браузеры</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/search/?target_type=posts&order=relevance&q=%5B%D0%B2%D1%8B%D1%81%D0%BE%D0%BA%D0%B0%D1%8F%20%D0%BF%D1%80%D0%BE%D0%B8%D0%B7%D0%B2%D0%BE%D0%B4%D0%B8%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C%5D">высокая производительность</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/search/?target_type=posts&order=relevance&q=%5B%D0%BE%D0%BF%D1%82%D0%B8%D0%BC%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F%5D">оптимизация</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/search/?target_type=posts&order=relevance&q=%5Bruvds_%D1%81%D1%82%D0%B0%D1%82%D1%8C%D0%B8%5D">ruvds_статьи</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<p><span>Хабы:</span></p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/company/ruvds/blog/">Блог компании RUVDS.com</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/hub/hi/">Высокая производительность</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/hub/javascript/">JavaScript</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/hub/client_side_optimization/">Клиентская оптимизация</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="http://fakehost/ru/hub/browsers/">Браузеры</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</DIV>
|
||||
1776
packages/readabilityjs/test/test-pages/habr.com/source.html
Normal file
1776
packages/readabilityjs/test/test-pages/habr.com/source.html
Normal file
File diff suppressed because it is too large
Load Diff
1
packages/readabilityjs/test/test-pages/habr.com/url.txt
Normal file
1
packages/readabilityjs/test/test-pages/habr.com/url.txt
Normal file
@ -0,0 +1 @@
|
||||
https://habr.com/ru/company/ruvds/blog/712386/
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "How to fetch data with React Hooks",
|
||||
"byline": "Robin Wieruch",
|
||||
"dir": null,
|
||||
"excerpt": "A tutorial on how to fetch data in React with Hooks from third-party APIs. You will use state and effect hooks for the data request from a real API ...",
|
||||
"siteName": null,
|
||||
"siteIcon": "http://fakehost/favicon-32x32.png?v=9db82c76a9aaf54925ac42d41f3d384c",
|
||||
"previewImage": "https://www.robinwieruch.de/static/9b13b3546c675d6f1a1e565f5185cab6/9842e/banner.jpg",
|
||||
"publishedDate": null,
|
||||
"language": "English",
|
||||
"readerable": true
|
||||
}
|
||||
1469
packages/readabilityjs/test/test-pages/robinwieruch.de/expected.html
Normal file
1469
packages/readabilityjs/test/test-pages/robinwieruch.de/expected.html
Normal file
File diff suppressed because it is too large
Load Diff
2504
packages/readabilityjs/test/test-pages/robinwieruch.de/source.html
Normal file
2504
packages/readabilityjs/test/test-pages/robinwieruch.de/source.html
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1 @@
|
||||
https://www.robinwieruch.de/react-hooks-fetch-data/
|
||||
220
packages/readabilityjs/test/test-pages/yuyue.com/distiller.html
Normal file
220
packages/readabilityjs/test/test-pages/yuyue.com/distiller.html
Normal file
@ -0,0 +1,220 @@
|
||||
<div><div>
|
||||
一句话,用整体性学习,即把新旧知识链起来成网,而不是分割成一块一块。<span><br/></span>
|
||||
</div><div>作者用了三个观点和五个步骤来介绍整体性学习,如下:<span><br/></span>
|
||||
</div><div>整体性学习基于三个观点:<span><br/></span>
|
||||
</div><div>1、结构<span><br/></span>相当于一座座城市,语文是一座,数学是一座。发达的城市,学有关的东西就会很快,例如学表达,写作。聪明人就是把新东西和老城市建立交易,联系越多越容易学,条条大路通新知识。完成自觉建立知识间联系的习惯,很容易学好。也就是说,只要新知识能放进城市里,建立起来联系,那就很容易学。<span><br/></span>已经成熟的结构有<span><br/></span><span><span>●</span></span>感知结构:眼、鼻、耳、舌、手。最基本的结构,也发展的最好。<span><br/></span><span><span>●</span></span>关系结构:各种关系,人人、人事等等。<span><br/></span><span><span>●</span></span>基础数学结构:代数、函数等,用来简化其他学科内的关系。<span><br/></span>
|
||||
</div><div>2、模型<span><br/></span>属于简化的结构,是城市的缩略图,是书的目录。模型的形式不限制,主要是为了压缩信息,将核心概念整合在一起,是城市的地基,最核心的部分,在模型的基础上引申出全部的知识。模型可以是一张图,一句话。后续的新知识在模型的基础上进行联系和优化。模型可以改进和优化,比如用视觉化。<span><br/></span>
|
||||
</div><div>3、高速公路<span><br/></span>城市之间的连接,例如正在学习生物,将其与熟悉的商业发展史建立联系。高速公路可以激发创造力,将常人眼里风马牛不相及的专业联系在一起,将知识变得更有弹性。<span><br/></span>
|
||||
</div><div>整体性学习的五个步骤<span><br/></span>
|
||||
</div><div>1、获取<span><br/></span>①获取的信息要准确:信息来源尽可能质量高一点。得到、或者比较好的课程。<span><br/></span>②信息要简化:废话删掉。用笔记流加适当图表。<span><br/></span>(1)不要呆板、僵硬、貌似层次分明的笔记。(2)在写下来的观点之间建立联系。<span><br/></span>
|
||||
</div><div>
|
||||
STHY IN ONE PAGE
|
||||
</div><div>
|
||||
MESIN ISU'L CESIUNT . NORL REART
|
||||
</div><div>
|
||||
DMHRU
|
||||
</div><div>
|
||||
NHER QUARTILE DANGE
|
||||
</div><div>
|
||||
189
|
||||
</div><div>
|
||||
压缩笔记示例
|
||||
</div><div>
|
||||
(第-133
|
||||
</div><div>
|
||||
(一页纸概括了一门课的所有观点)
|
||||
</div><div>
|
||||
VERIANIS
|
||||
</div><div>
|
||||
SHEPIR SUAR SOARY
|
||||
</div><div>
|
||||
之一部
|
||||
</div><div>
|
||||
LBEEEFFJ
|
||||
</div><div>
|
||||
PGOLUC ING
|
||||
</div><div>
|
||||
AWUNTILE QUTY PERCOATAGE
|
||||
</div><div>
|
||||
HORMAT QUARHILE UIAT
|
||||
</div><div>
|
||||
RE NFENFEAY
|
||||
</div><div>
|
||||
MAOICTBINS!
|
||||
</div><div>
|
||||
VALUE& OF OF.
|
||||
</div><div>
|
||||
SARTPLE
|
||||
</div><div>
|
||||
VERS
|
||||
</div><div>
|
||||
YY RESPONSE
|
||||
</div><div>
|
||||
FIEANCNTY.9RAND
|
||||
</div><div>
|
||||
BLANPLANATORY
|
||||
</div><div>
|
||||
中国石化
|
||||
</div><div>
|
||||
CERRELATION A 二
|
||||
</div><div>
|
||||
MVHANASG
|
||||
</div><div>
|
||||
WIGHRION
|
||||
</div><div>
|
||||
EFP AINGT BY
|
||||
</div><div>
|
||||
H-!
|
||||
</div><div>
|
||||
QUNER,ENSS
|
||||
</div><div>
|
||||
THABE VED PONIRE
|
||||
</div><div>
|
||||
王云以
|
||||
</div><div>
|
||||
DESS ANE CENT OFROTPOWE CENE CEN
|
||||
</div><div>
|
||||
LE EST SQVARES GEGSI ON LINE
|
||||
</div><div>
|
||||
5.5
|
||||
</div><div>
|
||||
LBUT
|
||||
</div><div>
|
||||
19
|
||||
</div><div>
|
||||
TRAPOIPLEN
|
||||
</div><img alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671339142303-ce7c7caa-57b6-473b-8fb3-bfaf59a79d3b.png?x-oss-process=image%2Fresize%2Cw_385%2Climit_0" draggable="true"/><div><span><br/></span>③容量尽可能大:一年读2本和一年读100本的差别<span><br/></span>④速度尽可能快:阅读方法要好,同时不能漏掉太多重点。推荐用指读法。<span><br/></span>
|
||||
</div><div>2、理解(停留在这一步就是死记硬背式学习)<span><br/></span>①字面意思是什么,每个字母代表什么。<span><br/></span>②怎么得来的,和上下文有联系吗。<span><br/></span>③如果无法理解,就往更细的点拆分,直至理解。<span><br/></span>
|
||||
</div><div>3、拓展<span><br/></span>①这才是整体性学习的真正开始,用已有的模型来简化新知识的结构。<span><br/></span>②分三种方式<span><br/></span>
|
||||
</div><div>
|
||||
知识的背景探究:从何而来,有什么
|
||||
</div><div>
|
||||
深度拓展(最
|
||||
</div><div>
|
||||
试验,论据是什么
|
||||
</div><div>
|
||||
耗时)
|
||||
</div><div>
|
||||
类似的结论有哪些,异同点是什么,
|
||||
</div><div>
|
||||
横向拓展
|
||||
</div><div>
|
||||
同时期的发现有哪些,同领域的发现
|
||||
</div><div>
|
||||
有哪些
|
||||
</div><div>
|
||||
在结构间建立高速公路
|
||||
</div><div>
|
||||
(1)为你正在学习的东西创造脑海中的图像.
|
||||
</div><div>
|
||||
纵向拓展(最
|
||||
</div><div>
|
||||
难,最具创造
|
||||
</div><div>
|
||||
较好的方法是,比喻法和内在化
|
||||
</div><div>
|
||||
内在化即图像化
|
||||
</div><div>
|
||||
(2)在这幅图像上加入其他感官和情感.
|
||||
</div><div>
|
||||
性)
|
||||
</div><div>
|
||||
(3)寻找图像不适用或不足的地方,防止产生
|
||||
</div><div>
|
||||
错误的联系
|
||||
</div><img alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671338909604-87fea1ef-2468-4b0d-a6f7-c105201ed3e9.png" draggable="true"/><div>4、纠错<span><br/></span>①发现一些特例并指出,删除一些现实中不存在的联系,删除错误结论。<span><br/></span>②不断实践,搞清楚是概念本身的问题还是理解问题;每种类型都实践下;每天都练练,不要临时突击。<span><br/></span>
|
||||
</div><div>5、应用:创造途径,将所学应用到生活中去<span><br/></span>
|
||||
</div><div>0、测试:伴随每一步,主要是改进技术<span><br/></span>
|
||||
</div><div>
|
||||
获取:我以前看过或听过这个吗
|
||||
</div><div>
|
||||
理解:我理解知识的含义吗
|
||||
</div><div>
|
||||
拓展:我知道它从何而来,与哪些知识有联系吗
|
||||
</div><div>
|
||||
-纠错:我删了错误结论以及不恰当的联系吗
|
||||
</div><div>
|
||||
应用:我将知识应用到实际生活中了吗
|
||||
</div><img alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671339064271-45de07d6-b4ca-45f5-8404-3ae3ac40e6f0.png" draggable="true"/><div>另外讲了信息的类型<span><br/></span>1、随意信息:事实、日期、定义或规则,没逻辑和规律。可以用联想来处理(最弱的信息,最难进行整体性学习,尽可能赋予一点逻辑,在无序中找有序)<span><br/></span>2、观点信息:存在争论的信息,用图表法来处理<span><br/></span>3、过程信息:教你怎么行动的信息,如游泳,需要不断练习,可以用内在化、比喻法来改进。(强信息,可以直接唤起新旧知识的联系)<span><br/></span>4、具体信息:信息和感官可以联系在一起(强信息,可以直接唤起新旧知识的联系)<span><br/></span>5、抽象信息:有逻辑,但是没图像,非常抽象(看过《别闹了,费曼先生》,就知道费曼最过人之处就是别人看到的是抽象物理知识,而他看到的是实际生活)<span><br/></span><span><br/></span>信息处理的精髓即,将弱信息结构转为强信息结构。<span><br/></span>
|
||||
</div><div>讲了这样学习的好处<span><br/></span>通过联想,所有的观点、知识都会变得有用,尝试将你的课程与感兴趣的东西联系在一起,任何所学知识都要发掘其实际的用处,特别是对于改进自身有什么实际用处。<span><br/></span>(1)统计学──我利用统计学知识给本书起名字以及定价。利用谷歌搜索引擎,我尝试各种名字和价格,最终利用统计学决定了这个书名和价格最为吸引人。<span><br/></span>(2)计算机──除了编程这种明显的应用之外,我还发现计算机科学是寻找问题的有用途径,纠错、算法都是可以借鉴到其他地方的有用思想。<span><br/></span>(3)会计学──会计学能帮助我理清个人财务以及报税。运用基本的会计学原理整理我的个人财务,使它们看起来一目了然。<span><br/></span>(4)经济学──经济学教会我重新看待金钱在社会中的价值,明白了金钱仅仅是物质交换的载体后,我的个人哲学体系也随之发生了很多变化。<span><br/></span>(5)历史──历史是了解现在的工具,通过学习古代亚洲史能帮助我们看清现代中国、印度和日本的种种问题。历史就是照亮现在的一面镜子。<span><br/></span>
|
||||
</div><div>最后讲了如何提高效率<span><br/></span>1、能量管理:关于能量管理,最好的一本书是《精力管理:管理精力,而非时间,是高效、健康与快乐的基础》(The Powerof Full Engagement)<span><br/></span>2、保持整体性学习的闭环实践,而不是只做其中一部分。<span><br/></span>3、不拖延,用周目标和日目标来分配工作<span><br/></span>
|
||||
</div><div>
|
||||
这是我的周/日(W/D)目标体系.
|
||||
</div><div>
|
||||
MY LISTS THLS LLST:EDIT I REORDER I SHARS
|
||||
</div><div>
|
||||
周目标:2月4~10日
|
||||
</div><div>
|
||||
每周博客更新
|
||||
</div><div>
|
||||
PTB文档
|
||||
</div><div>
|
||||
MY LISTS THIS LIST:EDIT RCORDEE I SHARE
|
||||
</div><div>
|
||||
"FLEX"
|
||||
</div><div>
|
||||
文档
|
||||
</div><div>
|
||||
日目标:2008年2月5日
|
||||
</div><div>
|
||||
网址备份
|
||||
</div><div>
|
||||
课程
|
||||
</div><div>
|
||||
阅读周四ENT案例
|
||||
</div><div>
|
||||
健身
|
||||
</div><div>
|
||||
阅读下一个周四ENT案例
|
||||
</div><div>
|
||||
演讲
|
||||
</div><div>
|
||||
土司马斯
|
||||
</div><div>
|
||||
(TOASTMASTERS)
|
||||
</div><div>
|
||||
我使用TADALIST,这是一个
|
||||
</div><div>
|
||||
阅读会计学第5章
|
||||
</div><div>
|
||||
在线程序.每天晚上我都要检查
|
||||
</div><div>
|
||||
阅读会计学第5章
|
||||
</div><div>
|
||||
自己的每日目标和每周目标完成
|
||||
</div><div>
|
||||
阅读周四ENT案例
|
||||
</div><div>
|
||||
情况,以确保最终实现目标.
|
||||
</div><img alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671336386908-19b26e9c-e92c-4aa6-9e3a-d341297c4d9c.png" draggable="true"/><div><span><br/></span>4、批量处理:《批处理:节省时间、减轻压力的20个小技巧》。<span><br/></span>5、有序:某些物品放在固定位置;有随时记录想法的地方;坚持写清单和日历。<span><br/></span>6、养成习惯并每天都坚持:《如何改变一个习惯》(How to Change a Habit)。<span><br/></span><span><br/></span><span><br/></span>
|
||||
</div><div>
|
||||
从智力挑战开始
|
||||
</div><div>
|
||||
智力挑战的目的是养成新的习惯,许多新方法一开始用起来都很费时间.练
|
||||
</div><div>
|
||||
习2~4周后,速度和效果会大大提高.最后,你需要根据学习的目标对方法进行适当
|
||||
</div><div>
|
||||
的改进.
|
||||
</div><div>
|
||||
以下是一些重要的技巧.
|
||||
</div><div>
|
||||
(1)至少坚持了周.可能你想学会本书介绍的很多技术,但是要记住,如果你不
|
||||
</div><div>
|
||||
坚持3周以上的智力挑战练习,很难将新技术变成一种习惯.
|
||||
</div><div>
|
||||
(2)一次只做一个.不要试图一次完成几个智力挑战,一次只专注一个.
|
||||
</div><div>
|
||||
(3)比喻,内在化和图表法优先.这些是整体性学习中的核心技术,就从它们
|
||||
</div><div>
|
||||
开始吧!
|
||||
</div><div>
|
||||
(4)使用奖励材料.本书附赠有6段专门设计用于练习智力挑战的奖励材料,利
|
||||
</div><div>
|
||||
用它们会让你更轻松些.
|
||||
</div><div>
|
||||
(5)记录下学习的过程.练习智力挑战时,坚持写一句话日记,用一两句话记
|
||||
</div><div>
|
||||
下你的体会和感受,有助于你坚持下来和解决练习中的各种问题.
|
||||
</div><img alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671351449892-3cf066fb-c09b-4cf1-bcda-d03174647d37.png" draggable="true"/><div>
|
||||
|
||||
</div></div>
|
||||
@ -0,0 +1,12 @@
|
||||
{
|
||||
"title": "读《如何高效学习》—Madlife · 语雀",
|
||||
"byline": null,
|
||||
"dir": null,
|
||||
"excerpt": "一句话,用整体性学习,即把新旧知识链起来成网,而不是分...",
|
||||
"siteName": null,
|
||||
"siteIcon": "https://mdn.alipayobjects.com/huamei_0prmtq/afts/img/A*sRUdR543RjcAAAAAAAAAAAAADvuFAQ/original",
|
||||
"previewImage": "https://cdn.nlark.com/yuque/0/2022/png/22724648/1671339142303-ce7c7caa-57b6-473b-8fb3-bfaf59a79d3b.png",
|
||||
"publishedDate": null,
|
||||
"language": "English",
|
||||
"readerable": false
|
||||
}
|
||||
154
packages/readabilityjs/test/test-pages/yuyue.com/expected.html
Normal file
154
packages/readabilityjs/test/test-pages/yuyue.com/expected.html
Normal file
@ -0,0 +1,154 @@
|
||||
<DIV class="page" id="readability-page-1">
|
||||
<div>
|
||||
<div ne-viewer-toc-pin="true" id="u0381" data-viewer-mode="normal">
|
||||
<p> 一句话,用整体性学习,即把新旧知识链起来成网,而不是分割成一块一块。<span ne-filler="block"><br></span></p>
|
||||
<p>作者用了三个观点和五个步骤来介绍整体性学习,如下:<span ne-filler="block"><br></span></p>
|
||||
<p>整体性学习基于三个观点:<span ne-filler="block"><br></span></p>
|
||||
<p>1、结构<span ne-filler="block"><br></span>相当于一座座城市,语文是一座,数学是一座。发达的城市,学有关的东西就会很快,例如学表达,写作。聪明人就是把新东西和老城市建立交易,联系越多越容易学,条条大路通新知识。完成自觉建立知识间联系的习惯,很容易学好。也就是说,只要新知识能放进城市里,建立起来联系,那就很容易学。<span ne-filler="block"><br></span>已经成熟的结构有<span ne-filler="block"><br></span><span ne-fontsize="19"><span>●</span></span>感知结构:眼、鼻、耳、舌、手。最基本的结构,也发展的最好。<span ne-filler="block"><br></span><span ne-fontsize="19"><span>●</span></span>关系结构:各种关系,人人、人事等等。<span ne-filler="block"><br></span><span ne-fontsize="19"><span>●</span></span>基础数学结构:代数、函数等,用来简化其他学科内的关系。<span ne-filler="block"><br></span></p>
|
||||
<p>2、模型<span ne-filler="block"><br></span>属于简化的结构,是城市的缩略图,是书的目录。模型的形式不限制,主要是为了压缩信息,将核心概念整合在一起,是城市的地基,最核心的部分,在模型的基础上引申出全部的知识。模型可以是一张图,一句话。后续的新知识在模型的基础上进行联系和优化。模型可以改进和优化,比如用视觉化。<span ne-filler="block"><br></span></p>
|
||||
<p>3、高速公路<span ne-filler="block"><br></span>城市之间的连接,例如正在学习生物,将其与熟悉的商业发展史建立联系。高速公路可以激发创造力,将常人眼里风马牛不相及的专业联系在一起,将知识变得更有弹性。<span ne-filler="block"><br></span></p>
|
||||
<p>整体性学习的五个步骤<span ne-filler="block"><br></span></p>
|
||||
<p>1、获取<span ne-filler="block"><br></span>①获取的信息要准确:信息来源尽可能质量高一点。得到、或者比较好的课程。<span ne-filler="block"><br></span>②信息要简化:废话删掉。用笔记流加适当图表。<span ne-filler="block"><br></span>(1)不要呆板、僵硬、貌似层次分明的笔记。(2)在写下来的观点之间建立联系。<span ne-filler="block"><br></span></p>
|
||||
<div data-testid="ne-card-image">
|
||||
<div>
|
||||
<p> STHY IN ONE PAGE </p>
|
||||
<p> MESIN ISU'L CESIUNT . NORL REART </p>
|
||||
<p> DMHRU </p>
|
||||
<p> NHER QUARTILE DANGE </p>
|
||||
<p> 189 </p>
|
||||
<p> 压缩笔记示例 </p>
|
||||
<p> (第-133 </p>
|
||||
<p> (一页纸概括了一门课的所有观点) </p>
|
||||
<p> VERIANIS </p>
|
||||
<p> SHEPIR SUAR SOARY </p>
|
||||
<p> 之一部 </p>
|
||||
<p> LBEEEFFJ </p>
|
||||
<p> PGOLUC ING </p>
|
||||
<p> AWUNTILE QUTY PERCOATAGE </p>
|
||||
<p> HORMAT QUARHILE UIAT </p>
|
||||
<p> RE NFENFEAY </p>
|
||||
<p> MAOICTBINS! </p>
|
||||
<p> VALUE& OF OF. </p>
|
||||
<p> SARTPLE </p>
|
||||
<p> VERS </p>
|
||||
<p> YY RESPONSE </p>
|
||||
<p> FIEANCNTY.9RAND </p>
|
||||
<p> BLANPLANATORY </p>
|
||||
<p> 中国石化 </p>
|
||||
<p> CERRELATION A 二 </p>
|
||||
<p> MVHANASG </p>
|
||||
<p> WIGHRION </p>
|
||||
<p> EFP AINGT BY </p>
|
||||
<p> H-! </p>
|
||||
<p> QUNER,ENSS </p>
|
||||
<p> THABE VED PONIRE </p>
|
||||
<p> 王云以 </p>
|
||||
<p> DESS ANE CENT OFROTPOWE CENE CEN </p>
|
||||
<p> LE EST SQVARES GEGSI ON LINE </p>
|
||||
<p> 5.5 </p>
|
||||
<p> LBUT </p>
|
||||
<p> 19 </p>
|
||||
<p> TRAPOIPLEN </p>
|
||||
</div>
|
||||
<p><img width="385" alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671339142303-ce7c7caa-57b6-473b-8fb3-bfaf59a79d3b.png?x-oss-process=image%2Fresize%2Cw_385%2Climit_0" draggable="true">
|
||||
</p>
|
||||
</div>
|
||||
<p><span ne-filler="block"><br></span>③容量尽可能大:一年读2本和一年读100本的差别<span ne-filler="block"><br></span>④速度尽可能快:阅读方法要好,同时不能漏掉太多重点。推荐用指读法。<span ne-filler="block"><br></span></p>
|
||||
<p>2、理解(停留在这一步就是死记硬背式学习)<span ne-filler="block"><br></span>①字面意思是什么,每个字母代表什么。<span ne-filler="block"><br></span>②怎么得来的,和上下文有联系吗。<span ne-filler="block"><br></span>③如果无法理解,就往更细的点拆分,直至理解。<span ne-filler="block"><br></span></p>
|
||||
<p>3、拓展<span ne-filler="block"><br></span>①这才是整体性学习的真正开始,用已有的模型来简化新知识的结构。<span ne-filler="block"><br></span>②分三种方式<span ne-filler="block"><br></span></p>
|
||||
<div data-testid="ne-card-image">
|
||||
<div>
|
||||
<p> 知识的背景探究:从何而来,有什么 </p>
|
||||
<p> 深度拓展(最 </p>
|
||||
<p> 试验,论据是什么 </p>
|
||||
<p> 耗时) </p>
|
||||
<p> 类似的结论有哪些,异同点是什么, </p>
|
||||
<p> 横向拓展 </p>
|
||||
<p> 同时期的发现有哪些,同领域的发现 </p>
|
||||
<p> 有哪些 </p>
|
||||
<p> 在结构间建立高速公路 </p>
|
||||
<p> (1)为你正在学习的东西创造脑海中的图像. </p>
|
||||
<p> 纵向拓展(最 </p>
|
||||
<p> 难,最具创造 </p>
|
||||
<p> 较好的方法是,比喻法和内在化 </p>
|
||||
<p> 内在化即图像化 </p>
|
||||
<p> (2)在这幅图像上加入其他感官和情感. </p>
|
||||
<p> 性) </p>
|
||||
<p> (3)寻找图像不适用或不足的地方,防止产生 </p>
|
||||
<p> 错误的联系 </p>
|
||||
</div>
|
||||
<p><img width="860" alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671338909604-87fea1ef-2468-4b0d-a6f7-c105201ed3e9.png" draggable="true">
|
||||
</p>
|
||||
</div>
|
||||
<p>4、纠错<span ne-filler="block"><br></span>①发现一些特例并指出,删除一些现实中不存在的联系,删除错误结论。<span ne-filler="block"><br></span>②不断实践,搞清楚是概念本身的问题还是理解问题;每种类型都实践下;每天都练练,不要临时突击。<span ne-filler="block"><br></span></p>
|
||||
<p>5、应用:创造途径,将所学应用到生活中去<span ne-filler="block"><br></span></p>
|
||||
<p>0、测试:伴随每一步,主要是改进技术<span ne-filler="block"><br></span></p>
|
||||
<div data-testid="ne-card-image">
|
||||
<div>
|
||||
<p> 获取:我以前看过或听过这个吗 </p>
|
||||
<p> 理解:我理解知识的含义吗 </p>
|
||||
<p> 拓展:我知道它从何而来,与哪些知识有联系吗 </p>
|
||||
<p> -纠错:我删了错误结论以及不恰当的联系吗 </p>
|
||||
<p> 应用:我将知识应用到实际生活中了吗 </p>
|
||||
</div>
|
||||
<p><img width="468" alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671339064271-45de07d6-b4ca-45f5-8404-3ae3ac40e6f0.png" draggable="true">
|
||||
</p>
|
||||
</div>
|
||||
<p>另外讲了信息的类型<span ne-filler="block"><br></span>1、随意信息:事实、日期、定义或规则,没逻辑和规律。可以用联想来处理(最弱的信息,最难进行整体性学习,尽可能赋予一点逻辑,在无序中找有序)<span ne-filler="block"><br></span>2、观点信息:存在争论的信息,用图表法来处理<span ne-filler="block"><br></span>3、过程信息:教你怎么行动的信息,如游泳,需要不断练习,可以用内在化、比喻法来改进。(强信息,可以直接唤起新旧知识的联系)<span ne-filler="block"><br></span>4、具体信息:信息和感官可以联系在一起(强信息,可以直接唤起新旧知识的联系)<span ne-filler="block"><br></span>5、抽象信息:有逻辑,但是没图像,非常抽象(看过《别闹了,费曼先生》,就知道费曼最过人之处就是别人看到的是抽象物理知识,而他看到的是实际生活)<span ne-filler="block"><br></span><span ne-filler="block"><br></span>信息处理的精髓即,将弱信息结构转为强信息结构。<span ne-filler="block"><br></span></p>
|
||||
<p>讲了这样学习的好处<span ne-filler="block"><br></span>通过联想,所有的观点、知识都会变得有用,尝试将你的课程与感兴趣的东西联系在一起,任何所学知识都要发掘其实际的用处,特别是对于改进自身有什么实际用处。<span ne-filler="block"><br></span>(1)统计学──我利用统计学知识给本书起名字以及定价。利用谷歌搜索引擎,我尝试各种名字和价格,最终利用统计学决定了这个书名和价格最为吸引人。<span ne-filler="block"><br></span>(2)计算机──除了编程这种明显的应用之外,我还发现计算机科学是寻找问题的有用途径,纠错、算法都是可以借鉴到其他地方的有用思想。<span ne-filler="block"><br></span>(3)会计学──会计学能帮助我理清个人财务以及报税。运用基本的会计学原理整理我的个人财务,使它们看起来一目了然。<span ne-filler="block"><br></span>(4)经济学──经济学教会我重新看待金钱在社会中的价值,明白了金钱仅仅是物质交换的载体后,我的个人哲学体系也随之发生了很多变化。<span ne-filler="block"><br></span>(5)历史──历史是了解现在的工具,通过学习古代亚洲史能帮助我们看清现代中国、印度和日本的种种问题。历史就是照亮现在的一面镜子。<span ne-filler="block"><br></span></p>
|
||||
<p>最后讲了如何提高效率<span ne-filler="block"><br></span>1、能量管理:关于能量管理,最好的一本书是《精力管理:管理精力,而非时间,是高效、健康与快乐的基础》(The Powerof Full Engagement)<span ne-filler="block"><br></span>2、保持整体性学习的闭环实践,而不是只做其中一部分。<span ne-filler="block"><br></span>3、不拖延,用周目标和日目标来分配工作<span ne-filler="block"><br></span></p>
|
||||
<div data-testid="ne-card-image">
|
||||
<div>
|
||||
<p> 这是我的周/日(W/D)目标体系. </p>
|
||||
<p> MY LISTS THLS LLST:EDIT I REORDER I SHARS </p>
|
||||
<p> 周目标:2月4~10日 </p>
|
||||
<p> 每周博客更新 </p>
|
||||
<p> PTB文档 </p>
|
||||
<p> MY LISTS THIS LIST:EDIT RCORDEE I SHARE </p>
|
||||
<p> "FLEX" </p>
|
||||
<p> 文档 </p>
|
||||
<p> 日目标:2008年2月5日 </p>
|
||||
<p> 网址备份 </p>
|
||||
<p> 课程 </p>
|
||||
<p> 阅读周四ENT案例 </p>
|
||||
<p> 健身 </p>
|
||||
<p> 阅读下一个周四ENT案例 </p>
|
||||
<p> 演讲 </p>
|
||||
<p> 土司马斯 </p>
|
||||
<p> (TOASTMASTERS) </p>
|
||||
<p> 我使用TADALIST,这是一个 </p>
|
||||
<p> 阅读会计学第5章 </p>
|
||||
<p> 在线程序.每天晚上我都要检查 </p>
|
||||
<p> 阅读会计学第5章 </p>
|
||||
<p> 自己的每日目标和每周目标完成 </p>
|
||||
<p> 阅读周四ENT案例 </p>
|
||||
<p> 情况,以确保最终实现目标. </p>
|
||||
</div>
|
||||
<p><img width="520" alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671336386908-19b26e9c-e92c-4aa6-9e3a-d341297c4d9c.png" draggable="true">
|
||||
</p>
|
||||
</div>
|
||||
<p><span ne-filler="block"><br></span>4、批量处理:《批处理:节省时间、减轻压力的20个小技巧》。<span ne-filler="block"><br></span>5、有序:某些物品放在固定位置;有随时记录想法的地方;坚持写清单和日历。<span ne-filler="block"><br></span>6、养成习惯并每天都坚持:《如何改变一个习惯》(How to Change a Habit)。<span ne-filler="block"><br></span><span ne-filler="block"><br></span><span ne-filler="block"><br></span></p>
|
||||
<div data-testid="ne-card-image">
|
||||
<div>
|
||||
<p> 从智力挑战开始 </p>
|
||||
<p> 智力挑战的目的是养成新的习惯,许多新方法一开始用起来都很费时间.练 </p>
|
||||
<p> 习2~4周后,速度和效果会大大提高.最后,你需要根据学习的目标对方法进行适当 </p>
|
||||
<p> 的改进. </p>
|
||||
<p> 以下是一些重要的技巧. </p>
|
||||
<p> (1)至少坚持了周.可能你想学会本书介绍的很多技术,但是要记住,如果你不 </p>
|
||||
<p> 坚持3周以上的智力挑战练习,很难将新技术变成一种习惯. </p>
|
||||
<p> (2)一次只做一个.不要试图一次完成几个智力挑战,一次只专注一个. </p>
|
||||
<p> (3)比喻,内在化和图表法优先.这些是整体性学习中的核心技术,就从它们 </p>
|
||||
<p> 开始吧! </p>
|
||||
<p> (4)使用奖励材料.本书附赠有6段专门设计用于练习智力挑战的奖励材料,利 </p>
|
||||
<p> 用它们会让你更轻松些. </p>
|
||||
<p> (5)记录下学习的过程.练习智力挑战时,坚持写一句话日记,用一两句话记 </p>
|
||||
<p> 下你的体会和感受,有助于你坚持下来和解决练习中的各种问题. </p>
|
||||
</div>
|
||||
<p><img width="773" alt="image.png" src="https://cdn.nlark.com/yuque/0/2022/png/22724648/1671351449892-3cf066fb-c09b-4cf1-bcda-d03174647d37.png" draggable="true">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p> </p>
|
||||
</div>
|
||||
</DIV>
|
||||
34886
packages/readabilityjs/test/test-pages/yuyue.com/source.html
Normal file
34886
packages/readabilityjs/test/test-pages/yuyue.com/source.html
Normal file
File diff suppressed because one or more lines are too long
1
packages/readabilityjs/test/test-pages/yuyue.com/url.txt
Normal file
1
packages/readabilityjs/test/test-pages/yuyue.com/url.txt
Normal file
@ -0,0 +1 @@
|
||||
https://www.yuque.com/u22288095/gf5dgh/yoqgzsrsdltgeel9
|
||||
Reference in New Issue
Block a user